-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Methods for quantile_pred()
change interpretation of missingness, add to errors with missingness
#449
Comments
@dajmcdon Would you be able to assign priority & size estimates here? I'm not sure if you are still trying to do archives of forecasts, and don't know why the |
I'm not entirely sure I see what you would like the behaviour to be: suppressPackageStartupMessages({
library(dplyr)
library(hardhat)
library(vctrs)
})
preds1 <- quantile_pred(matrix(c(1:3, NA, NA, NA), 2, 3, byrow = TRUE), 1:3/4)
preds2 <- vec_c(preds1, NA) This shouldn't work. The vec_detect_missing(preds1)
#> [1] FALSE FALSE
preds1 == preds1
#> [1] TRUE TRUE This is the purpose of the implementation of vec_detect_missing(preds2)
#> [1] FALSE FALSE TRUE
preds2 == preds2
#> [1] TRUE TRUE NA
vec_equal(preds2, preds2, na_equal = TRUE)
#> [1] TRUE TRUE TRUE This object shouldn't exist, so I'm not worried about strange behaviour.
Seems to be the correct behaviour, as
None of this should be possible. Requires the fix above.
Does all of that seem correct to you? In that case, the problem seems to be that |
It's maybe up for debate what
I'm not sure whether a row of all NAs should be treated as "missing"; {distributional} seems not to work that way either; see linked hardhat issue. |
Agreed. Probably requires implementing the epipredict/R/quantile_pred-methods.R Line 75 in 7f08d40
|
Alternatively, and I think this was the original intention (matrix input + "special vector class used to efficiently store predictions from a quantile regression model"), |
Side note: the current vctrs::vec_detect_complete(hardhat::quantile_pred(matrix(c(1,2,3, 1,NA,NA, NA,NA,NA),3,3,byrow = TRUE), 1:3/4))
#> [1] TRUE TRUE TRUE
library(epipredict)
# [...]
vctrs::vec_detect_complete(hardhat::quantile_pred(matrix(c(1,2,3, 1,NA,NA, NA,NA,NA),3,3,byrow = TRUE), 1:3/4))
#> [1] TRUE FALSE FALSE Created on 2025-03-20 with reprex v2.1.1 |
So I think that leaves approaches touching on more central operations such as:
Here's the core of something like D., though I'd imagine A. or B. would be easier/cleaner... notlist <- function(x) {
class(x) <- "notlist"
x
}
new_quantile_pred2 <- function(quantiles, levels) {
# Force everything to numeric or else we need to track elt typeof in an attr
# and invite more ptype2 and vec_cast work, as vctrs ops on proxy objects
# don't like integer() type mixing with others and at some point we have to
# make an object with the appropriate type given an empty list of quantiles:
quantiles <- vec_cast_common(!!!quantiles, .to = double())
quantiles <- notlist(quantiles)
new_vctr(quantiles, quantile_levels = levels, class = "quantile_pred2")
}
#' @importFrom vctrs vec_proxy
#' @export
vec_proxy.quantile_pred2 <- function(x, ...) {
x_unclassed <- unclass(x)
mat <-
if (length(x_unclassed) == 0) {
matrix(numeric(), 0, length(attr(x, "quantile_levels")))
} else {
x_unclassed %>%
{vctrs::vec_interleave(!!!.)} %>%
matrix(length(x_unclassed), length(attr(x, "quantile_levels")))
}
# We need to wrap in a tibble or else vec_init won't respect the matrix
# ncol:
tibble(m = mat)
}
#' @importFrom vctrs vec_restore
#' @export
vec_restore.quantile_pred2 <- function(x, to, ...) {
x %>%
.$m %>%
vec_chop() %>%
lapply(function(x) {dim(x) <- NULL; x}) %>%
new_quantile_pred2(attr(to, "quantile_levels"))
} |
E.g., the
vec_proxy_equal()
implementation seems to be responsible for these changes in behavior demonstrated below. The errors are due to an upstream hardhat bug inas_tibble.quantile_pred()
, but the changes in behavior are from epipredict replacing the defaultvec_proxy_equal()
behavior. This is breaking ability to store forecasts in archives in epiprocess; see cmu-delphi/epiprocess#631.It's rude/frustrating for a package to change existing behavior of a class not introduced by the package itself. We'll probably need to do something like one of the following:
vec_proxy_equal.quantile_pred
vec_proxy_equal.quantile_pred
to [maybe] not change missingness treatment and not raise an error.quantile_pred
behavior.Similarly, for other
quantile_pred
method implementations that we define, we should consider contributing methods upstream if they change existing behavior, or else use a subclass and implement our behavior-change methods there. It might also be good to contribute behavior-adding-but-not-changing methods upstream.Created on 2025-03-19 with reprex v2.1.1
The text was updated successfully, but these errors were encountered: