From 4eecf4e8d36d6b49c73fb1c5bafd0d66ab56866d Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Thu, 4 Jul 2024 16:03:14 -0700 Subject: [PATCH 01/25] fix: layer_add_target/forecast_date * missing rlang prefix * max(NULL, date) produces an integer, tests fail --- R/layer_add_forecast_date.R | 6 +++--- R/layer_add_target_date.R | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/R/layer_add_forecast_date.R b/R/layer_add_forecast_date.R index 5bd6b6918..2174b7330 100644 --- a/R/layer_add_forecast_date.R +++ b/R/layer_add_forecast_date.R @@ -87,11 +87,11 @@ layer_add_forecast_date_new <- function(forecast_date, id) { #' @export slather.layer_add_forecast_date <- function(object, components, workflow, new_data, ...) { if (is.null(object$forecast_date)) { - max_time_value <- max( + max_time_value <- as.Date(max( workflows::extract_preprocessor(workflow)$max_time_value, workflow$fit$meta$max_time_value, max(new_data$time_value) - ) + )) forecast_date <- max_time_value } else { forecast_date <- object$forecast_date @@ -102,7 +102,7 @@ slather.layer_add_forecast_date <- function(object, components, workflow, new_da )$time_type if (expected_time_type == "week") expected_time_type <- "day" validate_date(forecast_date, expected_time_type, - call = expr(layer_add_forecast_date()) + call = rlang::expr(layer_add_forecast_date()) ) forecast_date <- coerce_time_type(forecast_date, expected_time_type) object$forecast_date <- forecast_date diff --git a/R/layer_add_target_date.R b/R/layer_add_target_date.R index f03bd6154..23aeb4091 100644 --- a/R/layer_add_target_date.R +++ b/R/layer_add_target_date.R @@ -101,17 +101,17 @@ slather.layer_add_target_date <- function(object, components, workflow, new_data the_frosting, "layer_add_forecast_date", "forecast_date" ))) { validate_date(forecast_date, expected_time_type, - call = expr(layer_add_forecast_date()) + call = rlang::expr(layer_add_forecast_date()) ) forecast_date <- coerce_time_type(forecast_date, expected_time_type) ahead <- extract_argument(the_recipe, "step_epi_ahead", "ahead") target_date <- forecast_date + ahead } else { - max_time_value <- max( + max_time_value <- as.Date(max( workflows::extract_preprocessor(workflow)$max_time_value, workflow$fit$meta$max_time_value, max(new_data$time_value) - ) + )) ahead <- extract_argument(the_recipe, "step_epi_ahead", "ahead") target_date <- max_time_value + ahead } From 519bed3ee50ccdf0d25bccf1ee172df4810c7c55 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Thu, 4 Jul 2024 16:07:42 -0700 Subject: [PATCH 02/25] tests all pass --- DESCRIPTION | 2 +- NAMESPACE | 13 +-- R/blueprint-epi_recipe-default.R | 142 ++++++++++------------------ R/epi_keys.R | 24 +---- R/epi_recipe.R | 15 +-- R/recipe.epi_df.R | 49 ++++++++++ man/default_epi_recipe_blueprint.Rd | 44 +++++++++ man/new_epi_recipe_blueprint.Rd | 92 ------------------ tests/testthat/test-blueprint.R | 12 +-- tests/testthat/test-epi_keys.R | 5 +- tests/testthat/test-epi_recipe.R | 43 ++++----- 11 files changed, 189 insertions(+), 252 deletions(-) create mode 100644 R/recipe.epi_df.R create mode 100644 man/default_epi_recipe_blueprint.Rd delete mode 100644 man/new_epi_recipe_blueprint.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 12d86602b..a17f5580b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -23,7 +23,7 @@ URL: https://github.com/cmu-delphi/epipredict/, https://cmu-delphi.github.io/epipredict BugReports: https://github.com/cmu-delphi/epipredict/issues/ Depends: - epiprocess (>= 0.7.5), + epiprocess (>= 0.7.12), parsnip (>= 1.0.0), R (>= 3.5.0) Imports: diff --git a/NAMESPACE b/NAMESPACE index 708c91e06..9180fcbca 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -27,11 +27,6 @@ S3method(bake,step_population_scaling) S3method(bake,step_training_window) S3method(detect_layer,frosting) S3method(detect_layer,workflow) -S3method(epi_keys,data.frame) -S3method(epi_keys,default) -S3method(epi_keys,epi_df) -S3method(epi_keys,epi_workflow) -S3method(epi_keys,recipe) S3method(epi_recipe,default) S3method(epi_recipe,epi_df) S3method(epi_recipe,formula) @@ -54,6 +49,8 @@ S3method(forecast,epi_workflow) S3method(format,dist_quantiles) S3method(is.na,dist_quantiles) S3method(is.na,distribution) +S3method(key_colnames,epi_workflow) +S3method(key_colnames,recipe) S3method(mean,dist_quantiles) S3method(median,dist_quantiles) S3method(predict,epi_workflow) @@ -96,6 +93,8 @@ S3method(print,step_naomit) S3method(print,step_population_scaling) S3method(print,step_training_window) S3method(quantile,dist_quantiles) +S3method(recipe,epi_df) +S3method(recipes::recipe,formula) S3method(refresh_blueprint,default_epi_recipe_blueprint) S3method(residuals,flatline) S3method(run_mold,default_epi_recipe_blueprint) @@ -148,7 +147,6 @@ export(detect_layer) export(dist_quantiles) export(epi_keys) export(epi_recipe) -export(epi_recipe_blueprint) export(epi_workflow) export(extract_argument) export(extract_frosting) @@ -180,8 +178,6 @@ export(layer_residual_quantiles) export(layer_threshold) export(layer_unnest) export(nested_quantiles) -export(new_default_epi_recipe_blueprint) -export(new_epi_recipe_blueprint) export(pivot_quantiles_longer) export(pivot_quantiles_wider) export(prep) @@ -235,6 +231,7 @@ importFrom(magrittr,"%>%") importFrom(quantreg,rq) importFrom(recipes,bake) importFrom(recipes,prep) +importFrom(recipes,recipe) importFrom(rlang,"!!!") importFrom(rlang,"!!") importFrom(rlang,"%@%") diff --git a/R/blueprint-epi_recipe-default.R b/R/blueprint-epi_recipe-default.R index 886cd5512..69a4dc1d1 100644 --- a/R/blueprint-epi_recipe-default.R +++ b/R/blueprint-epi_recipe-default.R @@ -1,111 +1,69 @@ -#' Recipe blueprint that accounts for `epi_df` panel data -#' -#' Used for simplicity. See [hardhat::new_recipe_blueprint()] or -#' [hardhat::default_recipe_blueprint()] for more details. -#' -#' @inheritParams hardhat::new_recipe_blueprint +#' Default epi_recipe blueprint #' -#' @details The `bake_dependent_roles` are automatically set to `epi_df` defaults. -#' @return A recipe blueprint. +#' Recipe blueprint that accounts for `epi_df` panel data +#' Used for simplicity. See [hardhat::default_recipe_blueprint()] for more +#' details. This subclass is nearly the same, except it ensures that +#' downstream processing doesn't drop the epi_df class from the data. #' -#' @keywords internal +#' @inheritParams hardhat::default_recipe_blueprint +#' @return A `epi_recipe` blueprint. #' @export -new_epi_recipe_blueprint <- - function(intercept = FALSE, allow_novel_levels = FALSE, fresh = TRUE, - composition = "tibble", - ptypes = NULL, recipe = NULL, ..., subclass = character()) { - hardhat::new_recipe_blueprint( - intercept = intercept, - allow_novel_levels = allow_novel_levels, - fresh = fresh, - composition = composition, - ptypes = ptypes, - recipe = recipe, - ..., - subclass = c(subclass, "epi_recipe_blueprint") - ) - } - - -#' @rdname new_epi_recipe_blueprint -#' @export -epi_recipe_blueprint <- - function(intercept = FALSE, allow_novel_levels = FALSE, - fresh = TRUE, - composition = "tibble") { - new_epi_recipe_blueprint( - intercept = intercept, - allow_novel_levels = allow_novel_levels, - fresh = fresh, - composition = composition - ) - } +#' @keywords internal +default_epi_recipe_blueprint <- function(intercept = FALSE, + allow_novel_levels = FALSE, + fresh = TRUE, + strings_as_factors = FALSE, + composition = "tibble") { + new_default_epi_recipe_blueprint( + intercept = intercept, + allow_novel_levels = allow_novel_levels, + fresh = fresh, + strings_as_factors = strings_as_factors, + composition = composition + ) +} -#' @rdname new_epi_recipe_blueprint -#' @export -default_epi_recipe_blueprint <- - function(intercept = FALSE, allow_novel_levels = FALSE, fresh = TRUE, - composition = "tibble") { - new_default_epi_recipe_blueprint( - intercept = intercept, - allow_novel_levels = allow_novel_levels, - fresh = fresh, - composition = composition - ) - } +new_default_epi_recipe_blueprint <- function(intercept = FALSE, + allow_novel_levels = TRUE, + fresh = TRUE, + strings_as_factors = FALSE, + composition = "tibble", + ptypes = NULL, + recipe = NULL, + extra_role_ptypes = NULL, + ..., + subclass = character()) { + hardhat::new_recipe_blueprint( + intercept = intercept, + allow_novel_levels = allow_novel_levels, + fresh = fresh, + strings_as_factors = strings_as_factors, + composition = composition, + ptypes = ptypes, + recipe = recipe, + extra_role_ptypes = extra_role_ptypes, + ..., + subclass = c(subclass, "default_epi_recipe_blueprint", "default_recipe_blueprint")) +} -#' @rdname new_epi_recipe_blueprint -#' @inheritParams hardhat::new_default_recipe_blueprint -#' @export -new_default_epi_recipe_blueprint <- - function(intercept = FALSE, allow_novel_levels = FALSE, - fresh = TRUE, - composition = "tibble", ptypes = NULL, recipe = NULL, - extra_role_ptypes = NULL, ..., subclass = character()) { - new_epi_recipe_blueprint( - intercept = intercept, - allow_novel_levels = allow_novel_levels, - fresh = fresh, - composition = composition, - ptypes = ptypes, - recipe = recipe, - extra_role_ptypes = extra_role_ptypes, - ..., - subclass = c(subclass, "default_epi_recipe_blueprint", "default_recipe_blueprint") - ) - } #' @importFrom hardhat run_mold #' @export run_mold.default_epi_recipe_blueprint <- function(blueprint, ..., data) { rlang::check_dots_empty0(...) - # blueprint <- hardhat:::patch_recipe_default_blueprint(blueprint) - cleaned <- mold_epi_recipe_default_clean(blueprint = blueprint, data = data) - blueprint <- cleaned$blueprint - data <- cleaned$data + # we don't do the "cleaning" in `hardhat:::run_mold.default_recipe_blueprint` + # That function drops the epi_df class without any recourse. + # The only way we should be here at all is if `data` is an epi_df, but just + # in case... + if (!is_epi_df(data)) { + cli_warn("`data` is not an {.cls epi_df}. It has class {.cls {class(data)}}.") + } hardhat:::mold_recipe_default_process(blueprint = blueprint, data = data) } -mold_epi_recipe_default_clean <- function(blueprint, data) { - hardhat:::check_data_frame_or_matrix(data) - if (!is_epi_df(data)) data <- hardhat:::coerce_to_tibble(data) - hardhat:::new_mold_clean(blueprint, data) -} - #' @importFrom hardhat refresh_blueprint #' @export refresh_blueprint.default_epi_recipe_blueprint <- function(blueprint) { do.call(new_default_epi_recipe_blueprint, as.list(blueprint)) } - -## removing this function? -# er_check_is_data_like <- function(.x, .x_nm) { -# if (rlang::is_missing(.x_nm)) { -# .x_nm <- rlang::as_label(rlang::enexpr(.x)) -# } -# if (!hardhat:::is_new_data_like(.x)) { -# hardhat:::glubort("`{.x_nm}` must be a data.frame or a matrix, not a {class1(.x)}.") -# } -# .x -# } diff --git a/R/epi_keys.R b/R/epi_keys.R index 08e4595c3..34d141cd6 100644 --- a/R/epi_keys.R +++ b/R/epi_keys.R @@ -6,34 +6,16 @@ #' @return If an `epi_df`, this returns all "keys". Otherwise `NULL` #' @keywords internal #' @export -epi_keys <- function(x, ...) { - UseMethod("epi_keys") -} +epi_keys <- key_colnames -#' @export -epi_keys.default <- function(x, ...) { - character(0L) -} - -#' @export -epi_keys.data.frame <- function(x, other_keys = character(0L), ...) { - arg_is_chr(other_keys, allow_empty = TRUE) - nm <- c("time_value", "geo_value", other_keys) - intersect(nm, names(x)) -} - -#' @export -epi_keys.epi_df <- function(x, ...) { - c("time_value", "geo_value", attr(x, "metadata")$other_keys) -} #' @export -epi_keys.recipe <- function(x, ...) { +key_colnames.recipe <- function(x, ...) { x$var_info$variable[x$var_info$role %in% c("time_value", "geo_value", "key")] } #' @export -epi_keys.epi_workflow <- function(x, ...) { +key_colnames.epi_workflow <- function(x, ...) { epi_keys_mold(hardhat::extract_mold(x)) } diff --git a/R/epi_recipe.R b/R/epi_recipe.R index e5182b99b..4afe1d6fb 100644 --- a/R/epi_recipe.R +++ b/R/epi_recipe.R @@ -9,6 +9,7 @@ #' @import recipes #' @export epi_recipe <- function(x, ...) { + # deprecate_soft("This function is being deprecated. Use `recipe()` instead.") UseMethod("epi_recipe") } @@ -16,10 +17,10 @@ epi_recipe <- function(x, ...) { #' @rdname epi_recipe #' @export epi_recipe.default <- function(x, ...) { - ## if not a formula or an epi_df, we just pass to recipes::recipe - if (is.matrix(x) || is.data.frame(x) || tibble::is_tibble(x)) { - x <- x[1, , drop = FALSE] - } + # if not a formula or an epi_df, we just pass to recipes::recipe + # if (is.matrix(x) || is.data.frame(x) || tibble::is_tibble(x)) { + # x <- x[1, , drop = FALSE] + # } recipes::recipe(x, ...) } @@ -57,6 +58,7 @@ epi_recipe.default <- function(x, ...) { #' r epi_recipe.epi_df <- function(x, formula = NULL, ..., vars = NULL, roles = NULL) { + return(recipe(x, formula = formula, ..., vars = vars, roles = roles)) if (!is.null(formula)) { if (!is.null(vars)) { rlang::abort( @@ -144,7 +146,7 @@ epi_recipe.epi_df <- #' @export epi_recipe.formula <- function(formula, data, ...) { # we ensure that there's only 1 row in the template - data <- data[1, ] + return(recipe(data, formula, ...)) # check for minus: if (!epiprocess::is_epi_df(data)) { return(recipes::recipe(formula, data, ...)) @@ -157,7 +159,8 @@ epi_recipe.formula <- function(formula, data, ...) { # Check for other in-line functions args <- epi_form2args(formula, data, ...) - obj <- epi_recipe.epi_df( + # browser() + obj <- recipe.epi_df( x = args$x, formula = NULL, ..., diff --git a/R/recipe.epi_df.R b/R/recipe.epi_df.R new file mode 100644 index 000000000..eae58d256 --- /dev/null +++ b/R/recipe.epi_df.R @@ -0,0 +1,49 @@ +#' @importFrom recipes recipe +#' @export +recipe.epi_df <- function(x, formula = NULL, ..., vars = NULL, roles = NULL) { + # vars + roles must be same-length character vectors + # formula is mutually exclusive with vars + roles + # either determines the variables needed for modelling + attr(x, "decay_to_tibble") <- FALSE # avoid as_tibble stripping the class + r <- NextMethod("recipe") + r <- add_epi_df_roles_to_recipe(r, x) + + # arrange to easy order + r$var_info <- r$var_info %>% + dplyr::arrange(factor( + role, + levels = union( + c("predictor", "outcome", "time_value", "geo_value", "key"), + unique(role) + ) # anything else + )) + r$term_info <- r$var_info + class(r) <- c("epi_recipe", class(r)) + r +} + +#' @exportS3Method recipes::recipe +recipe.formula <- function(formula, data, ...) { + # This method clobbers `recipes::recipe.formula`, but should have no noticible + # effect. + recipe(x = data, formula = formula, ...) +} + +add_epi_df_roles_to_recipe <- function(r, epi_df) { + edf_keys <- epiprocess::key_colnames(epi_df) + edf_roles <- c("time_value", "geo_value", rep("key", length(edf_keys) - 2)) + types <- recipes:::get_types(epi_df[, edf_keys])$type + info <- tibble( + variable = edf_keys, + type = types, + role = edf_roles, + source = "original" + ) + # reconstruct the constituents + r$template <- epi_df[ ,unique(c(edf_keys, r$var_info$variable))] + r$var_info <- r$var_info %>% + dplyr::filter(!((variable %in% edf_keys) & is.na(role))) %>% + dplyr::bind_rows(info) %>% + dplyr::distinct() + r +} diff --git a/man/default_epi_recipe_blueprint.Rd b/man/default_epi_recipe_blueprint.Rd new file mode 100644 index 000000000..465a8abef --- /dev/null +++ b/man/default_epi_recipe_blueprint.Rd @@ -0,0 +1,44 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/blueprint-epi_recipe-default.R +\name{default_epi_recipe_blueprint} +\alias{default_epi_recipe_blueprint} +\title{Default epi_recipe blueprint} +\usage{ +default_epi_recipe_blueprint( + intercept = FALSE, + allow_novel_levels = FALSE, + fresh = TRUE, + strings_as_factors = FALSE, + composition = "tibble" +) +} +\arguments{ +\item{intercept}{A logical. Should an intercept be included in the +processed data? This information is used by the \code{process} function +in the \code{mold} and \code{forge} function list.} + +\item{allow_novel_levels}{A logical. Should novel factor levels be allowed at +prediction time? This information is used by the \code{clean} function in the +\code{forge} function list, and is passed on to \code{\link[hardhat:scream]{scream()}}.} + +\item{fresh}{Should already trained operations be re-trained when \code{prep()} is +called?} + +\item{strings_as_factors}{Should character columns be converted to factors +when \code{prep()} is called?} + +\item{composition}{Either "tibble", "matrix", or "dgCMatrix" for the format +of the processed predictors. If "matrix" or "dgCMatrix" are chosen, all of +the predictors must be numeric after the preprocessing method has been +applied; otherwise an error is thrown.} +} +\value{ +A \code{epi_recipe} blueprint. +} +\description{ +Recipe blueprint that accounts for \code{epi_df} panel data +Used for simplicity. See \code{\link[hardhat:default_recipe_blueprint]{hardhat::default_recipe_blueprint()}} for more +details. This subclass is nearly the same, except it ensures that +downstream processing doesn't drop the epi_df class from the data. +} +\keyword{internal} diff --git a/man/new_epi_recipe_blueprint.Rd b/man/new_epi_recipe_blueprint.Rd deleted file mode 100644 index db22b5675..000000000 --- a/man/new_epi_recipe_blueprint.Rd +++ /dev/null @@ -1,92 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/blueprint-epi_recipe-default.R -\name{new_epi_recipe_blueprint} -\alias{new_epi_recipe_blueprint} -\alias{epi_recipe_blueprint} -\alias{default_epi_recipe_blueprint} -\alias{new_default_epi_recipe_blueprint} -\title{Recipe blueprint that accounts for \code{epi_df} panel data} -\usage{ -new_epi_recipe_blueprint( - intercept = FALSE, - allow_novel_levels = FALSE, - fresh = TRUE, - composition = "tibble", - ptypes = NULL, - recipe = NULL, - ..., - subclass = character() -) - -epi_recipe_blueprint( - intercept = FALSE, - allow_novel_levels = FALSE, - fresh = TRUE, - composition = "tibble" -) - -default_epi_recipe_blueprint( - intercept = FALSE, - allow_novel_levels = FALSE, - fresh = TRUE, - composition = "tibble" -) - -new_default_epi_recipe_blueprint( - intercept = FALSE, - allow_novel_levels = FALSE, - fresh = TRUE, - composition = "tibble", - ptypes = NULL, - recipe = NULL, - extra_role_ptypes = NULL, - ..., - subclass = character() -) -} -\arguments{ -\item{intercept}{A logical. Should an intercept be included in the -processed data? This information is used by the \code{process} function -in the \code{mold} and \code{forge} function list.} - -\item{allow_novel_levels}{A logical. Should novel factor levels be allowed at -prediction time? This information is used by the \code{clean} function in the -\code{forge} function list, and is passed on to \code{\link[hardhat:scream]{scream()}}.} - -\item{fresh}{Should already trained operations be re-trained when \code{prep()} is -called?} - -\item{composition}{Either "tibble", "matrix", or "dgCMatrix" for the format -of the processed predictors. If "matrix" or "dgCMatrix" are chosen, all of -the predictors must be numeric after the preprocessing method has been -applied; otherwise an error is thrown.} - -\item{ptypes}{Either \code{NULL}, or a named list with 2 elements, \code{predictors} -and \code{outcomes}, both of which are 0-row tibbles. \code{ptypes} is generated -automatically at \code{\link[hardhat:mold]{mold()}} time and is used to validate \code{new_data} at -prediction time.} - -\item{recipe}{Either \code{NULL}, or an unprepped recipe. This argument is set -automatically at \code{\link[hardhat:mold]{mold()}} time.} - -\item{...}{Name-value pairs for additional elements of blueprints that -subclass this blueprint.} - -\item{subclass}{A character vector. The subclasses of this blueprint.} - -\item{extra_role_ptypes}{A named list. The names are the unique non-standard -recipe roles (i.e. everything except \code{"predictors"} and \code{"outcomes"}). The -values are prototypes of the original columns with that role. These are -used for validation in \code{forge()}.} -} -\value{ -A recipe blueprint. -} -\description{ -Used for simplicity. See \code{\link[hardhat:new-blueprint]{hardhat::new_recipe_blueprint()}} or -\code{\link[hardhat:default_recipe_blueprint]{hardhat::default_recipe_blueprint()}} for more details. -} -\details{ -The \code{bake_dependent_roles} are automatically set to \code{epi_df} defaults. -} -\keyword{internal} diff --git a/tests/testthat/test-blueprint.R b/tests/testthat/test-blueprint.R index 2d22aff6e..c069c8bcb 100644 --- a/tests/testthat/test-blueprint.R +++ b/tests/testthat/test-blueprint.R @@ -1,22 +1,18 @@ test_that("epi_recipe blueprint keeps the class, mold works", { - bp <- new_default_epi_recipe_blueprint() - expect_length(class(bp), 5L) + bp <- default_epi_recipe_blueprint() + expect_length(class(bp), 4L) expect_s3_class(bp, "default_epi_recipe_blueprint") - expect_s3_class(refresh_blueprint(bp), "default_epi_recipe_blueprint") + expect_s3_class(hardhat::refresh_blueprint(bp), "default_epi_recipe_blueprint") jhu <- case_death_rate_subset # expect_s3_class(er_check_is_data_like(jhu), "epi_df") - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_naomit(all_predictors()) %>% step_naomit(all_outcomes(), skip = TRUE) - mm <- mold_epi_recipe_default_clean(bp, jhu) - expect_s3_class(mm$blueprint, "default_epi_recipe_blueprint") - expect_s3_class(mm$data, "epi_df") - bp <- hardhat:::update_blueprint(bp, recipe = r) run_mm <- run_mold(bp, data = jhu) expect_false(is.factor(run_mm$extras$roles$geo_value$geo_value)) diff --git a/tests/testthat/test-epi_keys.R b/tests/testthat/test-epi_keys.R index 3e794542e..a3c2fddc1 100644 --- a/tests/testthat/test-epi_keys.R +++ b/tests/testthat/test-epi_keys.R @@ -18,8 +18,9 @@ test_that("Extracts keys from an epi_df", { expect_equal(epi_keys(case_death_rate_subset), c("time_value", "geo_value")) }) -test_that("Extracts keys from a recipe; roles are NA, giving an empty vector", { - expect_equal(epi_keys(recipe(case_death_rate_subset)), character(0L)) +test_that("Extracts keys from a recipe", { + expect_equal(epi_keys(recipe(case_death_rate_subset)), c("time_value", "geo_value")) + expect_equal(epi_keys(recipe(cars)), character(0L)) }) test_that("epi_keys_mold extracts time_value and geo_value, but not raw", { diff --git a/tests/testthat/test-epi_recipe.R b/tests/testthat/test-epi_recipe.R index d288ec058..a4b05afac 100644 --- a/tests/testthat/test-epi_recipe.R +++ b/tests/testthat/test-epi_recipe.R @@ -1,27 +1,25 @@ -test_that("epi_recipe produces default recipe", { - # these all call recipes::recipe(), but the template will always have 1 row +test_that("recipe produces default recipe", { + # these all call recipes::recipe() tib <- tibble( x = 1:5, y = 1:5, time_value = seq(as.Date("2020-01-01"), by = 1, length.out = 5) ) - rec <- recipes::recipe(tib) - rec$template <- rec$template[1, ] + rec <- recipe(tib) expect_identical(rec, epi_recipe(tib)) - expect_equal(nrow(rec$template), 1L) + expect_equal(nrow(rec$template), 5L) - rec <- recipes::recipe(y ~ x, tib) - rec$template <- rec$template[1, ] + + rec <- recipe(y ~ x, tib) expect_identical(rec, epi_recipe(y ~ x, tib)) - expect_equal(nrow(rec$template), 1L) + expect_equal(nrow(rec$template), 5L) m <- as.matrix(tib) - rec <- recipes::recipe(m) - rec$template <- rec$template[1, ] + rec <- recipe(m) expect_identical(rec, epi_recipe(m)) - expect_equal(nrow(rec$template), 1L) + expect_equal(nrow(rec$template), 5L) }) -test_that("epi_recipe formula works", { +test_that("recipe formula works", { tib <- tibble( x = 1:5, y = 1:5, time_value = seq(as.Date("2020-01-01"), by = 1, length.out = 5), @@ -29,7 +27,7 @@ test_that("epi_recipe formula works", { ) %>% epiprocess::as_epi_df() # simple case - r <- epi_recipe(y ~ x, tib) + r <- recipe(y ~ x, tib) ref_var_info <- tibble::tribble( ~variable, ~type, ~role, ~source, "x", c("integer", "numeric"), "predictor", "original", @@ -38,10 +36,10 @@ test_that("epi_recipe formula works", { "geo_value", c("string", "unordered", "nominal"), "geo_value", "original" ) expect_identical(r$var_info, ref_var_info) - expect_equal(nrow(r$template), 1L) + expect_equal(nrow(r$template), 5L) # with an epi_key as a predictor - r <- epi_recipe(y ~ x + geo_value, tib) + r <- recipe(y ~ x + geo_value, tib) ref_var_info <- ref_var_info %>% tibble::add_row( variable = "geo_value", type = list(c("string", "unordered", "nominal")), @@ -49,7 +47,7 @@ test_that("epi_recipe formula works", { source = "original", .after = 1 ) expect_identical(r$var_info, ref_var_info) - expect_equal(nrow(r$template), 1L) + expect_equal(nrow(r$template), 5L) tib <- tibble( x = 1:5, y = 1:5, @@ -70,7 +68,7 @@ test_that("epi_recipe formula works", { expect_identical(r$var_info, ref_var_info) }) -test_that("epi_recipe epi_df works", { +test_that("recipe epi_df works", { tib <- tibble( x = 1:5, y = 1:5, time_value = seq(as.Date("2020-01-01"), by = 1, length.out = 5), @@ -82,11 +80,11 @@ test_that("epi_recipe epi_df works", { ~variable, ~type, ~role, ~source, "time_value", "date", "time_value", "original", "geo_value", c("string", "unordered", "nominal"), "geo_value", "original", - "x", c("integer", "numeric"), "raw", "original", - "y", c("integer", "numeric"), "raw", "original" + "x", c("integer", "numeric"), NA, "original", + "y", c("integer", "numeric"), NA, "original" ) expect_identical(r$var_info, ref_var_info) - expect_equal(nrow(r$template), 1L) + expect_equal(nrow(r$template), 5L) r <- epi_recipe(tib, formula = y ~ x) ref_var_info <- tibble::tribble( @@ -97,7 +95,7 @@ test_that("epi_recipe epi_df works", { "geo_value", c("string", "unordered", "nominal"), "geo_value", "original" ) expect_identical(r$var_info, ref_var_info) - expect_equal(nrow(r$template), 1L) + expect_equal(nrow(r$template), 5L) r <- epi_recipe( @@ -110,11 +108,12 @@ test_that("epi_recipe epi_df works", { source = "original" ) expect_identical(r$var_info, ref_var_info) - expect_equal(nrow(r$template), 1L) + expect_equal(nrow(r$template), 5L) }) test_that("add/update/adjust/remove epi_recipe works as intended", { + library(workflows) jhu <- case_death_rate_subset r <- epi_recipe(jhu) %>% From 30db68fac7a5885eb7e46ea0eb24f8e1d56d44ea Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Thu, 4 Jul 2024 19:16:34 -0700 Subject: [PATCH 03/25] fix: .pred is a distribution --- R/autoplot.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/R/autoplot.R b/R/autoplot.R index 77f04dde7..143ab35d5 100644 --- a/R/autoplot.R +++ b/R/autoplot.R @@ -183,6 +183,9 @@ autoplot.epi_workflow <- function( if (".pred" %in% names(predictions)) { ntarget_dates <- dplyr::n_distinct(predictions$time_value) + if (distributional::is_distribution(predictions$.pred)) { + predictions <- dplyr::mutate(predictions, .pred = median(.pred)) + } if (ntarget_dates > 1L) { bp <- bp + ggplot2::geom_line( From feb81a040bb009277f239426bbc530c33b24a642 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Thu, 4 Jul 2024 19:17:15 -0700 Subject: [PATCH 04/25] minor fixes in vignettes --- vignettes/preprocessing-and-models.Rmd | 32 +++++++++++++------------- vignettes/update.Rmd | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/vignettes/preprocessing-and-models.Rmd b/vignettes/preprocessing-and-models.Rmd index d557ed1f7..f946d0657 100644 --- a/vignettes/preprocessing-and-models.Rmd +++ b/vignettes/preprocessing-and-models.Rmd @@ -44,9 +44,9 @@ will create a classification model for hotspot predictions. library(tidyr) library(dplyr) library(epidatr) -library(epipredict) library(recipes) library(workflows) +library(epipredict) library(poissonreg) ``` @@ -147,9 +147,10 @@ manipulate variable roles easily. --- -Notice in the following preprocessing steps, we used `add_role()` on -`geo_value_factor` since, currently, the default role for it is `raw`, but -we would like to reuse this variable as `predictor`s. +Notice in the following preprocessing steps, we used `update_role()` on +`geo_value_factor` since, currently, the default role for it is `NA`, but +we would like to reuse this variable as `predictor`s. (If is had a non-`NA` +role, then we would use `add_role()` instead.) ```{r} counts_subset <- counts_subset %>% @@ -159,7 +160,7 @@ counts_subset <- counts_subset %>% epi_recipe(counts_subset) r <- epi_recipe(counts_subset) %>% - add_role(geo_value_factor, new_role = "predictor") %>% + update_role(geo_value_factor, new_role = "predictor") %>% step_dummy(geo_value_factor) %>% ## Occasionally, data reporting errors / corrections result in negative ## cases / deaths @@ -174,17 +175,15 @@ modeling and producing the prediction for death count, 7 days after the latest available date in the dataset. ```{r} -latest <- get_test_data(r, counts_subset) - wf <- epi_workflow(r, parsnip::poisson_reg()) %>% fit(counts_subset) -predict(wf, latest) %>% filter(!is.na(.pred)) +forecast(wf) %>% filter(!is.na(.pred)) ``` Note that the `time_value` corresponds to the last available date in the training set, **NOT** to the target date of the forecast -(`r max(latest$time_value) + 7`). +(`r max(counts_subset$time_value) + 7`). Let's take a look at the fit: @@ -320,8 +319,8 @@ jhu <- jhu %>% left_join(behav_ind, by = c("geo_value", "time_value")) %>% as_epi_df() -r <- epi_recipe(jhu) %>% - add_role(geo_value_factor, new_role = "predictor") %>% +r <- recipe(jhu) %>% + update_role(geo_value_factor, new_role = "predictor") %>% step_dummy(geo_value_factor) %>% step_epi_lag(case_rate, death_rate, lag = c(0, 7, 14)) %>% step_mutate( @@ -351,6 +350,7 @@ f <- frosting() %>% layer_add_target_date("2022-01-07") %>% layer_threshold(.pred, lower = 0) %>% layer_quantile_distn() %>% + layer_point_from_distn() %>% layer_naomit(.pred) %>% layer_population_scaling( .pred, .pred_distn, @@ -361,8 +361,8 @@ f <- frosting() %>% ) wf <- epi_workflow(r, quantile_reg(quantile_levels = c(.05, .5, .95))) %>% - fit(jhu) %>% - add_frosting(f) + add_frosting(f) %>% + fit(jhu) p <- forecast(wf) p @@ -456,9 +456,9 @@ jhu <- case_death_rate_subset %>% ) %>% mutate(geo_value_factor = as.factor(geo_value)) -r <- epi_recipe(jhu) %>% +r <- recipe(jhu) %>% add_role(time_value, new_role = "predictor") %>% - step_dummy(geo_value_factor) %>% + step_dummy(geo_value_factor, role = "predictor") %>% step_growth_rate(case_rate, role = "none", prefix = "gr_") %>% step_epi_lag(starts_with("gr_"), lag = c(0, 7, 14)) %>% step_epi_ahead(starts_with("gr_"), ahead = 7, role = "none") %>% @@ -471,7 +471,7 @@ r <- epi_recipe(jhu) %>% ), role = "outcome" ) %>% - step_rm(has_role("none"), has_role("raw")) %>% + step_rm(has_role("none"), has_role(NA)) %>% step_epi_naomit() ``` diff --git a/vignettes/update.Rmd b/vignettes/update.Rmd index cb19ce192..fa395e192 100644 --- a/vignettes/update.Rmd +++ b/vignettes/update.Rmd @@ -1,8 +1,8 @@ --- -title: "Using the add/update/remove and adjust functions" +title: "Using the add, update, remove, and adjust functions" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Using the update and adjust functions} + %\VignetteIndexEntry{Using the add, update, remove, and adjust functions} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- From f5d2142127bd9370ccf32029999d71d57720e91d Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Mon, 12 Aug 2024 14:55:04 -0700 Subject: [PATCH 05/25] refactor prep.epi_recipe --- DESCRIPTION | 2 +- NAMESPACE | 2 - R/arx_classifier.R | 2 +- R/arx_forecaster.R | 2 +- R/epi_recipe.R | 336 ++---------------------- R/recipe.epi_df.R | 40 +++ man/arx_class_epi_workflow.Rd | 2 +- man/arx_classifier.Rd | 2 +- man/arx_forecaster.Rd | 2 +- man/{epi_recipe.Rd => recipe.epi_df.Rd} | 29 +- 10 files changed, 78 insertions(+), 341 deletions(-) rename man/{epi_recipe.Rd => recipe.epi_df.Rd} (81%) diff --git a/DESCRIPTION b/DESCRIPTION index a17f5580b..b7027fdf1 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -72,4 +72,4 @@ Config/testthat/edition: 3 Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 diff --git a/NAMESPACE b/NAMESPACE index 9180fcbca..020b5f45c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -28,8 +28,6 @@ S3method(bake,step_training_window) S3method(detect_layer,frosting) S3method(detect_layer,workflow) S3method(epi_recipe,default) -S3method(epi_recipe,epi_df) -S3method(epi_recipe,formula) S3method(extract_argument,epi_workflow) S3method(extract_argument,frosting) S3method(extract_argument,layer) diff --git a/R/arx_classifier.R b/R/arx_classifier.R index de730826c..819b00544 100644 --- a/R/arx_classifier.R +++ b/R/arx_classifier.R @@ -10,7 +10,7 @@ #' be real-valued. Conversion of this data to unordered classes is handled #' internally based on the `breaks` argument to [arx_class_args_list()]. #' If discrete classes are already in the `epi_df`, it is recommended to -#' code up a classifier from scratch using [epi_recipe()]. +#' code up a classifier from scratch using [recipe()]. #' @param trainer A `{parsnip}` model describing the type of estimation. #' For now, we enforce `mode = "classification"`. Typical values are #' [parsnip::logistic_reg()] or [parsnip::multinom_reg()]. More complicated diff --git a/R/arx_forecaster.R b/R/arx_forecaster.R index 10b2d2bce..c4e54a6b0 100644 --- a/R/arx_forecaster.R +++ b/R/arx_forecaster.R @@ -1,7 +1,7 @@ #' Direct autoregressive forecaster with covariates #' #' This is an autoregressive forecasting model for -#' [epiprocess::epi_df] data. It does "direct" forecasting, meaning +#' [`epiprocess::epi_df`] data. It does "direct" forecasting, meaning #' that it estimates a model for a particular target horizon. #' #' diff --git a/R/epi_recipe.R b/R/epi_recipe.R index 4afe1d6fb..4be01925f 100644 --- a/R/epi_recipe.R +++ b/R/epi_recipe.R @@ -1,11 +1,3 @@ -#' Create a epi_recipe for preprocessing data -#' -#' A recipe is a description of the steps to be applied to a data set in -#' order to prepare it for data analysis. This is a loose wrapper -#' around [recipes::recipe()] to properly handle the additional -#' columns present in an `epi_df` -#' -#' @aliases epi_recipe epi_recipe.default epi_recipe.formula #' @import recipes #' @export epi_recipe <- function(x, ...) { @@ -13,206 +5,16 @@ epi_recipe <- function(x, ...) { UseMethod("epi_recipe") } - -#' @rdname epi_recipe #' @export epi_recipe.default <- function(x, ...) { # if not a formula or an epi_df, we just pass to recipes::recipe # if (is.matrix(x) || is.data.frame(x) || tibble::is_tibble(x)) { # x <- x[1, , drop = FALSE] # } - recipes::recipe(x, ...) -} - -#' @rdname epi_recipe -#' @inheritParams recipes::recipe -#' @param roles A character string (the same length of `vars`) that -#' describes a single role that the variable will take. This value could be -#' anything but common roles are `"outcome"`, `"predictor"`, -#' `"time_value"`, and `"geo_value"` -#' @param ... Further arguments passed to or from other methods (not currently -#' used). -#' @param formula A model formula. No in-line functions should be used here -#' (e.g. `log(x)`, `x:y`, etc.) and minus signs are not allowed. These types of -#' transformations should be enacted using `step` functions in this package. -#' Dots are allowed as are simple multivariate outcome terms (i.e. no need for -#' `cbind`; see Examples). -#' @param x,data A data frame, tibble, or epi_df of the *template* data set -#' (see below). This is always coerced to the first row to avoid memory issues -#' @inherit recipes::recipe return -#' -#' @export -#' @examples -#' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-08-01") %>% -#' dplyr::arrange(geo_value, time_value) -#' -#' r <- epi_recipe(jhu) %>% -#' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% -#' step_epi_ahead(death_rate, ahead = 7) %>% -#' step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% -#' recipes::step_naomit(recipes::all_predictors()) %>% -#' # below, `skip` means we don't do this at predict time -#' recipes::step_naomit(recipes::all_outcomes(), skip = TRUE) -#' -#' r -epi_recipe.epi_df <- - function(x, formula = NULL, ..., vars = NULL, roles = NULL) { - return(recipe(x, formula = formula, ..., vars = vars, roles = roles)) - if (!is.null(formula)) { - if (!is.null(vars)) { - rlang::abort( - paste0( - "This `vars` specification will be ignored ", - "when a formula is used" - ) - ) - } - if (!is.null(roles)) { - rlang::abort( - paste0( - "This `roles` specification will be ignored ", - "when a formula is used" - ) - ) - } - - obj <- epi_recipe.formula(formula, x, ...) - return(obj) - } - if (is.null(vars)) vars <- colnames(x) - if (any(table(vars) > 1)) { - rlang::abort("`vars` should have unique members") - } - if (any(!(vars %in% colnames(x)))) { - rlang::abort("1 or more elements of `vars` are not in the data") - } - - keys <- epi_keys(x) # we know x is an epi_df - - var_info <- tibble(variable = vars) - key_roles <- c("time_value", "geo_value", rep("key", length(keys) - 2)) - - ## Check and add roles when available - if (!is.null(roles)) { - if (length(roles) != length(vars)) { - rlang::abort(c( - "The number of roles should be the same as the number of ", - "variables." - )) - } - var_info$role <- roles - } else { - var_info <- var_info %>% dplyr::filter(!(variable %in% keys)) - var_info$role <- "raw" - } - ## Now we add the keys when necessary - var_info <- dplyr::union( - var_info, - tibble::tibble(variable = keys, role = key_roles) - ) - - ## Add types - var_info <- dplyr::full_join(recipes:::get_types(x), var_info, by = "variable") - var_info$source <- "original" - - ## arrange to easy order - var_info <- var_info %>% - dplyr::arrange(factor( - role, - levels = union( - c("predictor", "outcome", "time_value", "geo_value", "key"), - unique(role) - ) # anything else - )) - - ## Return final object of class `recipe` - out <- list( - var_info = var_info, - term_info = var_info, - steps = NULL, - template = x[1, ], - max_time_value = max(x$time_value), - levels = NULL, - retained = NA - ) - class(out) <- c("epi_recipe", "recipe") - out - } - - -#' @rdname epi_recipe -#' @importFrom rlang abort -#' @export -epi_recipe.formula <- function(formula, data, ...) { - # we ensure that there's only 1 row in the template - return(recipe(data, formula, ...)) - # check for minus: - if (!epiprocess::is_epi_df(data)) { - return(recipes::recipe(formula, data, ...)) - } - - f_funcs <- recipes:::fun_calls(formula) - if (any(f_funcs == "-")) { - abort("`-` is not allowed in a recipe formula. Use `step_rm()` instead.") - } - - # Check for other in-line functions - args <- epi_form2args(formula, data, ...) - # browser() - obj <- recipe.epi_df( - x = args$x, - formula = NULL, - ..., - vars = args$vars, - roles = args$roles - ) - obj -} - - -# slightly modified version of `form2args()` in {recipes} -epi_form2args <- function(formula, data, ...) { - if (!rlang::is_formula(formula)) formula <- as.formula(formula) - - ## check for in-line formulas - recipes:::inline_check(formula) - - ## use rlang to get both sides of the formula - outcomes <- recipes:::get_lhs_vars(formula, data) - predictors <- recipes:::get_rhs_vars(formula, data, no_lhs = TRUE) - keys <- epi_keys(data) - - ## if . was used on the rhs, subtract out the outcomes - predictors <- predictors[!(predictors %in% outcomes)] - ## if . was used anywhere, remove epi_keys - if (rlang::f_lhs(formula) == ".") { - outcomes <- outcomes[!(outcomes %in% keys)] - } - if (rlang::f_rhs(formula) == ".") { - predictors <- predictors[!(predictors %in% keys)] - } - - ## get `vars` from rhs, lhs. keys get added downstream - vars <- c(predictors, outcomes) - ## subset data columns - data <- data[, union(vars, keys)] - - ## derive roles - roles <- rep("predictor", length(predictors)) - if (length(outcomes) > 0) { - roles <- c(roles, rep("outcome", length(outcomes))) - } - # if (length(keys) > 0) { - # roles <- c(roles, c("time_value", rep("key", length(keys) - 1))) - # } - - ## pass to recipe.default with vars and roles - list(x = data, vars = vars, roles = roles) + recipe(x, ...) } - #' Test for `epi_recipe` #' #' @param x An object. @@ -429,137 +231,39 @@ adjust_epi_recipe.epi_recipe <- function( x } -# unfortunately, almost everything the same as in prep.recipe except string/fctr handling + #' @export prep.epi_recipe <- function( x, training = NULL, fresh = FALSE, verbose = FALSE, retain = TRUE, log_changes = FALSE, strings_as_factors = TRUE, ...) { - if (is.null(training)) { - cli::cli_warn(c( - "!" = "No training data was supplied to {.fn prep}.", - "!" = "Unlike a {.cls recipe}, an {.cls epi_recipe} does not ", - "!" = "store the full template data in the object.", - "!" = "Please supply the training data to the {.fn prep} function,", - "!" = "to avoid addtional warning messages." - )) - } + + if (!strings_as_factors) return(NextMethod("prep")) + # workaround to avoid converting strings2factors with recipes::prep.recipe() + # We do the conversion here, then set it to FALSE training <- recipes:::check_training_set(training, x, fresh) training <- epi_check_training_set(training, x) training <- dplyr::relocate(training, tidyselect::all_of(epi_keys(training))) - tr_data <- recipes:::train_info(training) keys <- epi_keys(x) - orig_lvls <- lapply(training, recipes:::get_levels) orig_lvls <- kill_levels(orig_lvls, keys) - if (strings_as_factors) { - lvls <- lapply(training, recipes:::get_levels) - lvls <- kill_levels(lvls, keys) - training <- recipes:::strings2factors(training, lvls) - } else { - lvls <- NULL - } - skippers <- map_lgl(x$steps, recipes:::is_skipable) - if (any(skippers) & !retain) { - cli::cli_warn(c( - "Since some operations have `skip = TRUE`, using ", - "`retain = TRUE` will allow those steps results to ", - "be accessible." - )) - } - if (fresh) x$term_info <- x$var_info - - running_info <- x$term_info %>% dplyr::mutate(number = 0, skip = FALSE) - for (i in seq(along.with = x$steps)) { - needs_tuning <- map_lgl(x$steps[[i]], recipes:::is_tune) - if (any(needs_tuning)) { - arg <- names(needs_tuning)[needs_tuning] - arg <- paste0("'", arg, "'", collapse = ", ") - msg <- paste0( - "You cannot `prep()` a tuneable recipe. Argument(s) with `tune()`: ", - arg, ". Do you want to use a tuning function such as `tune_grid()`?" - ) - rlang::abort(msg) - } - note <- paste("oper", i, gsub("_", " ", class(x$steps[[i]])[1])) - if (!x$steps[[i]]$trained | fresh) { - if (verbose) { - cat(note, "[training]", "\n") - } - before_nms <- names(training) - before_template <- training[1, ] - x$steps[[i]] <- prep(x$steps[[i]], - training = training, - info = x$term_info - ) - training <- bake(x$steps[[i]], new_data = training) - if (!tibble::is_tibble(training)) { - cli::cli_abort("`bake()` methods should always return {.cls tibble}.") - } - if (!is_epi_df(training)) { - # tidymodels killed our class - # for now, we only allow step_epi_* to alter the metadata - training <- dplyr::dplyr_reconstruct( - epiprocess::as_epi_df(training), before_template - ) - } - training <- dplyr::relocate(training, tidyselect::all_of(epi_keys(training))) - x$term_info <- recipes:::merge_term_info(get_types(training), x$term_info) - if (!is.na(x$steps[[i]]$role)) { - new_vars <- setdiff(x$term_info$variable, running_info$variable) - pos_new_var <- x$term_info$variable %in% new_vars - pos_new_and_na_role <- pos_new_var & is.na(x$term_info$role) - pos_new_and_na_source <- pos_new_var & is.na(x$term_info$source) - x$term_info$role[pos_new_and_na_role] <- x$steps[[i]]$role - x$term_info$source[pos_new_and_na_source] <- "derived" - } - recipes:::changelog(log_changes, before_nms, names(training), x$steps[[i]]) - running_info <- rbind( - running_info, - dplyr::mutate(x$term_info, number = i, skip = x$steps[[i]]$skip) - ) - } else { - if (verbose) cat(note, "[pre-trained]\n") - } - } - if (strings_as_factors) { - lvls <- lapply(training, recipes:::get_levels) - lvls <- kill_levels(lvls, keys) - check_lvls <- recipes:::has_lvls(lvls) - if (!any(check_lvls)) lvls <- NULL - } else { - lvls <- NULL - } - if (retain) { - if (verbose) { - cat( - "The retained training set is ~", - format(utils::object.size(training), units = "Mb", digits = 2), - " in memory.\n\n" - ) - } - x$template <- training - } else { - x$template <- training[0, ] - } - x$max_time_value <- max(training$time_value) - x$tr_info <- tr_data - x$levels <- lvls + lvls <- lapply(training, recipes:::get_levels) + lvls <- kill_levels(lvls, keys) # don't do anything to the epi_keys + training <- recipes:::strings2factors(training, lvls) + strings_as_factors <- FALSE # now they're already done + + x <- NextMethod("prep") + # Now, we undo the conversion. + + lvls <- lapply(x$template, recipes:::get_levels) + lvls <- kill_levels(lvls, keys) + check_lvls <- recipes:::has_lvls(lvls) + if (!any(check_lvls)) lvls <- NULL + x$lvls <- lvls x$orig_lvls <- orig_lvls - x$retained <- retain - x$last_term_info <- running_info %>% - dplyr::group_by(variable) %>% - dplyr::arrange(dplyr::desc(number)) %>% - dplyr::summarise( - type = list(dplyr::first(type)), - role = list(unique(unlist(role))), - source = dplyr::first(source), - number = dplyr::first(number), - skip = dplyr::first(skip), - .groups = "keep" - ) x } + #' @export bake.epi_recipe <- function(object, new_data, ..., composition = "epi_df") { meta <- NULL diff --git a/R/recipe.epi_df.R b/R/recipe.epi_df.R index eae58d256..308cc6033 100644 --- a/R/recipe.epi_df.R +++ b/R/recipe.epi_df.R @@ -1,3 +1,43 @@ +#' Create a recipe for preprocessing panel data +#' +#' A recipe is a description of the steps to be applied to a data set in +#' order to prepare it for data analysis. This is an S3 method for +#' [recipes::recipe()] to properly handle the additional (panel data) +#' columns present in an [`epiprocess::epi_df`]: `time_value`, `geo_value`, and any +#' additional keys. +#' +#' @aliases epi_recipe epi_recipe.default epi_recipe.formula +#' @inheritParams recipes::recipe +#' @param roles A character string (the same length of `vars`) that +#' describes a single role that the variable will take. This value could be +#' anything but common roles are `"outcome"`, `"predictor"`, +#' `"time_value"`, and `"geo_value"` +#' @param ... Further arguments passed to or from other methods (not currently +#' used). +#' @param formula A model formula. No in-line functions should be used here +#' (e.g. `log(x)`, `x:y`, etc.) and minus signs are not allowed. These types of +#' transformations should be enacted using `step` functions in this package. +#' Dots are allowed as are simple multivariate outcome terms (i.e. no need for +#' `cbind`; see Examples). +#' @param x,data A data frame, tibble, or epi_df of the *template* data set +#' (see below). This is always coerced to the first row to avoid memory issues +#' @inherit recipes::recipe return +#' +#' @export +#' @examples +#' jhu <- case_death_rate_subset %>% +#' dplyr::filter(time_value > "2021-08-01") %>% +#' dplyr::arrange(geo_value, time_value) +#' +#' r <- epi_recipe(jhu) %>% +#' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% +#' step_epi_ahead(death_rate, ahead = 7) %>% +#' step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% +#' recipes::step_naomit(recipes::all_predictors()) %>% +#' # below, `skip` means we don't do this at predict time +#' recipes::step_naomit(recipes::all_outcomes(), skip = TRUE) +#' +#' r #' @importFrom recipes recipe #' @export recipe.epi_df <- function(x, formula = NULL, ..., vars = NULL, roles = NULL) { diff --git a/man/arx_class_epi_workflow.Rd b/man/arx_class_epi_workflow.Rd index bfce7cdaa..f6a00f1b4 100644 --- a/man/arx_class_epi_workflow.Rd +++ b/man/arx_class_epi_workflow.Rd @@ -20,7 +20,7 @@ arx_class_epi_workflow( be real-valued. Conversion of this data to unordered classes is handled internally based on the \code{breaks} argument to \code{\link[=arx_class_args_list]{arx_class_args_list()}}. If discrete classes are already in the \code{epi_df}, it is recommended to -code up a classifier from scratch using \code{\link[=epi_recipe]{epi_recipe()}}.} +code up a classifier from scratch using \code{\link[=recipe]{recipe()}}.} \item{predictors}{A character vector giving column(s) of predictor variables. This defaults to the \code{outcome}. However, if manually specified, only those variables diff --git a/man/arx_classifier.Rd b/man/arx_classifier.Rd index 350352ae9..85543af7d 100644 --- a/man/arx_classifier.Rd +++ b/man/arx_classifier.Rd @@ -20,7 +20,7 @@ arx_classifier( be real-valued. Conversion of this data to unordered classes is handled internally based on the \code{breaks} argument to \code{\link[=arx_class_args_list]{arx_class_args_list()}}. If discrete classes are already in the \code{epi_df}, it is recommended to -code up a classifier from scratch using \code{\link[=epi_recipe]{epi_recipe()}}.} +code up a classifier from scratch using \code{\link[=recipe]{recipe()}}.} \item{predictors}{A character vector giving column(s) of predictor variables. This defaults to the \code{outcome}. However, if manually specified, only those variables diff --git a/man/arx_forecaster.Rd b/man/arx_forecaster.Rd index af05c0682..173fa2bbd 100644 --- a/man/arx_forecaster.Rd +++ b/man/arx_forecaster.Rd @@ -37,7 +37,7 @@ workflow } \description{ This is an autoregressive forecasting model for -\link[epiprocess:epi_df]{epiprocess::epi_df} data. It does "direct" forecasting, meaning +\code{\link[epiprocess:epi_df]{epiprocess::epi_df}} data. It does "direct" forecasting, meaning that it estimates a model for a particular target horizon. } \examples{ diff --git a/man/epi_recipe.Rd b/man/recipe.epi_df.Rd similarity index 81% rename from man/epi_recipe.Rd rename to man/recipe.epi_df.Rd index 1c9048a36..d7aa7aa90 100644 --- a/man/epi_recipe.Rd +++ b/man/recipe.epi_df.Rd @@ -1,33 +1,27 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/epi_recipe.R -\name{epi_recipe} +% Please edit documentation in R/recipe.epi_df.R +\name{recipe.epi_df} +\alias{recipe.epi_df} \alias{epi_recipe} \alias{epi_recipe.default} \alias{epi_recipe.formula} -\alias{epi_recipe.epi_df} -\title{Create a epi_recipe for preprocessing data} +\title{Create a recipe for preprocessing panel data} \usage{ -epi_recipe(x, ...) - -\method{epi_recipe}{default}(x, ...) - -\method{epi_recipe}{epi_df}(x, formula = NULL, ..., vars = NULL, roles = NULL) - -\method{epi_recipe}{formula}(formula, data, ...) +\method{recipe}{epi_df}(x, formula = NULL, ..., vars = NULL, roles = NULL) } \arguments{ \item{x, data}{A data frame, tibble, or epi_df of the \emph{template} data set (see below). This is always coerced to the first row to avoid memory issues} -\item{...}{Further arguments passed to or from other methods (not currently -used).} - \item{formula}{A model formula. No in-line functions should be used here (e.g. \code{log(x)}, \code{x:y}, etc.) and minus signs are not allowed. These types of transformations should be enacted using \code{step} functions in this package. Dots are allowed as are simple multivariate outcome terms (i.e. no need for \code{cbind}; see Examples).} +\item{...}{Further arguments passed to or from other methods (not currently +used).} + \item{vars}{A character string of column names corresponding to variables that will be used in any context (see below)} @@ -52,9 +46,10 @@ the recipe is trained.} } \description{ A recipe is a description of the steps to be applied to a data set in -order to prepare it for data analysis. This is a loose wrapper -around \code{\link[recipes:recipe]{recipes::recipe()}} to properly handle the additional -columns present in an \code{epi_df} +order to prepare it for data analysis. This is an S3 method for +\code{\link[recipes:recipe]{recipes::recipe()}} to properly handle the additional (panel data) +columns present in an \code{\link[epiprocess:epi_df]{epiprocess::epi_df}}: \code{time_value}, \code{geo_value}, and any +additional keys. } \examples{ jhu <- case_death_rate_subset \%>\% From aa4e78885ed93f0f5120cf58217d21f93d78c713 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Mon, 12 Aug 2024 16:30:38 -0700 Subject: [PATCH 06/25] remove all instances of epi_recipe, pass checks --- NAMESPACE | 1 + R/arx_classifier.R | 2 +- R/arx_forecaster.R | 2 +- R/autoplot.R | 11 +++-- R/cdc_baseline_forecaster.R | 42 ++++++++-------- R/epi_recipe.R | 17 ++++--- R/epi_workflow.R | 11 +++-- R/flatline_forecaster.R | 2 +- R/frosting.R | 17 ++++--- R/get_test_data.R | 2 +- R/layer_add_forecast_date.R | 9 ++-- R/layer_add_target_date.R | 7 +-- R/layer_cdc_flatline_quantiles.R | 48 +++++++++---------- R/layer_naomit.R | 5 +- R/layer_point_from_distn.R | 8 ++-- R/layer_population_scaling.R | 11 +++-- R/layer_predict.R | 4 +- R/layer_predictive_distn.R | 7 +-- R/layer_quantile_distn.R | 5 +- R/layer_residual_quantiles.R | 7 +-- R/layer_threshold_preds.R | 9 ++-- R/layers.R | 7 +-- R/make_smooth_quantile_reg.R | 21 ++++---- R/model-methods.R | 10 ++-- R/recipe.epi_df.R | 13 +++-- R/reexports-tidymodels.R | 4 ++ R/step_epi_naomit.R | 2 +- R/step_epi_shift.R | 2 +- R/step_epi_slide.R | 4 +- R/step_growth_rate.R | 2 +- R/step_lag_difference.R | 2 +- R/step_population_scaling.R | 13 +++-- R/step_training_window.R | 7 +-- R/tidy.R | 7 +-- man/Add_model.Rd | 10 ++-- man/add_epi_recipe.Rd | 4 +- man/add_frosting.Rd | 5 +- man/adjust_epi_recipe.Rd | 4 +- man/adjust_frosting.Rd | 5 +- man/arx_forecaster.Rd | 2 +- man/autoplot-epipred.Rd | 11 +++-- man/cdc_baseline_forecaster.Rd | 38 +++++++-------- man/epi_workflow.Rd | 2 +- man/fit-epi_workflow.Rd | 2 +- man/frosting.Rd | 7 +-- man/get_test_data.Rd | 2 +- man/layer_add_forecast_date.Rd | 9 ++-- man/layer_add_target_date.Rd | 7 +-- man/layer_cdc_flatline_quantiles.Rd | 48 +++++++++---------- man/layer_naomit.Rd | 5 +- man/layer_point_from_distn.Rd | 8 ++-- man/layer_population_scaling.Rd | 11 +++-- man/layer_predict.Rd | 4 +- man/layer_predictive_distn.Rd | 7 +-- man/layer_quantile_distn.Rd | 5 +- man/layer_residual_quantiles.Rd | 7 +-- man/layer_threshold.Rd | 8 ++-- man/predict-epi_workflow.Rd | 7 +-- man/recipe.epi_df.Rd | 15 ++++-- man/reexports.Rd | 3 +- man/smooth_quantile_reg.Rd | 21 ++++---- man/step_epi_naomit.Rd | 2 +- man/step_epi_shift.Rd | 2 +- man/step_epi_slide.Rd | 4 +- man/step_growth_rate.Rd | 2 +- man/step_lag_difference.Rd | 2 +- man/step_population_scaling.Rd | 13 +++-- man/step_training_window.Rd | 7 +-- man/tidy.frosting.Rd | 7 +-- man/update.layer.Rd | 7 +-- tests/testthat/test-bake-method.R | 4 +- tests/testthat/test-check_enough_train_data.R | 22 ++++----- tests/testthat/test-epi_keys.R | 4 +- tests/testthat/test-epi_recipe.R | 19 -------- tests/testthat/test-epi_workflow.R | 10 ++-- tests/testthat/test-extract_argument.R | 2 +- tests/testthat/test-frosting.R | 6 +-- tests/testthat/test-get_test_data.R | 14 +++--- tests/testthat/test-layer_add_forecast_date.R | 2 +- tests/testthat/test-layer_add_target_date.R | 2 +- tests/testthat/test-layer_naomit.R | 2 +- tests/testthat/test-layer_predict.R | 2 +- .../testthat/test-layer_residual_quantiles.R | 4 +- tests/testthat/test-layer_threshold_preds.R | 2 +- tests/testthat/test-population_scaling.R | 26 +++++----- tests/testthat/test-step_epi_naomit.R | 2 +- tests/testthat/test-step_epi_shift.R | 10 ++-- tests/testthat/test-step_epi_slide.R | 4 +- tests/testthat/test-step_growth_rate.R | 10 ++-- tests/testthat/test-step_lag_difference.R | 10 ++-- tests/testthat/test-step_training_window.R | 23 +++++---- vignettes/articles/smooth-qr.Rmd | 2 +- vignettes/epipredict.Rmd | 4 +- vignettes/panel-data.Rmd | 4 +- vignettes/preprocessing-and-models.Rmd | 10 ++-- vignettes/update.Rmd | 6 +-- 96 files changed, 426 insertions(+), 404 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index fd57a07f7..1cf322207 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -184,6 +184,7 @@ export(pivot_quantiles_longer) export(pivot_quantiles_wider) export(prep) export(quantile_reg) +export(recipe) export(remove_epi_recipe) export(remove_frosting) export(remove_model) diff --git a/R/arx_classifier.R b/R/arx_classifier.R index 1e832d060..54966337b 100644 --- a/R/arx_classifier.R +++ b/R/arx_classifier.R @@ -128,7 +128,7 @@ arx_class_epi_workflow <- function( # --- preprocessor # ------- predictors - r <- epi_recipe(epi_data) %>% + r <- recipe(epi_data) %>% step_growth_rate( tidyselect::all_of(predictors), role = "grp", diff --git a/R/arx_forecaster.R b/R/arx_forecaster.R index 1b9e3d503..d19e16cb3 100644 --- a/R/arx_forecaster.R +++ b/R/arx_forecaster.R @@ -121,7 +121,7 @@ arx_fcast_epi_workflow <- function( lags <- arx_lags_validator(predictors, args_list$lags) # --- preprocessor - r <- epi_recipe(epi_data) + r <- recipe(epi_data) for (l in seq_along(lags)) { p <- predictors[l] r <- step_epi_lag(r, !!p, lag = lags[[l]]) diff --git a/R/autoplot.R b/R/autoplot.R index 143ab35d5..ec9a6bba6 100644 --- a/R/autoplot.R +++ b/R/autoplot.R @@ -28,10 +28,11 @@ ggplot2::autoplot #' #' @name autoplot-epipred #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% #' filter(time_value >= as.Date("2021-11-01")) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% @@ -41,21 +42,21 @@ ggplot2::autoplot #' layer_residual_quantiles( #' quantile_levels = c(.025, .1, .25, .75, .9, .975) #' ) %>% -#' layer_threshold(dplyr::starts_with(".pred")) %>% +#' layer_threshold(starts_with(".pred")) %>% #' layer_add_target_date() #' -#' wf <- epi_workflow(r, parsnip::linear_reg(), f) %>% fit(jhu) +#' wf <- epi_workflow(r, linear_reg(), f) %>% fit(jhu) #' #' autoplot(wf) #' -#' latest <- jhu %>% dplyr::filter(time_value >= max(time_value) - 14) +#' latest <- jhu %>% filter(time_value >= max(time_value) - 14) #' preds <- predict(wf, latest) #' autoplot(wf, preds, .max_facets = 4) #' #' # ------- Show multiple horizons #' #' p <- lapply(c(7, 14, 21, 28), \(h) { -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = h) %>% #' step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% diff --git a/R/cdc_baseline_forecaster.R b/R/cdc_baseline_forecaster.R index d5b74a9c3..5117c7bb4 100644 --- a/R/cdc_baseline_forecaster.R +++ b/R/cdc_baseline_forecaster.R @@ -36,25 +36,25 @@ #' cdc <- cdc_baseline_forecaster(weekly_deaths, "deaths") #' preds <- pivot_quantiles_wider(cdc$predictions, .pred_distn) #' -#' if (require(ggplot2)) { -#' forecast_date <- unique(preds$forecast_date) -#' four_states <- c("ca", "pa", "wa", "ny") -#' preds %>% -#' filter(geo_value %in% four_states) %>% -#' ggplot(aes(target_date)) + -#' geom_ribbon(aes(ymin = `0.1`, ymax = `0.9`), fill = blues9[3]) + -#' geom_ribbon(aes(ymin = `0.25`, ymax = `0.75`), fill = blues9[6]) + -#' geom_line(aes(y = .pred), color = "orange") + -#' geom_line( -#' data = weekly_deaths %>% filter(geo_value %in% four_states), -#' aes(x = time_value, y = deaths) -#' ) + -#' scale_x_date(limits = c(forecast_date - 90, forecast_date + 30)) + -#' labs(x = "Date", y = "Weekly deaths") + -#' facet_wrap(~geo_value, scales = "free_y") + -#' theme_bw() + -#' geom_vline(xintercept = forecast_date) -#' } +#' library(ggplot2) +#' forecast_date <- unique(preds$forecast_date) +#' four_states <- c("ca", "pa", "wa", "ny") +#' preds %>% +#' filter(geo_value %in% four_states) %>% +#' ggplot(aes(target_date)) + +#' geom_ribbon(aes(ymin = `0.1`, ymax = `0.9`), fill = blues9[3]) + +#' geom_ribbon(aes(ymin = `0.25`, ymax = `0.75`), fill = blues9[6]) + +#' geom_line(aes(y = .pred), color = "orange") + +#' geom_line( +#' data = weekly_deaths %>% filter(geo_value %in% four_states), +#' aes(x = time_value, y = deaths) +#' ) + +#' scale_x_date(limits = c(forecast_date - 90, forecast_date + 30)) + +#' labs(x = "Date", y = "Weekly deaths") + +#' facet_wrap(~geo_value, scales = "free_y") + +#' theme_bw() + +#' geom_vline(xintercept = forecast_date) +#' cdc_baseline_forecaster <- function( epi_data, outcome, @@ -68,7 +68,7 @@ cdc_baseline_forecaster <- function( outcome <- rlang::sym(outcome) - r <- epi_recipe(epi_data) %>% + r <- recipe(epi_data) %>% step_epi_ahead(!!outcome, ahead = args_list$data_frequency, skip = TRUE) %>% recipes::update_role(!!outcome, new_role = "predictor") %>% recipes::add_role(tidyselect::all_of(keys), new_role = "predictor") %>% @@ -79,7 +79,7 @@ cdc_baseline_forecaster <- function( latest <- get_test_data( - epi_recipe(epi_data), epi_data, TRUE, args_list$nafill_buffer, + recipe(epi_data), epi_data, TRUE, args_list$nafill_buffer, forecast_date ) diff --git a/R/epi_recipe.R b/R/epi_recipe.R index 24ae734c9..bd0aba28b 100644 --- a/R/epi_recipe.R +++ b/R/epi_recipe.R @@ -65,7 +65,7 @@ is_epi_recipe <- function(x) { #' filter(time_value > "2021-08-01") %>% #' arrange(geo_value, time_value) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% @@ -77,7 +77,7 @@ is_epi_recipe <- function(x) { #' #' workflow #' -#' r2 <- epi_recipe(jhu) %>% +#' r2 <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) #' @@ -147,12 +147,12 @@ update_epi_recipe <- function(x, recipe, ..., blueprint = default_epi_recipe_blu #' #' jhu <- case_death_rate_subset %>% #' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() #' -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) +#' wf <- epi_workflow(r, linear_reg()) %>% fit(jhu) #' latest <- jhu %>% #' filter(time_value >= max(time_value) - 14) #' @@ -239,16 +239,19 @@ prep.epi_recipe <- function( lvls <- lapply(training, recipes:::get_levels) lvls <- kill_levels(lvls, keys) # don't do anything to the epi_keys training <- recipes:::strings2factors(training, lvls) - strings_as_factors <- FALSE # now they're already done - x <- NextMethod("prep") + # browser() + x <- NextMethod("prep", training = training, fresh = fresh, + verbose = verbose, + retain = retain, log_changes = log_changes, + strings_as_factors = FALSE, ...) # Now, we undo the conversion. lvls <- lapply(x$template, recipes:::get_levels) lvls <- kill_levels(lvls, keys) check_lvls <- recipes:::has_lvls(lvls) if (!any(check_lvls)) lvls <- NULL - x$lvls <- lvls + x$levels <- lvls x$orig_lvls <- orig_lvls x } diff --git a/R/epi_workflow.R b/R/epi_workflow.R index 0bdeece4f..43db5d38c 100644 --- a/R/epi_workflow.R +++ b/R/epi_workflow.R @@ -22,7 +22,7 @@ #' @examples #' jhu <- case_death_rate_subset #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% @@ -87,7 +87,7 @@ is_epi_workflow <- function(x) { #' jhu <- case_death_rate_subset %>% #' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) #' @@ -139,16 +139,17 @@ fit.epi_workflow <- function(object, data, ..., control = workflows::control_wor #' @name predict-epi_workflow #' @export #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% #' step_epi_naomit() #' -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) -#' latest <- jhu %>% dplyr::filter(time_value >= max(time_value) - 14) +#' wf <- epi_workflow(r, linear_reg()) %>% fit(jhu) +#' latest <- jhu %>% filter(time_value >= max(time_value) - 14) #' #' preds <- predict(wf, latest) #' preds diff --git a/R/flatline_forecaster.R b/R/flatline_forecaster.R index e14e44a96..a9fad8807 100644 --- a/R/flatline_forecaster.R +++ b/R/flatline_forecaster.R @@ -40,7 +40,7 @@ flatline_forecaster <- function( outcome <- rlang::sym(outcome) - r <- epi_recipe(epi_data) %>% + r <- recipe(epi_data) %>% step_epi_ahead(!!outcome, ahead = args_list$ahead, skip = TRUE) %>% recipes::update_role(!!outcome, new_role = "predictor") %>% recipes::add_role(tidyselect::all_of(keys), new_role = "predictor") %>% diff --git a/R/frosting.R b/R/frosting.R index 4fc0caec3..d11a23ca2 100644 --- a/R/frosting.R +++ b/R/frosting.R @@ -8,15 +8,16 @@ #' @export #' #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% #' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) #' #' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) #' latest <- jhu %>% -#' dplyr::filter(time_value >= max(time_value) - 14) +#' filter(time_value >= max(time_value) - 14) #' #' # Add frosting to a workflow and predict #' f <- frosting() %>% @@ -125,14 +126,15 @@ update_frosting <- function(x, frosting, ...) { #' #' @export #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% #' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() #' -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) +#' wf <- epi_workflow(r, linear_reg()) %>% fit(jhu) #' #' # in the frosting from the workflow #' f1 <- frosting() %>% @@ -266,15 +268,16 @@ new_frosting <- function() { #' wf <- epi_workflow() %>% add_frosting(f) #' #' # A more realistic example +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) +#' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() #' -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) +#' wf <- epi_workflow(r, linear_reg()) %>% fit(jhu) #' #' f <- frosting() %>% #' layer_predict() %>% diff --git a/R/get_test_data.R b/R/get_test_data.R index 0a7d0dc2a..63c677c31 100644 --- a/R/get_test_data.R +++ b/R/get_test_data.R @@ -35,7 +35,7 @@ #' keys, as well other variables in the original dataset. #' @examples #' # create recipe -#' rec <- epi_recipe(case_death_rate_subset) %>% +#' rec <- recipe(case_death_rate_subset) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_lag(case_rate, lag = c(0, 7, 14)) diff --git a/R/layer_add_forecast_date.R b/R/layer_add_forecast_date.R index c4bb7d483..c90face25 100644 --- a/R/layer_add_forecast_date.R +++ b/R/layer_add_forecast_date.R @@ -19,15 +19,16 @@ #' #' @export #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) -#' r <- epi_recipe(jhu) %>% +#' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) +#' wf <- epi_workflow(r, linear_reg()) %>% fit(jhu) #' latest <- jhu %>% -#' dplyr::filter(time_value >= max(time_value) - 14) +#' filter(time_value >= max(time_value) - 14) #' #' # Don't specify `forecast_date` (by default, this should be last date in latest) #' f <- frosting() %>% diff --git a/R/layer_add_target_date.R b/R/layer_add_target_date.R index 23aeb4091..5840b555b 100644 --- a/R/layer_add_target_date.R +++ b/R/layer_add_target_date.R @@ -20,14 +20,15 @@ #' #' @export #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) -#' r <- epi_recipe(jhu) %>% +#' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() #' -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) +#' wf <- epi_workflow(r, linear_reg()) %>% fit(jhu) #' #' # Use ahead + forecast date #' f <- frosting() %>% diff --git a/R/layer_cdc_flatline_quantiles.R b/R/layer_cdc_flatline_quantiles.R index f54c1da78..5ad7c6c12 100644 --- a/R/layer_cdc_flatline_quantiles.R +++ b/R/layer_cdc_flatline_quantiles.R @@ -55,12 +55,13 @@ #' @export #' #' @examples -#' r <- epi_recipe(case_death_rate_subset) %>% +#' library(recipes) +#' r <- recipe(case_death_rate_subset) %>% #' # data is "daily", so we fit this to 1 ahead, the result will contain #' # 1 day ahead residuals #' step_epi_ahead(death_rate, ahead = 1L, skip = TRUE) %>% -#' recipes::update_role(death_rate, new_role = "predictor") %>% -#' recipes::add_role(time_value, geo_value, new_role = "predictor") +#' update_role(death_rate, new_role = "predictor") %>% +#' add_role(time_value, geo_value, new_role = "predictor") #' #' forecast_date <- max(case_death_rate_subset$time_value) #' @@ -68,12 +69,12 @@ #' layer_predict() %>% #' layer_cdc_flatline_quantiles(aheads = c(7, 14, 21, 28), symmetrize = TRUE) #' -#' eng <- parsnip::linear_reg() %>% parsnip::set_engine("flatline") +#' eng <- linear_reg() %>% set_engine("flatline") #' #' wf <- epi_workflow(r, eng, f) %>% fit(case_death_rate_subset) #' preds <- forecast(wf) %>% -#' dplyr::select(-time_value) %>% -#' dplyr::mutate(forecast_date = forecast_date) +#' select(-time_value) %>% +#' mutate(forecast_date = forecast_date) #' preds #' #' preds <- preds %>% @@ -81,24 +82,23 @@ #' pivot_quantiles_wider(.pred_distn) %>% #' mutate(target_date = forecast_date + ahead) #' -#' if (require("ggplot2")) { -#' four_states <- c("ca", "pa", "wa", "ny") -#' preds %>% -#' filter(geo_value %in% four_states) %>% -#' ggplot(aes(target_date)) + -#' geom_ribbon(aes(ymin = `0.1`, ymax = `0.9`), fill = blues9[3]) + -#' geom_ribbon(aes(ymin = `0.25`, ymax = `0.75`), fill = blues9[6]) + -#' geom_line(aes(y = .pred), color = "orange") + -#' geom_line( -#' data = case_death_rate_subset %>% filter(geo_value %in% four_states), -#' aes(x = time_value, y = death_rate) -#' ) + -#' scale_x_date(limits = c(forecast_date - 90, forecast_date + 30)) + -#' labs(x = "Date", y = "Death rate") + -#' facet_wrap(~geo_value, scales = "free_y") + -#' theme_bw() + -#' geom_vline(xintercept = forecast_date) -#' } +#' library(ggplot2) +#' four_states <- c("ca", "pa", "wa", "ny") +#' preds %>% +#' filter(geo_value %in% four_states) %>% +#' ggplot(aes(target_date)) + +#' geom_ribbon(aes(ymin = `0.1`, ymax = `0.9`), fill = blues9[3]) + +#' geom_ribbon(aes(ymin = `0.25`, ymax = `0.75`), fill = blues9[6]) + +#' geom_line(aes(y = .pred), color = "orange") + +#' geom_line( +#' data = case_death_rate_subset %>% filter(geo_value %in% four_states), +#' aes(x = time_value, y = death_rate) +#' ) + +#' scale_x_date(limits = c(forecast_date - 90, forecast_date + 30)) + +#' labs(x = "Date", y = "Death rate") + +#' facet_wrap(~geo_value, scales = "free_y") + +#' theme_bw() + +#' geom_vline(xintercept = forecast_date) layer_cdc_flatline_quantiles <- function( frosting, ..., diff --git a/R/layer_naomit.R b/R/layer_naomit.R index 85842bfdf..a133180ad 100644 --- a/R/layer_naomit.R +++ b/R/layer_naomit.R @@ -11,10 +11,11 @@ #' @return an updated `frosting` postprocessor #' @export #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) +#' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) #' diff --git a/R/layer_point_from_distn.R b/R/layer_point_from_distn.R index f415e7bd4..a16306ee0 100644 --- a/R/layer_point_from_distn.R +++ b/R/layer_point_from_distn.R @@ -16,15 +16,17 @@ #' @export #' #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) +#' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() #' -#' wf <- epi_workflow(r, quantile_reg(quantile_levels = c(.25, .5, .75))) %>% fit(jhu) +#' wf <- epi_workflow(r, quantile_reg(quantile_levels = c(.25, .5, .75))) %>% +#' fit(jhu) #' #' f1 <- frosting() %>% #' layer_predict() %>% diff --git a/R/layer_population_scaling.R b/R/layer_population_scaling.R index 33183198d..f3b267f04 100644 --- a/R/layer_population_scaling.R +++ b/R/layer_population_scaling.R @@ -47,13 +47,14 @@ #' @return an updated `frosting` postprocessor #' @export #' @examples -#' jhu <- epiprocess::jhu_csse_daily_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ca", "ny")) %>% -#' dplyr::select(geo_value, time_value, cases) +#' library(dplyr) +#' jhu <- jhu_csse_daily_subset %>% +#' filter(time_value > "2021-11-01", geo_value %in% c("ca", "ny")) %>% +#' select(geo_value, time_value, cases) #' #' pop_data <- data.frame(states = c("ca", "ny"), value = c(20000, 30000)) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_population_scaling( #' df = pop_data, #' df_pop_col = "value", @@ -74,7 +75,7 @@ #' df_pop_col = "value" #' ) #' -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% +#' wf <- epi_workflow(r, linear_reg()) %>% #' fit(jhu) %>% #' add_frosting(f) #' diff --git a/R/layer_predict.R b/R/layer_predict.R index 46d81be18..c452dd25e 100644 --- a/R/layer_predict.R +++ b/R/layer_predict.R @@ -19,12 +19,12 @@ #' jhu <- case_death_rate_subset %>% #' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() #' -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) +#' wf <- epi_workflow(r, linear_reg()) %>% fit(jhu) #' latest <- jhu %>% filter(time_value >= max(time_value) - 14) #' #' # Predict layer alone diff --git a/R/layer_predictive_distn.R b/R/layer_predictive_distn.R index 9b1a160e1..00d096d50 100644 --- a/R/layer_predictive_distn.R +++ b/R/layer_predictive_distn.R @@ -20,15 +20,16 @@ #' @export #' #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) +#' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() #' -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) +#' wf <- epi_workflow(r, linear_reg()) %>% fit(jhu) #' #' f <- frosting() %>% #' layer_predict() %>% diff --git a/R/layer_quantile_distn.R b/R/layer_quantile_distn.R index 734ccec9e..c875d6c5b 100644 --- a/R/layer_quantile_distn.R +++ b/R/layer_quantile_distn.R @@ -17,10 +17,11 @@ #' @export #' #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) +#' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() diff --git a/R/layer_residual_quantiles.R b/R/layer_residual_quantiles.R index 85c1c6ed0..ef5be371b 100644 --- a/R/layer_residual_quantiles.R +++ b/R/layer_residual_quantiles.R @@ -14,15 +14,16 @@ #' residual quantiles added to the prediction #' @export #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) +#' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() #' -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) +#' wf <- epi_workflow(r, linear_reg()) %>% fit(jhu) #' #' f <- frosting() %>% #' layer_predict() %>% diff --git a/R/layer_threshold_preds.R b/R/layer_threshold_preds.R index 8b2b56d1e..233adbf0c 100644 --- a/R/layer_threshold_preds.R +++ b/R/layer_threshold_preds.R @@ -22,15 +22,14 @@ #' @return an updated `frosting` postprocessor #' @export #' @examples - +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value < "2021-03-08", -#' geo_value %in% c("ak", "ca", "ar")) -#' r <- epi_recipe(jhu) %>% +#' filter(time_value < "2021-03-08", geo_value %in% c("ak", "ca", "ar")) +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) +#' wf <- epi_workflow(r, linear_reg()) %>% fit(jhu) #' #' f <- frosting() %>% #' layer_predict() %>% diff --git a/R/layers.R b/R/layers.R index b59e95cdd..1ecf861bc 100644 --- a/R/layers.R +++ b/R/layers.R @@ -41,15 +41,16 @@ layer <- function(subclass, ..., .prefix = "layer_") { #' in the layer, and the values are the new values to update the layer with. #' #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) -#' r <- epi_recipe(jhu) %>% +#' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() #' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) #' latest <- jhu %>% -#' dplyr::filter(time_value >= max(time_value) - 14) +#' filter(time_value >= max(time_value) - 14) #' #' # Specify a `forecast_date` that is greater than or equal to `as_of` date #' f <- frosting() %>% diff --git a/R/make_smooth_quantile_reg.R b/R/make_smooth_quantile_reg.R index 9ab3a366b..dc585de22 100644 --- a/R/make_smooth_quantile_reg.R +++ b/R/make_smooth_quantile_reg.R @@ -62,17 +62,16 @@ #' lines(pl$x, pl$`0.8`, col = "blue") #' lines(pl$x, pl$`0.5`, col = "red") #' -#' if (require("ggplot2")) { -#' ggplot(data.frame(x = x, y = y), aes(x)) + -#' geom_ribbon(data = pl, aes(ymin = `0.2`, ymax = `0.8`), fill = "lightblue") + -#' geom_point(aes(y = y), colour = "grey") + # observed data -#' geom_function(fun = sin, colour = "black") + # truth -#' geom_vline(xintercept = fd, linetype = "dashed") + # end of training data -#' geom_line(data = pl, aes(y = `0.5`), colour = "red") + # median prediction -#' theme_bw() + -#' coord_cartesian(xlim = c(0, NA)) + -#' ylab("y") -#' } +#' library(ggplot2) +#' ggplot(data.frame(x = x, y = y), aes(x)) + +#' geom_ribbon(data = pl, aes(ymin = `0.2`, ymax = `0.8`), fill = "lightblue") + +#' geom_point(aes(y = y), colour = "grey") + # observed data +#' geom_function(fun = sin, colour = "black") + # truth +#' geom_vline(xintercept = fd, linetype = "dashed") + # end of training data +#' geom_line(data = pl, aes(y = `0.5`), colour = "red") + # median prediction +#' theme_bw() + +#' coord_cartesian(xlim = c(0, NA)) + +#' ylab("y") smooth_quantile_reg <- function( mode = "regression", engine = "smoothqr", diff --git a/R/model-methods.R b/R/model-methods.R index 607b04234..131a6ee91 100644 --- a/R/model-methods.R +++ b/R/model-methods.R @@ -32,13 +32,11 @@ #' #' @export #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter( -#' time_value > "2021-11-01", -#' geo_value %in% c("ak", "ca", "ny") -#' ) +#' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) #' @@ -49,7 +47,7 @@ #' wf <- wf %>% Add_model(rf_model) #' wf #' -#' lm_model <- parsnip::linear_reg() +#' lm_model <- linear_reg() #' #' wf <- Update_model(wf, lm_model) #' wf diff --git a/R/recipe.epi_df.R b/R/recipe.epi_df.R index 308cc6033..8b7f67572 100644 --- a/R/recipe.epi_df.R +++ b/R/recipe.epi_df.R @@ -25,17 +25,19 @@ #' #' @export #' @examples +#' library(dplyr) +#' library(recipes) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-08-01") %>% -#' dplyr::arrange(geo_value, time_value) +#' filter(time_value > "2021-08-01") %>% +#' arrange(geo_value, time_value) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% -#' recipes::step_naomit(recipes::all_predictors()) %>% +#' step_naomit(recipes::all_predictors()) %>% #' # below, `skip` means we don't do this at predict time -#' recipes::step_naomit(recipes::all_outcomes(), skip = TRUE) +#' step_naomit(recipes::all_outcomes(), skip = TRUE) #' #' r #' @importFrom recipes recipe @@ -63,6 +65,7 @@ recipe.epi_df <- function(x, formula = NULL, ..., vars = NULL, roles = NULL) { } #' @exportS3Method recipes::recipe +#' @rdname recipe.epi_df recipe.formula <- function(formula, data, ...) { # This method clobbers `recipes::recipe.formula`, but should have no noticible # effect. diff --git a/R/reexports-tidymodels.R b/R/reexports-tidymodels.R index 2c69139a2..d099cde4a 100644 --- a/R/reexports-tidymodels.R +++ b/R/reexports-tidymodels.R @@ -13,3 +13,7 @@ recipes::prep #' @importFrom recipes bake #' @export recipes::bake + +#' @importFrom recipes prep +#' @export +recipes::recipe diff --git a/R/step_epi_naomit.R b/R/step_epi_naomit.R index 1cbc9c5d9..3a4e46763 100644 --- a/R/step_epi_naomit.R +++ b/R/step_epi_naomit.R @@ -9,7 +9,7 @@ #' @export #' @examples #' case_death_rate_subset %>% -#' epi_recipe() %>% +#' recipe() %>% #' step_epi_naomit() step_epi_naomit <- function(recipe) { stopifnot(inherits(recipe, "recipe")) diff --git a/R/step_epi_shift.R b/R/step_epi_shift.R index 52f51de16..3adc82921 100644 --- a/R/step_epi_shift.R +++ b/R/step_epi_shift.R @@ -46,7 +46,7 @@ #' @rdname step_epi_shift #' @export #' @examples -#' r <- epi_recipe(case_death_rate_subset) %>% +#' r <- recipe(case_death_rate_subset) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) #' r diff --git a/R/step_epi_slide.R b/R/step_epi_slide.R index 637d31a54..09883dbf1 100644 --- a/R/step_epi_slide.R +++ b/R/step_epi_slide.R @@ -35,9 +35,9 @@ #' library(dplyr) #' jhu <- case_death_rate_subset %>% #' filter(time_value >= as.Date("2021-01-01"), geo_value %in% c("ca", "ny")) -#' rec <- epi_recipe(jhu) %>% +#' rec <- recipe(jhu) %>% #' step_epi_slide(case_rate, death_rate, -#' .f = \(x) mean(x, na.rm = TRUE), +#' .f = function(x) mean(x, na.rm = TRUE), #' before = 6L #' ) #' bake(prep(rec, jhu), new_data = NULL) diff --git a/R/step_growth_rate.R b/R/step_growth_rate.R index e5edb18d4..f7ac8af9f 100644 --- a/R/step_growth_rate.R +++ b/R/step_growth_rate.R @@ -34,7 +34,7 @@ #' @importFrom epiprocess growth_rate #' @export #' @examples -#' r <- epi_recipe(case_death_rate_subset) %>% +#' r <- recipe(case_death_rate_subset) %>% #' step_growth_rate(case_rate, death_rate) #' r #' diff --git a/R/step_lag_difference.R b/R/step_lag_difference.R index e954bd9a0..4938b4231 100644 --- a/R/step_lag_difference.R +++ b/R/step_lag_difference.R @@ -15,7 +15,7 @@ #' @family row operation steps #' @export #' @examples -#' r <- epi_recipe(case_death_rate_subset) %>% +#' r <- recipe(case_death_rate_subset) %>% #' step_lag_difference(case_rate, death_rate, horizon = c(7, 14)) %>% #' step_epi_naomit() #' r diff --git a/R/step_population_scaling.R b/R/step_population_scaling.R index 7f2d44ab9..946f6d859 100644 --- a/R/step_population_scaling.R +++ b/R/step_population_scaling.R @@ -63,15 +63,14 @@ #' @return Scales raw data by the population #' @export #' @examples -#' library(epiprocess) -#' library(epipredict) -#' jhu <- epiprocess::jhu_csse_daily_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ca", "ny")) %>% -#' dplyr::select(geo_value, time_value, cases) +#' library(dplyr) +#' jhu <- jhu_csse_daily_subset %>% +#' filter(time_value > "2021-11-01", geo_value %in% c("ca", "ny")) %>% +#' select(geo_value, time_value, cases) #' #' pop_data <- data.frame(states = c("ca", "ny"), value = c(20000, 30000)) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_population_scaling( #' df = pop_data, #' df_pop_col = "value", @@ -92,7 +91,7 @@ #' df_pop_col = "value" #' ) #' -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% +#' wf <- epi_workflow(r, linear_reg()) %>% #' fit(jhu) %>% #' add_frosting(f) #' diff --git a/R/step_training_window.R b/R/step_training_window.R index 7102d29d8..59427357a 100644 --- a/R/step_training_window.R +++ b/R/step_training_window.R @@ -36,13 +36,14 @@ #' ) %>% #' as_epi_df() #' -#' epi_recipe(y ~ x, data = tib) %>% +#' recipe(y ~ x, data = tib) %>% #' step_training_window(n_recent = 3) %>% #' prep(tib) %>% #' bake(new_data = NULL) #' -#' epi_recipe(y ~ x, data = tib) %>% -#' recipes::step_naomit() %>% +#' library(recipes) +#' recipe(y ~ x, data = tib) %>% +#' step_naomit() %>% #' step_training_window(n_recent = 3) %>% #' prep(tib) %>% #' bake(new_data = NULL) diff --git a/R/tidy.R b/R/tidy.R index 06835eff0..caeb7b720 100644 --- a/R/tidy.R +++ b/R/tidy.R @@ -26,15 +26,16 @@ #' `type` (the method, e.g. "predict", "naomit"), and a character column `id`. #' #' @examples +#' library(dplyr) #' jhu <- case_death_rate_subset %>% -#' dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) +#' filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) #' -#' r <- epi_recipe(jhu) %>% +#' r <- recipe(jhu) %>% #' step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% #' step_epi_ahead(death_rate, ahead = 7) %>% #' step_epi_naomit() #' -#' wf <- epi_workflow(r, parsnip::linear_reg()) %>% fit(jhu) +#' wf <- epi_workflow(r, linear_reg()) %>% fit(jhu) #' latest <- get_test_data(recipe = r, x = jhu) #' f <- frosting() %>% diff --git a/man/Add_model.Rd b/man/Add_model.Rd index 6bf6b6b02..27236cf44 100644 --- a/man/Add_model.Rd +++ b/man/Add_model.Rd @@ -71,13 +71,11 @@ aliases with the lower-case names. However, in the event that properly. } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter( - time_value > "2021-11-01", - geo_value \%in\% c("ak", "ca", "ny") - ) + filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) @@ -88,7 +86,7 @@ wf <- epi_workflow(r) wf <- wf \%>\% Add_model(rf_model) wf -lm_model <- parsnip::linear_reg() +lm_model <- linear_reg() wf <- Update_model(wf, lm_model) wf diff --git a/man/add_epi_recipe.Rd b/man/add_epi_recipe.Rd index 0da2d55b3..3abf675ef 100644 --- a/man/add_epi_recipe.Rd +++ b/man/add_epi_recipe.Rd @@ -45,7 +45,7 @@ jhu <- case_death_rate_subset \%>\% filter(time_value > "2021-08-01") \%>\% arrange(geo_value, time_value) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_lag(case_rate, lag = c(0, 7, 14)) \%>\% @@ -57,7 +57,7 @@ workflow <- epi_workflow() \%>\% workflow -r2 <- epi_recipe(jhu) \%>\% +r2 <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) diff --git a/man/add_frosting.Rd b/man/add_frosting.Rd index 161a540e2..e014084d2 100644 --- a/man/add_frosting.Rd +++ b/man/add_frosting.Rd @@ -26,15 +26,16 @@ update_frosting(x, frosting, ...) Add frosting to a workflow } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) latest <- jhu \%>\% - dplyr::filter(time_value >= max(time_value) - 14) + filter(time_value >= max(time_value) - 14) # Add frosting to a workflow and predict f <- frosting() \%>\% diff --git a/man/adjust_epi_recipe.Rd b/man/adjust_epi_recipe.Rd index 7468c4ce2..d7fc5e72a 100644 --- a/man/adjust_epi_recipe.Rd +++ b/man/adjust_epi_recipe.Rd @@ -57,12 +57,12 @@ library(workflows) jhu <- case_death_rate_subset \%>\% filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) latest <- jhu \%>\% filter(time_value >= max(time_value) - 14) diff --git a/man/adjust_frosting.Rd b/man/adjust_frosting.Rd index 6cdc13b30..fd7a606a2 100644 --- a/man/adjust_frosting.Rd +++ b/man/adjust_frosting.Rd @@ -35,14 +35,15 @@ must be inputted as \code{...}. See the examples below for brief illustrations of the different types of updates. } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) # in the frosting from the workflow f1 <- frosting() \%>\% diff --git a/man/arx_forecaster.Rd b/man/arx_forecaster.Rd index 173fa2bbd..af05c0682 100644 --- a/man/arx_forecaster.Rd +++ b/man/arx_forecaster.Rd @@ -37,7 +37,7 @@ workflow } \description{ This is an autoregressive forecasting model for -\code{\link[epiprocess:epi_df]{epiprocess::epi_df}} data. It does "direct" forecasting, meaning +\link[epiprocess:epi_df]{epiprocess::epi_df} data. It does "direct" forecasting, meaning that it estimates a model for a particular target horizon. } \examples{ diff --git a/man/autoplot-epipred.Rd b/man/autoplot-epipred.Rd index dd6b37dcd..0b5434b95 100644 --- a/man/autoplot-epipred.Rd +++ b/man/autoplot-epipred.Rd @@ -70,10 +70,11 @@ will be shown as well. Unfit workflows will result in an error, (you can simply call \code{autoplot()} on the original \code{epi_df}). } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% filter(time_value >= as.Date("2021-11-01")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_lag(case_rate, lag = c(0, 7, 14)) \%>\% @@ -83,21 +84,21 @@ f <- frosting() \%>\% layer_residual_quantiles( quantile_levels = c(.025, .1, .25, .75, .9, .975) ) \%>\% - layer_threshold(dplyr::starts_with(".pred")) \%>\% + layer_threshold(starts_with(".pred")) \%>\% layer_add_target_date() -wf <- epi_workflow(r, parsnip::linear_reg(), f) \%>\% fit(jhu) +wf <- epi_workflow(r, linear_reg(), f) \%>\% fit(jhu) autoplot(wf) -latest <- jhu \%>\% dplyr::filter(time_value >= max(time_value) - 14) +latest <- jhu \%>\% filter(time_value >= max(time_value) - 14) preds <- predict(wf, latest) autoplot(wf, preds, .max_facets = 4) # ------- Show multiple horizons p <- lapply(c(7, 14, 21, 28), \(h) { - r <- epi_recipe(jhu) \%>\% + r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = h) \%>\% step_epi_lag(case_rate, lag = c(0, 7, 14)) \%>\% diff --git a/man/cdc_baseline_forecaster.Rd b/man/cdc_baseline_forecaster.Rd index cd3c4ed67..3d451b275 100644 --- a/man/cdc_baseline_forecaster.Rd +++ b/man/cdc_baseline_forecaster.Rd @@ -51,23 +51,23 @@ weekly_deaths <- case_death_rate_subset \%>\% cdc <- cdc_baseline_forecaster(weekly_deaths, "deaths") preds <- pivot_quantiles_wider(cdc$predictions, .pred_distn) -if (require(ggplot2)) { - forecast_date <- unique(preds$forecast_date) - four_states <- c("ca", "pa", "wa", "ny") - preds \%>\% - filter(geo_value \%in\% four_states) \%>\% - ggplot(aes(target_date)) + - geom_ribbon(aes(ymin = `0.1`, ymax = `0.9`), fill = blues9[3]) + - geom_ribbon(aes(ymin = `0.25`, ymax = `0.75`), fill = blues9[6]) + - geom_line(aes(y = .pred), color = "orange") + - geom_line( - data = weekly_deaths \%>\% filter(geo_value \%in\% four_states), - aes(x = time_value, y = deaths) - ) + - scale_x_date(limits = c(forecast_date - 90, forecast_date + 30)) + - labs(x = "Date", y = "Weekly deaths") + - facet_wrap(~geo_value, scales = "free_y") + - theme_bw() + - geom_vline(xintercept = forecast_date) -} +library(ggplot2) +forecast_date <- unique(preds$forecast_date) +four_states <- c("ca", "pa", "wa", "ny") +preds \%>\% + filter(geo_value \%in\% four_states) \%>\% + ggplot(aes(target_date)) + + geom_ribbon(aes(ymin = `0.1`, ymax = `0.9`), fill = blues9[3]) + + geom_ribbon(aes(ymin = `0.25`, ymax = `0.75`), fill = blues9[6]) + + geom_line(aes(y = .pred), color = "orange") + + geom_line( + data = weekly_deaths \%>\% filter(geo_value \%in\% four_states), + aes(x = time_value, y = deaths) + ) + + scale_x_date(limits = c(forecast_date - 90, forecast_date + 30)) + + labs(x = "Date", y = "Weekly deaths") + + facet_wrap(~geo_value, scales = "free_y") + + theme_bw() + + geom_vline(xintercept = forecast_date) + } diff --git a/man/epi_workflow.Rd b/man/epi_workflow.Rd index b29078d52..0b9fba73e 100644 --- a/man/epi_workflow.Rd +++ b/man/epi_workflow.Rd @@ -35,7 +35,7 @@ and numerous examples, see there. \examples{ jhu <- case_death_rate_subset -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_lag(case_rate, lag = c(0, 7, 14)) \%>\% diff --git a/man/fit-epi_workflow.Rd b/man/fit-epi_workflow.Rd index 3dfa0029a..623706d42 100644 --- a/man/fit-epi_workflow.Rd +++ b/man/fit-epi_workflow.Rd @@ -31,7 +31,7 @@ preprocessing the data and fitting the underlying parsnip model. jhu <- case_death_rate_subset \%>\% filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) diff --git a/man/frosting.Rd b/man/frosting.Rd index 367d132ec..9ce060f30 100644 --- a/man/frosting.Rd +++ b/man/frosting.Rd @@ -28,15 +28,16 @@ f <- frosting() wf <- epi_workflow() \%>\% add_frosting(f) # A more realistic example +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) + filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) f <- frosting() \%>\% layer_predict() \%>\% diff --git a/man/get_test_data.Rd b/man/get_test_data.Rd index b18685d89..5e7874276 100644 --- a/man/get_test_data.Rd +++ b/man/get_test_data.Rd @@ -56,7 +56,7 @@ values with more advanced techniques. } \examples{ # create recipe -rec <- epi_recipe(case_death_rate_subset) \%>\% +rec <- recipe(case_death_rate_subset) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_lag(case_rate, lag = c(0, 7, 14)) diff --git a/man/layer_add_forecast_date.Rd b/man/layer_add_forecast_date.Rd index 4e173d662..be48d75f9 100644 --- a/man/layer_add_forecast_date.Rd +++ b/man/layer_add_forecast_date.Rd @@ -36,15 +36,16 @@ less than the maximum \code{as_of} value (from the data used pre-processing, model fitting, and postprocessing), an appropriate warning will be thrown. } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% + filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) latest <- jhu \%>\% - dplyr::filter(time_value >= max(time_value) - 14) + filter(time_value >= max(time_value) - 14) # Don't specify `forecast_date` (by default, this should be last date in latest) f <- frosting() \%>\% diff --git a/man/layer_add_target_date.Rd b/man/layer_add_target_date.Rd index 5b32002d1..ecb8c590e 100644 --- a/man/layer_add_target_date.Rd +++ b/man/layer_add_target_date.Rd @@ -37,14 +37,15 @@ has been specified in a preprocessing step (most likely in in the test data to get the target date. } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% + filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) # Use ahead + forecast date f <- frosting() \%>\% diff --git a/man/layer_cdc_flatline_quantiles.Rd b/man/layer_cdc_flatline_quantiles.Rd index 5653f9691..346bce1a1 100644 --- a/man/layer_cdc_flatline_quantiles.Rd +++ b/man/layer_cdc_flatline_quantiles.Rd @@ -84,12 +84,13 @@ the future. This version continues to use the same set of residuals, and adds them on to produce wider intervals as \code{ahead} increases. } \examples{ -r <- epi_recipe(case_death_rate_subset) \%>\% +library(recipes) +r <- recipe(case_death_rate_subset) \%>\% # data is "daily", so we fit this to 1 ahead, the result will contain # 1 day ahead residuals step_epi_ahead(death_rate, ahead = 1L, skip = TRUE) \%>\% - recipes::update_role(death_rate, new_role = "predictor") \%>\% - recipes::add_role(time_value, geo_value, new_role = "predictor") + update_role(death_rate, new_role = "predictor") \%>\% + add_role(time_value, geo_value, new_role = "predictor") forecast_date <- max(case_death_rate_subset$time_value) @@ -97,12 +98,12 @@ f <- frosting() \%>\% layer_predict() \%>\% layer_cdc_flatline_quantiles(aheads = c(7, 14, 21, 28), symmetrize = TRUE) -eng <- parsnip::linear_reg() \%>\% parsnip::set_engine("flatline") +eng <- linear_reg() \%>\% set_engine("flatline") wf <- epi_workflow(r, eng, f) \%>\% fit(case_death_rate_subset) preds <- forecast(wf) \%>\% - dplyr::select(-time_value) \%>\% - dplyr::mutate(forecast_date = forecast_date) + select(-time_value) \%>\% + mutate(forecast_date = forecast_date) preds preds <- preds \%>\% @@ -110,22 +111,21 @@ preds <- preds \%>\% pivot_quantiles_wider(.pred_distn) \%>\% mutate(target_date = forecast_date + ahead) -if (require("ggplot2")) { - four_states <- c("ca", "pa", "wa", "ny") - preds \%>\% - filter(geo_value \%in\% four_states) \%>\% - ggplot(aes(target_date)) + - geom_ribbon(aes(ymin = `0.1`, ymax = `0.9`), fill = blues9[3]) + - geom_ribbon(aes(ymin = `0.25`, ymax = `0.75`), fill = blues9[6]) + - geom_line(aes(y = .pred), color = "orange") + - geom_line( - data = case_death_rate_subset \%>\% filter(geo_value \%in\% four_states), - aes(x = time_value, y = death_rate) - ) + - scale_x_date(limits = c(forecast_date - 90, forecast_date + 30)) + - labs(x = "Date", y = "Death rate") + - facet_wrap(~geo_value, scales = "free_y") + - theme_bw() + - geom_vline(xintercept = forecast_date) -} +library(ggplot2) +four_states <- c("ca", "pa", "wa", "ny") +preds \%>\% + filter(geo_value \%in\% four_states) \%>\% + ggplot(aes(target_date)) + + geom_ribbon(aes(ymin = `0.1`, ymax = `0.9`), fill = blues9[3]) + + geom_ribbon(aes(ymin = `0.25`, ymax = `0.75`), fill = blues9[6]) + + geom_line(aes(y = .pred), color = "orange") + + geom_line( + data = case_death_rate_subset \%>\% filter(geo_value \%in\% four_states), + aes(x = time_value, y = death_rate) + ) + + scale_x_date(limits = c(forecast_date - 90, forecast_date + 30)) + + labs(x = "Date", y = "Death rate") + + facet_wrap(~geo_value, scales = "free_y") + + theme_bw() + + geom_vline(xintercept = forecast_date) } diff --git a/man/layer_naomit.Rd b/man/layer_naomit.Rd index e3325fe7c..e9e02863b 100644 --- a/man/layer_naomit.Rd +++ b/man/layer_naomit.Rd @@ -24,10 +24,11 @@ an updated \code{frosting} postprocessor Omit \code{NA}s from predictions or other columns } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) + filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) diff --git a/man/layer_point_from_distn.Rd b/man/layer_point_from_distn.Rd index 58d8add8b..54d275828 100644 --- a/man/layer_point_from_distn.Rd +++ b/man/layer_point_from_distn.Rd @@ -34,15 +34,17 @@ information, so one should usually call this AFTER \code{layer_quantile_distn()} or set the \code{name} argument to something specific. } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) + filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() -wf <- epi_workflow(r, quantile_reg(quantile_levels = c(.25, .5, .75))) \%>\% fit(jhu) +wf <- epi_workflow(r, quantile_reg(quantile_levels = c(.25, .5, .75))) \%>\% + fit(jhu) f1 <- frosting() \%>\% layer_predict() \%>\% diff --git a/man/layer_population_scaling.Rd b/man/layer_population_scaling.Rd index cf8dfcc1a..88607139f 100644 --- a/man/layer_population_scaling.Rd +++ b/man/layer_population_scaling.Rd @@ -74,13 +74,14 @@ passed will \emph{multiply} the selected variables while the \code{rate_rescalin argument is a common \emph{divisor} of the selected variables. } \examples{ -jhu <- epiprocess::jhu_csse_daily_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ca", "ny")) \%>\% - dplyr::select(geo_value, time_value, cases) +library(dplyr) +jhu <- jhu_csse_daily_subset \%>\% + filter(time_value > "2021-11-01", geo_value \%in\% c("ca", "ny")) \%>\% + select(geo_value, time_value, cases) pop_data <- data.frame(states = c("ca", "ny"), value = c(20000, 30000)) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_population_scaling( df = pop_data, df_pop_col = "value", @@ -101,7 +102,7 @@ f <- frosting() \%>\% df_pop_col = "value" ) -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) \%>\% add_frosting(f) diff --git a/man/layer_predict.Rd b/man/layer_predict.Rd index 03473053f..900e4a7e1 100644 --- a/man/layer_predict.Rd +++ b/man/layer_predict.Rd @@ -61,12 +61,12 @@ postprocessor. jhu <- case_death_rate_subset \%>\% filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) latest <- jhu \%>\% filter(time_value >= max(time_value) - 14) # Predict layer alone diff --git a/man/layer_predictive_distn.Rd b/man/layer_predictive_distn.Rd index 7cd4e4efc..38ca505e2 100644 --- a/man/layer_predictive_distn.Rd +++ b/man/layer_predictive_distn.Rd @@ -39,15 +39,16 @@ should be reasonably accurate for models fit using \code{lm} when the new point \verb{x*} isn't too far from the bulk of the data. } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) + filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) f <- frosting() \%>\% layer_predict() \%>\% diff --git a/man/layer_quantile_distn.Rd b/man/layer_quantile_distn.Rd index 695a1d12d..fca435a03 100644 --- a/man/layer_quantile_distn.Rd +++ b/man/layer_quantile_distn.Rd @@ -37,10 +37,11 @@ If this engine is used, then this layer will grab out estimated (or extrapolated quantiles at the requested quantile values. } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) + filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() diff --git a/man/layer_residual_quantiles.Rd b/man/layer_residual_quantiles.Rd index dd576aa5e..16f69ac86 100644 --- a/man/layer_residual_quantiles.Rd +++ b/man/layer_residual_quantiles.Rd @@ -39,15 +39,16 @@ residual quantiles added to the prediction Creates predictions based on residual quantiles } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) + filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) f <- frosting() \%>\% layer_predict() \%>\% diff --git a/man/layer_threshold.Rd b/man/layer_threshold.Rd index dbd7e6669..615c9f15b 100644 --- a/man/layer_threshold.Rd +++ b/man/layer_threshold.Rd @@ -40,14 +40,14 @@ smaller than the lower threshold or higher than the upper threshold equal to the threshold values. } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value < "2021-03-08", - geo_value \%in\% c("ak", "ca", "ar")) -r <- epi_recipe(jhu) \%>\% + filter(time_value < "2021-03-08", geo_value \%in\% c("ak", "ca", "ar")) +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) f <- frosting() \%>\% layer_predict() \%>\% diff --git a/man/predict-epi_workflow.Rd b/man/predict-epi_workflow.Rd index 130279249..531c9216e 100644 --- a/man/predict-epi_workflow.Rd +++ b/man/predict-epi_workflow.Rd @@ -66,16 +66,17 @@ possible. Specifically, the output will have \code{time_value} and } } \examples{ +library(dplyr) jhu <- case_death_rate_subset -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_lag(case_rate, lag = c(0, 7, 14)) \%>\% step_epi_naomit() -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) -latest <- jhu \%>\% dplyr::filter(time_value >= max(time_value) - 14) +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) +latest <- jhu \%>\% filter(time_value >= max(time_value) - 14) preds <- predict(wf, latest) preds diff --git a/man/recipe.epi_df.Rd b/man/recipe.epi_df.Rd index d7aa7aa90..bb96f33c8 100644 --- a/man/recipe.epi_df.Rd +++ b/man/recipe.epi_df.Rd @@ -5,9 +5,12 @@ \alias{epi_recipe} \alias{epi_recipe.default} \alias{epi_recipe.formula} +\alias{recipe.formula} \title{Create a recipe for preprocessing panel data} \usage{ \method{recipe}{epi_df}(x, formula = NULL, ..., vars = NULL, roles = NULL) + +\method{recipe}{formula}(formula, data, ...) } \arguments{ \item{x, data}{A data frame, tibble, or epi_df of the \emph{template} data set @@ -52,17 +55,19 @@ columns present in an \code{\link[epiprocess:epi_df]{epiprocess::epi_df}}: \code additional keys. } \examples{ +library(dplyr) +library(recipes) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value > "2021-08-01") \%>\% - dplyr::arrange(geo_value, time_value) + filter(time_value > "2021-08-01") \%>\% + arrange(geo_value, time_value) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_lag(case_rate, lag = c(0, 7, 14)) \%>\% - recipes::step_naomit(recipes::all_predictors()) \%>\% + step_naomit(recipes::all_predictors()) \%>\% # below, `skip` means we don't do this at predict time - recipes::step_naomit(recipes::all_outcomes(), skip = TRUE) + step_naomit(recipes::all_outcomes(), skip = TRUE) r } diff --git a/man/reexports.Rd b/man/reexports.Rd index 1ac328b2c..9136a04ce 100644 --- a/man/reexports.Rd +++ b/man/reexports.Rd @@ -8,6 +8,7 @@ \alias{forecast} \alias{prep} \alias{bake} +\alias{recipe} \title{Objects exported from other packages} \keyword{internal} \description{ @@ -19,6 +20,6 @@ below to see their documentation. \item{ggplot2}{\code{\link[ggplot2]{autoplot}}} - \item{recipes}{\code{\link[recipes]{bake}}, \code{\link[recipes]{prep}}} + \item{recipes}{\code{\link[recipes]{bake}}, \code{\link[recipes]{prep}}, \code{\link[recipes]{recipe}}} }} diff --git a/man/smooth_quantile_reg.Rd b/man/smooth_quantile_reg.Rd index bd8c012f2..1564107f2 100644 --- a/man/smooth_quantile_reg.Rd +++ b/man/smooth_quantile_reg.Rd @@ -75,17 +75,16 @@ lines(pl$x, pl$`0.2`, col = "blue") lines(pl$x, pl$`0.8`, col = "blue") lines(pl$x, pl$`0.5`, col = "red") -if (require("ggplot2")) { - ggplot(data.frame(x = x, y = y), aes(x)) + - geom_ribbon(data = pl, aes(ymin = `0.2`, ymax = `0.8`), fill = "lightblue") + - geom_point(aes(y = y), colour = "grey") + # observed data - geom_function(fun = sin, colour = "black") + # truth - geom_vline(xintercept = fd, linetype = "dashed") + # end of training data - geom_line(data = pl, aes(y = `0.5`), colour = "red") + # median prediction - theme_bw() + - coord_cartesian(xlim = c(0, NA)) + - ylab("y") -} +library(ggplot2) +ggplot(data.frame(x = x, y = y), aes(x)) + + geom_ribbon(data = pl, aes(ymin = `0.2`, ymax = `0.8`), fill = "lightblue") + + geom_point(aes(y = y), colour = "grey") + # observed data + geom_function(fun = sin, colour = "black") + # truth + geom_vline(xintercept = fd, linetype = "dashed") + # end of training data + geom_line(data = pl, aes(y = `0.5`), colour = "red") + # median prediction + theme_bw() + + coord_cartesian(xlim = c(0, NA)) + + ylab("y") } \seealso{ \code{\link[=fit.model_spec]{fit.model_spec()}}, \code{\link[=set_engine]{set_engine()}} diff --git a/man/step_epi_naomit.Rd b/man/step_epi_naomit.Rd index b579dd6d6..a16657c74 100644 --- a/man/step_epi_naomit.Rd +++ b/man/step_epi_naomit.Rd @@ -20,6 +20,6 @@ Unified NA omission wrapper function for recipes } \examples{ case_death_rate_subset \%>\% - epi_recipe() \%>\% + recipe() \%>\% step_epi_naomit() } diff --git a/man/step_epi_shift.Rd b/man/step_epi_shift.Rd index f4419b831..57b39a16e 100644 --- a/man/step_epi_shift.Rd +++ b/man/step_epi_shift.Rd @@ -88,7 +88,7 @@ are always set to \code{"ahead_"} and \code{"epi_ahead"} respectively, while for \code{step_epi_lag}, they are set to \code{"lag_"} and \verb{"epi_lag}, respectively. } \examples{ -r <- epi_recipe(case_death_rate_subset) \%>\% +r <- recipe(case_death_rate_subset) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) r diff --git a/man/step_epi_slide.Rd b/man/step_epi_slide.Rd index 46bb386ad..141f279d9 100644 --- a/man/step_epi_slide.Rd +++ b/man/step_epi_slide.Rd @@ -77,9 +77,9 @@ a computation along existing data. library(dplyr) jhu <- case_death_rate_subset \%>\% filter(time_value >= as.Date("2021-01-01"), geo_value \%in\% c("ca", "ny")) -rec <- epi_recipe(jhu) \%>\% +rec <- recipe(jhu) \%>\% step_epi_slide(case_rate, death_rate, - .f = \(x) mean(x, na.rm = TRUE), + .f = function(x) mean(x, na.rm = TRUE), before = 6L ) bake(prep(rec, jhu), new_data = NULL) diff --git a/man/step_growth_rate.Rd b/man/step_growth_rate.Rd index 46d8b92f6..d58b5451c 100644 --- a/man/step_growth_rate.Rd +++ b/man/step_growth_rate.Rd @@ -83,7 +83,7 @@ sequence of any existing operations. that will generate one or more new columns of derived data. } \examples{ -r <- epi_recipe(case_death_rate_subset) \%>\% +r <- recipe(case_death_rate_subset) \%>\% step_growth_rate(case_rate, death_rate) r diff --git a/man/step_lag_difference.Rd b/man/step_lag_difference.Rd index 123265ea6..0054dfa3e 100644 --- a/man/step_lag_difference.Rd +++ b/man/step_lag_difference.Rd @@ -55,7 +55,7 @@ sequence of any existing operations. that will generate one or more new columns of derived data. } \examples{ -r <- epi_recipe(case_death_rate_subset) \%>\% +r <- recipe(case_death_rate_subset) \%>\% step_lag_difference(case_rate, death_rate, horizon = c(7, 14)) \%>\% step_epi_naomit() r diff --git a/man/step_population_scaling.Rd b/man/step_population_scaling.Rd index 2af3c245b..4799a0e55 100644 --- a/man/step_population_scaling.Rd +++ b/man/step_population_scaling.Rd @@ -98,15 +98,14 @@ passed will \emph{divide} the selected variables while the \code{rate_rescaling} argument is a common \emph{multiplier} of the selected variables. } \examples{ -library(epiprocess) -library(epipredict) -jhu <- epiprocess::jhu_csse_daily_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ca", "ny")) \%>\% - dplyr::select(geo_value, time_value, cases) +library(dplyr) +jhu <- jhu_csse_daily_subset \%>\% + filter(time_value > "2021-11-01", geo_value \%in\% c("ca", "ny")) \%>\% + select(geo_value, time_value, cases) pop_data <- data.frame(states = c("ca", "ny"), value = c(20000, 30000)) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_population_scaling( df = pop_data, df_pop_col = "value", @@ -127,7 +126,7 @@ f <- frosting() \%>\% df_pop_col = "value" ) -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) \%>\% add_frosting(f) diff --git a/man/step_training_window.Rd b/man/step_training_window.Rd index ce7c0fc74..5a9ce90e1 100644 --- a/man/step_training_window.Rd +++ b/man/step_training_window.Rd @@ -58,13 +58,14 @@ tib <- tibble::tibble( ) \%>\% as_epi_df() -epi_recipe(y ~ x, data = tib) \%>\% +recipe(y ~ x, data = tib) \%>\% step_training_window(n_recent = 3) \%>\% prep(tib) \%>\% bake(new_data = NULL) -epi_recipe(y ~ x, data = tib) \%>\% - recipes::step_naomit() \%>\% +library(recipes) +recipe(y ~ x, data = tib) \%>\% + step_naomit() \%>\% step_training_window(n_recent = 3) \%>\% prep(tib) \%>\% bake(new_data = NULL) diff --git a/man/tidy.frosting.Rd b/man/tidy.frosting.Rd index 6b28461b4..7509aae13 100644 --- a/man/tidy.frosting.Rd +++ b/man/tidy.frosting.Rd @@ -37,15 +37,16 @@ method for the operation exists). Note that this is a modified version of the \code{tidy} method for a recipe. } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) + filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() -wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) +wf <- epi_workflow(r, linear_reg()) \%>\% fit(jhu) latest <- get_test_data(recipe = r, x = jhu) f <- frosting() \%>\% layer_predict() \%>\% diff --git a/man/update.layer.Rd b/man/update.layer.Rd index 0f1fe9c22..005d80c84 100644 --- a/man/update.layer.Rd +++ b/man/update.layer.Rd @@ -18,15 +18,16 @@ will replace the elements of the same name in the actual post-processing layer. Analogous to \code{update.step()} from the \code{recipes} package. } \examples{ +library(dplyr) jhu <- case_death_rate_subset \%>\% - dplyr::filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) \%>\% + filter(time_value > "2021-11-01", geo_value \%in\% c("ak", "ca", "ny")) +r <- recipe(jhu) \%>\% step_epi_lag(death_rate, lag = c(0, 7, 14)) \%>\% step_epi_ahead(death_rate, ahead = 7) \%>\% step_epi_naomit() wf <- epi_workflow(r, parsnip::linear_reg()) \%>\% fit(jhu) latest <- jhu \%>\% - dplyr::filter(time_value >= max(time_value) - 14) + filter(time_value >= max(time_value) - 14) # Specify a `forecast_date` that is greater than or equal to `as_of` date f <- frosting() \%>\% diff --git a/tests/testthat/test-bake-method.R b/tests/testthat/test-bake-method.R index 0e2746cf2..e1dd232e6 100644 --- a/tests/testthat/test-bake-method.R +++ b/tests/testthat/test-bake-method.R @@ -1,11 +1,11 @@ test_that("bake method works in all cases", { edf <- case_death_rate_subset %>% filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) - r <- epi_recipe(edf) %>% + r <- recipe(edf) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) - r2 <- epi_recipe(edf) %>% + r2 <- recipe(edf) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_naomit() diff --git a/tests/testthat/test-check_enough_train_data.R b/tests/testthat/test-check_enough_train_data.R index 502ea06f1..f5b3173f2 100644 --- a/tests/testthat/test-check_enough_train_data.R +++ b/tests/testthat/test-check_enough_train_data.R @@ -17,14 +17,14 @@ toy_epi_df <- tibble::tibble( test_that("check_enough_train_data works on pooled data", { # Check both columns have enough data expect_no_error( - epi_recipe(toy_epi_df) %>% + recipe(toy_epi_df) %>% check_enough_train_data(x, y, n = 2 * n, drop_na = FALSE) %>% prep(toy_epi_df) %>% bake(new_data = NULL) ) # Check both column don't have enough data expect_error( - epi_recipe(toy_epi_df) %>% + recipe(toy_epi_df) %>% check_enough_train_data(x, y, n = 2 * n + 1, drop_na = FALSE) %>% prep(toy_epi_df) %>% bake(new_data = NULL), @@ -32,7 +32,7 @@ test_that("check_enough_train_data works on pooled data", { ) # Check drop_na works expect_error( - epi_recipe(toy_epi_df) %>% + recipe(toy_epi_df) %>% check_enough_train_data(x, y, n = 2 * n - 1, drop_na = TRUE) %>% prep(toy_epi_df) %>% bake(new_data = NULL) @@ -42,14 +42,14 @@ test_that("check_enough_train_data works on pooled data", { test_that("check_enough_train_data works on unpooled data", { # Check both columns have enough data expect_no_error( - epi_recipe(toy_epi_df) %>% + recipe(toy_epi_df) %>% check_enough_train_data(x, y, n = n, epi_keys = "geo_value", drop_na = FALSE) %>% prep(toy_epi_df) %>% bake(new_data = NULL) ) # Check one column don't have enough data expect_error( - epi_recipe(toy_epi_df) %>% + recipe(toy_epi_df) %>% check_enough_train_data(x, y, n = n + 1, epi_keys = "geo_value", drop_na = FALSE) %>% prep(toy_epi_df) %>% bake(new_data = NULL), @@ -57,7 +57,7 @@ test_that("check_enough_train_data works on unpooled data", { ) # Check drop_na works expect_error( - epi_recipe(toy_epi_df) %>% + recipe(toy_epi_df) %>% check_enough_train_data(x, y, n = 2 * n - 3, epi_keys = "geo_value", drop_na = TRUE) %>% prep(toy_epi_df) %>% bake(new_data = NULL) @@ -66,7 +66,7 @@ test_that("check_enough_train_data works on unpooled data", { test_that("check_enough_train_data outputs the correct recipe values", { expect_no_error( - p <- epi_recipe(toy_epi_df) %>% + p <- recipe(toy_epi_df) %>% check_enough_train_data(x, y, n = 2 * n - 2) %>% prep(toy_epi_df) %>% bake(new_data = NULL) @@ -91,14 +91,14 @@ test_that("check_enough_train_data only checks train data", { slice(3:10) %>% epiprocess::as_epi_df() expect_no_error( - epi_recipe(toy_epi_df) %>% + recipe(toy_epi_df) %>% check_enough_train_data(x, y, n = n - 2, epi_keys = "geo_value") %>% prep(toy_epi_df) %>% bake(new_data = toy_test_data) ) # Same thing, but skip = FALSE expect_no_error( - epi_recipe(toy_epi_df) %>% + recipe(toy_epi_df) %>% check_enough_train_data(y, n = n - 2, epi_keys = "geo_value", skip = FALSE) %>% prep(toy_epi_df) %>% bake(new_data = toy_test_data) @@ -108,14 +108,14 @@ test_that("check_enough_train_data only checks train data", { test_that("check_enough_train_data works with all_predictors() downstream of constructed terms", { # With a lag of 2, we will get 2 * n - 6 non-NA rows expect_no_error( - epi_recipe(toy_epi_df) %>% + recipe(toy_epi_df) %>% step_epi_lag(x, lag = c(1, 2)) %>% check_enough_train_data(all_predictors(), y, n = 2 * n - 6) %>% prep(toy_epi_df) %>% bake(new_data = NULL) ) expect_error( - epi_recipe(toy_epi_df) %>% + recipe(toy_epi_df) %>% step_epi_lag(x, lag = c(1, 2)) %>% check_enough_train_data(all_predictors(), y, n = 2 * n - 5) %>% prep(toy_epi_df) %>% diff --git a/tests/testthat/test-epi_keys.R b/tests/testthat/test-epi_keys.R index a3c2fddc1..be9791873 100644 --- a/tests/testthat/test-epi_keys.R +++ b/tests/testthat/test-epi_keys.R @@ -24,7 +24,7 @@ test_that("Extracts keys from a recipe", { }) test_that("epi_keys_mold extracts time_value and geo_value, but not raw", { - my_recipe <- epi_recipe(case_death_rate_subset) %>% + my_recipe <- recipe(case_death_rate_subset) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% @@ -55,7 +55,7 @@ test_that("epi_keys_mold extracts additional keys when they are present", { additional_metadata = list(other_keys = c("state", "pol")) ) - my_recipe <- epi_recipe(my_data) %>% + my_recipe <- recipe(my_data) %>% step_epi_ahead(value, ahead = 7) %>% step_epi_naomit() diff --git a/tests/testthat/test-epi_recipe.R b/tests/testthat/test-epi_recipe.R index 8031b3176..df04f6521 100644 --- a/tests/testthat/test-epi_recipe.R +++ b/tests/testthat/test-epi_recipe.R @@ -13,28 +13,9 @@ test_that("recipe produces default recipe", { expect_identical(rec, epi_recipe(y ~ x, tib)) expect_equal(nrow(rec$template), 5L) - m <- as.matrix(tib) - rec <- recipe(m) - expect_identical(rec, epi_recipe(m)) - expect_equal(nrow(rec$template), 5L) - expected_rec <- recipes::recipe(tib) - expected_rec$template <- expected_rec$template[1, ] - expect_warning(rec <- epi_recipe(tib), regexp = "epi_recipe has been called with a non-epi_df object") - expect_identical(expected_rec, rec) - expect_equal(nrow(rec$template), 1L) expected_rec <- recipes::recipe(y ~ x, tib) - expected_rec$template <- expected_rec$template[1, ] - expect_warning(rec <- epi_recipe(y ~ x, tib), regexp = "epi_recipe has been called with a non-epi_df object") - expect_identical(expected_rec, rec) - expect_equal(nrow(rec$template), 1L) - - m <- as.matrix(tib) - expected_rec <- recipes::recipe(m) - expected_rec$template <- expected_rec$template[1, ] - expect_warning(rec <- epi_recipe(m), regexp = "epi_recipe has been called with a non-epi_df object") expect_identical(expected_rec, rec) - expect_equal(nrow(rec$template), 1L) }) test_that("recipe formula works", { diff --git a/tests/testthat/test-epi_workflow.R b/tests/testthat/test-epi_workflow.R index 09dd6fe82..94799faa1 100644 --- a/tests/testthat/test-epi_workflow.R +++ b/tests/testthat/test-epi_workflow.R @@ -1,5 +1,5 @@ test_that("postprocesser was evaluated", { - r <- epi_recipe(case_death_rate_subset) + r <- recipe(case_death_rate_subset) s <- parsnip::linear_reg() f <- frosting() @@ -14,7 +14,7 @@ test_that("postprocesser was evaluated", { test_that("outcome of the two methods are the same", { jhu <- case_death_rate_subset - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_lag(case_rate, lag = c(7)) %>% @@ -36,7 +36,7 @@ test_that("model can be added/updated/removed from epi_workflow", { jhu <- case_death_rate_subset %>% dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) @@ -66,7 +66,7 @@ test_that("model can be added/updated/removed from epi_workflow", { test_that("forecast method works", { jhu <- case_death_rate_subset %>% filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_naomit() @@ -97,7 +97,7 @@ test_that("forecast method works", { test_that("forecast method errors when workflow not fit", { jhu <- case_death_rate_subset %>% filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_naomit() diff --git a/tests/testthat/test-extract_argument.R b/tests/testthat/test-extract_argument.R index 3250b2991..bbccaad78 100644 --- a/tests/testthat/test-extract_argument.R +++ b/tests/testthat/test-extract_argument.R @@ -32,7 +32,7 @@ test_that("recipe argument extractor works", { dplyr::filter(time_value > "2021-08-01") %>% dplyr::arrange(geo_value, time_value) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% diff --git a/tests/testthat/test-frosting.R b/tests/testthat/test-frosting.R index 5cab9c494..9c00e210d 100644 --- a/tests/testthat/test-frosting.R +++ b/tests/testthat/test-frosting.R @@ -42,7 +42,7 @@ test_that("frosting can be created/added/updated/adjusted/removed", { test_that("prediction works without any postprocessor", { jhu <- case_death_rate_subset %>% dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_naomit(all_predictors()) %>% @@ -65,7 +65,7 @@ test_that("layer_predict is added by default if missing", { jhu <- case_death_rate_subset %>% dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_naomit() @@ -92,7 +92,7 @@ test_that("parsnip settings can be passed through predict.epi_workflow", { jhu <- case_death_rate_subset %>% dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_naomit() diff --git a/tests/testthat/test-get_test_data.R b/tests/testthat/test-get_test_data.R index 035fc6463..c0f32bc42 100644 --- a/tests/testthat/test-get_test_data.R +++ b/tests/testthat/test-get_test_data.R @@ -1,6 +1,6 @@ library(dplyr) test_that("return expected number of rows and returned dataset is ungrouped", { - r <- epi_recipe(case_death_rate_subset) %>% + r <- recipe(case_death_rate_subset) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_lag(death_rate, lag = c(0, 7, 14, 21, 28)) %>% step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% @@ -19,7 +19,7 @@ test_that("return expected number of rows and returned dataset is ungrouped", { test_that("expect insufficient training data error", { - r <- epi_recipe(case_death_rate_subset) %>% + r <- recipe(case_death_rate_subset) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_lag(death_rate, lag = c(0, 367)) %>% step_naomit(all_predictors()) %>% @@ -30,7 +30,7 @@ test_that("expect insufficient training data error", { test_that("expect error that geo_value or time_value does not exist", { - r <- epi_recipe(case_death_rate_subset) %>% + r <- recipe(case_death_rate_subset) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% @@ -52,7 +52,7 @@ test_that("NA fill behaves as desired", { ) %>% epiprocess::as_epi_df() - r <- epi_recipe(df) %>% + r <- recipe(df) %>% step_epi_ahead(x1, ahead = 3) %>% step_epi_lag(x1, x2, lag = c(1, 3)) %>% step_epi_naomit() @@ -89,7 +89,7 @@ test_that("forecast date behaves", { ) %>% epiprocess::as_epi_df() - r <- epi_recipe(df) %>% + r <- recipe(df) %>% step_epi_ahead(x1, ahead = 3) %>% step_epi_lag(x1, x2, lag = c(1, 3)) @@ -118,7 +118,7 @@ test_that("Omit end rows according to minimum lag when that’s not lag 0", { x = 1:10 ) %>% epiprocess::as_epi_df() - toy_rec <- epi_recipe(toy_epi_df) %>% + toy_rec <- recipe(toy_epi_df) %>% step_epi_lag(x, lag = c(2, 4)) %>% step_epi_ahead(x, ahead = 3) %>% step_epi_naomit() @@ -140,7 +140,7 @@ test_that("Omit end rows according to minimum lag when that’s not lag 0", { ca <- case_death_rate_subset %>% filter(geo_value == "ca") - rec <- epi_recipe(ca) %>% + rec <- recipe(ca) %>% step_epi_lag(case_rate, lag = c(2, 4, 6)) %>% step_epi_ahead(case_rate, ahead = 7) %>% step_epi_naomit() diff --git a/tests/testthat/test-layer_add_forecast_date.R b/tests/testthat/test-layer_add_forecast_date.R index 9595b47b6..6b81a9cd6 100644 --- a/tests/testthat/test-layer_add_forecast_date.R +++ b/tests/testthat/test-layer_add_forecast_date.R @@ -1,6 +1,6 @@ jhu <- case_death_rate_subset %>% dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) %>% +r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_naomit(all_predictors()) %>% diff --git a/tests/testthat/test-layer_add_target_date.R b/tests/testthat/test-layer_add_target_date.R index e5349839b..3fcae9cad 100644 --- a/tests/testthat/test-layer_add_target_date.R +++ b/tests/testthat/test-layer_add_target_date.R @@ -1,6 +1,6 @@ jhu <- case_death_rate_subset %>% dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) %>% +r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_naomit(all_predictors()) %>% diff --git a/tests/testthat/test-layer_naomit.R b/tests/testthat/test-layer_naomit.R index 1d5b4ee25..1254bfc36 100644 --- a/tests/testthat/test-layer_naomit.R +++ b/tests/testthat/test-layer_naomit.R @@ -1,7 +1,7 @@ jhu <- case_death_rate_subset %>% dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) %>% +r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14, 30)) %>% step_epi_ahead(death_rate, ahead = 7) %>% recipes::step_naomit(all_predictors()) %>% diff --git a/tests/testthat/test-layer_predict.R b/tests/testthat/test-layer_predict.R index 041516b29..32fd6940e 100644 --- a/tests/testthat/test-layer_predict.R +++ b/tests/testthat/test-layer_predict.R @@ -1,6 +1,6 @@ jhu <- case_death_rate_subset %>% dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) %>% +r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_naomit(all_predictors()) %>% diff --git a/tests/testthat/test-layer_residual_quantiles.R b/tests/testthat/test-layer_residual_quantiles.R index e3668b249..c2b9aa198 100644 --- a/tests/testthat/test-layer_residual_quantiles.R +++ b/tests/testthat/test-layer_residual_quantiles.R @@ -1,7 +1,7 @@ jhu <- case_death_rate_subset %>% dplyr::filter(time_value > "2021-11-01", geo_value %in% c("ak", "ca", "ny")) -r <- epi_recipe(jhu) %>% +r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_naomit() @@ -40,7 +40,7 @@ test_that("Errors when used with a classifier", { geo_value = "ak" ) %>% as_epi_df() - r <- epi_recipe(y ~ x1 + x2, data = tib) + r <- recipe(y ~ x1 + x2, data = tib) wf <- epi_workflow(r, parsnip::logistic_reg()) %>% fit(tib) f <- frosting() %>% layer_predict() %>% diff --git a/tests/testthat/test-layer_threshold_preds.R b/tests/testthat/test-layer_threshold_preds.R index 9df7e64ab..f051913f9 100644 --- a/tests/testthat/test-layer_threshold_preds.R +++ b/tests/testthat/test-layer_threshold_preds.R @@ -1,6 +1,6 @@ jhu <- case_death_rate_subset %>% dplyr::filter(time_value < "2021-03-08", geo_value %in% c("ak", "ca", "ar")) -r <- epi_recipe(jhu) %>% +r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_naomit() diff --git a/tests/testthat/test-population_scaling.R b/tests/testthat/test-population_scaling.R index b66bb08c3..615468bd3 100644 --- a/tests/testthat/test-population_scaling.R +++ b/tests/testthat/test-population_scaling.R @@ -7,13 +7,13 @@ test_that("Column names can be passed with and without the tidy way", { newdata <- case_death_rate_subset %>% filter(geo_value %in% c("ak", "al", "ar", "as", "az", "ca")) - r1 <- epi_recipe(newdata) %>% + r1 <- recipe(newdata) %>% step_population_scaling(c("case_rate", "death_rate"), df = pop_data, df_pop_col = "value", by = c("geo_value" = "states") ) - r2 <- epi_recipe(newdata) %>% + r2 <- recipe(newdata) %>% step_population_scaling(case_rate, death_rate, df = pop_data, df_pop_col = "value", by = c("geo_value" = "states") @@ -47,9 +47,9 @@ test_that("Number of columns and column names returned correctly, Upper and lowe case = 1:10, death = 1:10 ) %>% - epiprocess::as_epi_df() + epiprocess::as_epi_df(additional_metadata = list(other_keys = "county")) - r <- epi_recipe(newdata) %>% + r <- recipe(newdata) %>% step_population_scaling(c("case", "death"), df = pop_data, df_pop_col = "value", by = c("geo_value" = "states", "county" = "counties"), @@ -65,7 +65,7 @@ test_that("Number of columns and column names returned correctly, Upper and lowe - r <- epi_recipe(newdata) %>% + r <- recipe(newdata) %>% step_population_scaling( df = pop_data, df_pop_col = "value", @@ -92,7 +92,7 @@ test_that("Postprocessing workflow works and values correct", { value = c(20000, 30000) ) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_population_scaling(cases, df = pop_data, df_pop_col = "value", @@ -152,7 +152,7 @@ test_that("Postprocessing to get cases from case rate", { value = c(1 / 20000, 1 / 30000) ) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_population_scaling( df = reverse_pop_data, df_pop_col = "value", @@ -196,7 +196,7 @@ test_that("test joining by default columns", { values = c(1 / 20000, 1 / 30000) ) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_population_scaling(case_rate, df = reverse_pop_data, df_pop_col = "values", @@ -242,7 +242,7 @@ test_that("expect error if `by` selector does not match", { values = c(1 / 20000, 1 / 30000) ) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_population_scaling(case_rate, df = reverse_pop_data, df_pop_col = "values", @@ -270,7 +270,7 @@ test_that("expect error if `by` selector does not match", { add_frosting(f) ) - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_population_scaling(case_rate, df = reverse_pop_data, df_pop_col = "values", @@ -314,7 +314,7 @@ test_that("Rate rescaling behaves as expected", { value = c(1 / 1000) ) - r <- epi_recipe(x) %>% + r <- recipe(x) %>% step_population_scaling( df = reverse_pop_data, df_pop_col = "value", @@ -343,7 +343,7 @@ test_that("Rate rescaling behaves as expected", { ) %>% as_epi_df() - r <- epi_recipe(x) %>% + r <- recipe(x) %>% step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% # cases step_epi_ahead(case_rate, ahead = 7, role = "outcome") %>% # cases recipes::step_naomit(recipes::all_predictors()) %>% @@ -385,7 +385,7 @@ test_that("Extra Columns are ignored", { value = c(1 / 1000), extra_col = c("full name") ) - recip <- epi_recipe(x) %>% + recip <- recipe(x) %>% step_population_scaling( df = reverse_pop_data, df_pop_col = "value", diff --git a/tests/testthat/test-step_epi_naomit.R b/tests/testthat/test-step_epi_naomit.R index 2fb173f01..7e84f5d75 100644 --- a/tests/testthat/test-step_epi_naomit.R +++ b/tests/testthat/test-step_epi_naomit.R @@ -12,7 +12,7 @@ x <- tibble( epiprocess::as_epi_df() # Preparing the datasets to be used for comparison -r <- epi_recipe(x) %>% +r <- recipe(x) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) diff --git a/tests/testthat/test-step_epi_shift.R b/tests/testthat/test-step_epi_shift.R index da04fd0f2..f6d523417 100644 --- a/tests/testthat/test-step_epi_shift.R +++ b/tests/testthat/test-step_epi_shift.R @@ -21,7 +21,7 @@ slm_fit <- function(recipe, data = x) { test_that("Values for ahead and lag must be integer values", { expect_error( - r1 <- epi_recipe(x) %>% + r1 <- recipe(x) %>% step_epi_ahead(death_rate, ahead = 3.6) %>% step_epi_lag(death_rate, lag = 1.9) ) @@ -29,7 +29,7 @@ test_that("Values for ahead and lag must be integer values", { test_that("A negative lag value should should throw an error", { expect_error( - r2 <- epi_recipe(x) %>% + r2 <- recipe(x) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_lag(death_rate, lag = -7) ) @@ -37,14 +37,14 @@ test_that("A negative lag value should should throw an error", { test_that("A nonpositive ahead value should throw an error", { expect_error( - r3 <- epi_recipe(x) %>% + r3 <- recipe(x) %>% step_epi_ahead(death_rate, ahead = -7) %>% step_epi_lag(death_rate, lag = 7) ) }) test_that("Values for ahead and lag cannot be duplicates", { - r4 <- epi_recipe(x) %>% + r4 <- recipe(x) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_lag(death_rate, lag = 7) %>% step_epi_lag(death_rate, lag = 7) @@ -54,7 +54,7 @@ test_that("Values for ahead and lag cannot be duplicates", { }) test_that("Check that epi_lag shifts applies the shift", { - r5 <- epi_recipe(x) %>% + r5 <- recipe(x) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) diff --git a/tests/testthat/test-step_epi_slide.R b/tests/testthat/test-step_epi_slide.R index 29e046eae..dd42c646c 100644 --- a/tests/testthat/test-step_epi_slide.R +++ b/tests/testthat/test-step_epi_slide.R @@ -8,7 +8,7 @@ edf <- data.frame( ) %>% as_epi_df() -r <- epi_recipe(edf) +r <- recipe(edf) rolled_before <- edf %>% group_by(geo_value) %>% epi_slide(value = mean(value), before = 3L) %>% @@ -21,7 +21,7 @@ rolled_after <- edf %>% test_that("epi_slide errors when needed", { # not an epi_recipe - expect_error(recipe(edf) %>% step_epi_slide(value, .f = mean, before = 6L)) + expect_error(recipe(as_tibble(edf)) %>% step_epi_slide(value, .f = mean, before = 6L)) # non-scalar args expect_error(r %>% step_epi_slide(value, .f = mean, before = c(3L, 6L))) diff --git a/tests/testthat/test-step_growth_rate.R b/tests/testthat/test-step_growth_rate.R index 052141710..aefe14d60 100644 --- a/tests/testthat/test-step_growth_rate.R +++ b/tests/testthat/test-step_growth_rate.R @@ -4,7 +4,7 @@ test_that("step_growth_rate validates arguments", { expect_error(step_growth_rate(r)) edf <- as_epi_df(df) - r <- epi_recipe(edf) + r <- recipe(edf) expect_error(step_growth_rate(r, value, role = 1)) expect_error(step_growth_rate(r, value, method = "abc")) @@ -30,7 +30,7 @@ test_that("step_growth_rate validates arguments", { test_that("step_growth_rate works for a single signal", { df <- data.frame(time_value = 1:5, geo_value = rep("a", 5), value = 6:10) edf <- as_epi_df(df) - r <- epi_recipe(edf) + r <- recipe(edf) res <- r %>% step_growth_rate(value, horizon = 1) %>% @@ -43,7 +43,7 @@ test_that("step_growth_rate works for a single signal", { data.frame(time_value = 1:5, geo_value = rep("b", 5), value = 6:10) ) edf <- as_epi_df(df) - r <- epi_recipe(edf) + r <- recipe(edf) res <- r %>% step_growth_rate(value, horizon = 1) %>% prep(edf) %>% @@ -59,7 +59,7 @@ test_that("step_growth_rate works for a two signals", { v1 = 6:10, v2 = 1:5 ) edf <- as_epi_df(df) - r <- epi_recipe(edf) + r <- recipe(edf) res <- r %>% step_growth_rate(v1, v2, horizon = 1) %>% @@ -73,7 +73,7 @@ test_that("step_growth_rate works for a two signals", { data.frame(time_value = 1:5, geo_value = rep("b", 5), v1 = 6:10, v2 = 1:5) ) edf <- as_epi_df(df) - r <- epi_recipe(edf) + r <- recipe(edf) res <- r %>% step_growth_rate(v1, v2, horizon = 1) %>% prep(edf) %>% diff --git a/tests/testthat/test-step_lag_difference.R b/tests/testthat/test-step_lag_difference.R index c0fd377e6..3285b30cf 100644 --- a/tests/testthat/test-step_lag_difference.R +++ b/tests/testthat/test-step_lag_difference.R @@ -4,7 +4,7 @@ test_that("step_lag_difference validates arguments", { expect_error(step_lag_difference(r)) edf <- as_epi_df(df) - r <- epi_recipe(edf) + r <- recipe(edf) expect_error(step_lag_difference(r, value, role = 1)) expect_error(step_lag_difference(r, value, horizon = 0)) @@ -23,7 +23,7 @@ test_that("step_lag_difference validates arguments", { test_that("step_lag_difference works for a single signal", { df <- data.frame(time_value = 1:5, geo_value = rep("a", 5), value = 6:10) edf <- as_epi_df(df) - r <- epi_recipe(edf) + r <- recipe(edf) res <- r %>% step_lag_difference(value, horizon = 1) %>% @@ -45,7 +45,7 @@ test_that("step_lag_difference works for a single signal", { data.frame(time_value = 1:5, geo_value = rep("b", 5), value = 6:10) ) edf <- as_epi_df(df) - r <- epi_recipe(edf) + r <- recipe(edf) res <- r %>% step_lag_difference(value, horizon = 1) %>% prep(edf) %>% @@ -61,7 +61,7 @@ test_that("step_lag_difference works for a two signals", { v1 = 6:10, v2 = 1:5 * 2 ) edf <- as_epi_df(df) - r <- epi_recipe(edf) + r <- recipe(edf) res <- r %>% step_lag_difference(v1, v2, horizon = 1:2) %>% @@ -77,7 +77,7 @@ test_that("step_lag_difference works for a two signals", { data.frame(time_value = 1:5, geo_value = rep("b", 5), v1 = 6:10, v2 = 1:5) ) edf <- as_epi_df(df) - r <- epi_recipe(edf) + r <- recipe(edf) res <- r %>% step_lag_difference(v1, v2, horizon = 1:2) %>% prep(edf) %>% diff --git a/tests/testthat/test-step_training_window.R b/tests/testthat/test-step_training_window.R index f49668a40..cefdb79ce 100644 --- a/tests/testthat/test-step_training_window.R +++ b/tests/testthat/test-step_training_window.R @@ -9,7 +9,7 @@ toy_epi_df <- tibble::tibble( test_that("step_training_window works with default n_recent", { - p <- epi_recipe(y ~ x, data = toy_epi_df) %>% + p <- recipe(y ~ x, data = toy_epi_df) %>% step_training_window() %>% prep(toy_epi_df) %>% bake(new_data = NULL) @@ -26,7 +26,7 @@ test_that("step_training_window works with default n_recent", { }) test_that("step_training_window works with specified n_recent", { - p2 <- epi_recipe(y ~ x, data = toy_epi_df) %>% + p2 <- recipe(y ~ x, data = toy_epi_df) %>% step_training_window(n_recent = 5) %>% prep(toy_epi_df) %>% bake(new_data = NULL) @@ -46,7 +46,7 @@ test_that("step_training_window does not proceed with specified new_data", { # Should just return whatever the new_data is, unaffected by the step # because step_training_window only effects training data, not # testing data. - p3 <- epi_recipe(y ~ x, data = toy_epi_df) %>% + p3 <- recipe(y ~ x, data = toy_epi_df) %>% step_training_window(n_recent = 3) %>% prep(toy_epi_df) %>% bake(new_data = toy_epi_df[1:10, ]) @@ -72,11 +72,10 @@ test_that("step_training_window works with multiple keys", { ), times = 2), geo_value = rep(c("ca", "hi"), each = 100), additional_key = as.factor(rep(1:4, each = 50)), - ) %>% epiprocess::as_epi_df() - - attributes(toy_epi_df2)$metadata$other_keys <- "additional_key" + ) %>% + epiprocess::as_epi_df(additional_metadata = list(other_keys = "additional_key")) - p4 <- epi_recipe(y ~ x, data = toy_epi_df2) %>% + p4 <- recipe(y ~ x, data = toy_epi_df2) %>% step_training_window(n_recent = 3) %>% prep(toy_epi_df2) %>% bake(new_data = NULL) @@ -84,7 +83,7 @@ test_that("step_training_window works with multiple keys", { expect_equal(nrow(p4), 12L) expect_equal(ncol(p4), 5L) expect_s3_class(p4, "epi_df") - expect_named(p4, c("geo_value", "time_value", "additional_key", "x", "y")) + expect_named(p4, c("geo_value", "time_value", "x", "y", "additional_key")) expect_equal( p4$time_value, rep(c( @@ -110,23 +109,23 @@ test_that("step_training_window and step_naomit interact", { ) %>% as_epi_df() - e1 <- epi_recipe(y ~ x, data = tib) %>% + e1 <- recipe(y ~ x, data = tib) %>% step_training_window(n_recent = 3) %>% prep(tib) %>% bake(new_data = NULL) - e2 <- epi_recipe(y ~ x, data = tib) %>% + e2 <- recipe(y ~ x, data = tib) %>% step_naomit() %>% step_training_window(n_recent = 3) %>% prep(tib) %>% bake(new_data = NULL) - e3 <- epi_recipe(y ~ x, data = tib) %>% + e3 <- recipe(y ~ x, data = tib) %>% step_training_window(n_recent = 3) %>% step_naomit() %>% prep(tib) %>% bake(new_data = NULL) - expect_identical(e1, e2) + # expect_identical(e1, e2) e1 remains an epi_df, the others don't expect_identical(e2, e3) }) diff --git a/vignettes/articles/smooth-qr.Rmd b/vignettes/articles/smooth-qr.Rmd index 07e237181..3b5d1e3ad 100644 --- a/vignettes/articles/smooth-qr.Rmd +++ b/vignettes/articles/smooth-qr.Rmd @@ -173,7 +173,7 @@ We input our forecaster into a function for ease of use. ```{r} smooth_fc <- function(x, aheads = 1:28, degree = 3L, quantiles = 0.5, fd) { - rec <- epi_recipe(x) %>% + rec <- recipe(x) %>% step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = aheads) diff --git a/vignettes/epipredict.Rmd b/vignettes/epipredict.Rmd index af83dc321..923df8a0a 100644 --- a/vignettes/epipredict.Rmd +++ b/vignettes/epipredict.Rmd @@ -340,7 +340,7 @@ Some models like `lm` internally handle `NA`s, but not everything does, so we deal with them explicitly. The code to do this (inside the forecaster) is ```{r} -er <- epi_recipe(jhu) %>% +er <- recipe(jhu) %>% step_epi_lag(case_rate, death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_naomit() @@ -445,7 +445,7 @@ To illustrate everything above, here is (roughly) the code for the `flatline_forecaster()` applied to the `case_rate`. ```{r} -r <- epi_recipe(jhu) %>% +r <- recipe(jhu) %>% step_epi_ahead(case_rate, ahead = 7, skip = TRUE) %>% update_role(case_rate, new_role = "predictor") %>% add_role(all_of(epi_keys(jhu)), new_role = "predictor") diff --git a/vignettes/panel-data.Rmd b/vignettes/panel-data.Rmd index 0dea322f2..c5b121dc3 100644 --- a/vignettes/panel-data.Rmd +++ b/vignettes/panel-data.Rmd @@ -189,7 +189,7 @@ since we specified our `time_type` to be `year`, our `lag` and `lead` values are both in years. ```{r make-recipe, include=T, eval=T} -r <- epi_recipe(employ_small) %>% +r <- recipe(employ_small) %>% step_epi_ahead(num_graduates_prop, ahead = 1) %>% step_epi_lag(num_graduates_prop, lag = 0:2) %>% step_epi_naomit() @@ -327,7 +327,7 @@ $z_{tijk}$ is the number of graduates (proportion) at time $t$. Again, we construct an `epi_recipe` detailing the pre-processing steps. ```{r custom-arx, include=T} -rx <- epi_recipe(employ_small) %>% +rx <- recipe(employ_small) %>% step_epi_ahead(med_income_5y_prop, ahead = 1) %>% # 5-year median income has current, and two lags c(0, 1, 2) step_epi_lag(med_income_5y_prop, lag = 0:2) %>% diff --git a/vignettes/preprocessing-and-models.Rmd b/vignettes/preprocessing-and-models.Rmd index f946d0657..0aa1ac24a 100644 --- a/vignettes/preprocessing-and-models.Rmd +++ b/vignettes/preprocessing-and-models.Rmd @@ -157,9 +157,9 @@ counts_subset <- counts_subset %>% mutate(geo_value_factor = as.factor(geo_value)) %>% as_epi_df() -epi_recipe(counts_subset) +recipe(counts_subset) -r <- epi_recipe(counts_subset) %>% +r <- recipe(counts_subset) %>% update_role(geo_value_factor, new_role = "predictor") %>% step_dummy(geo_value_factor) %>% ## Occasionally, data reporting errors / corrections result in negative @@ -490,7 +490,7 @@ We can also look at the estimated coefficients and model summary information: extract_fit_engine(wf) ``` -One could also use a formula in `epi_recipe()` to achieve the same results as +One could also use a formula in `recipe()` to achieve the same results as above. However, only one of `add_formula()`, `add_recipe()`, or `workflow_variables()` can be specified. For the purpose of demonstrating `add_formula` rather than `add_recipe`, we will `prep` and `bake` our recipe to @@ -532,7 +532,7 @@ latest available date in our dataset. We will compare two methods of trying to create lags and leads: ```{r} -p1 <- epi_recipe(ex) %>% +p1 <- recipe(ex) %>% step_epi_lag(case_rate, lag = c(0, 7, 14)) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7, role = "outcome") %>% @@ -543,7 +543,7 @@ b1 <- bake(p1, ex) b1 -p2 <- epi_recipe(ex) %>% +p2 <- recipe(ex) %>% step_mutate( lag0case_rate = lag(case_rate, 0), lag7case_rate = lag(case_rate, 7), diff --git a/vignettes/update.Rmd b/vignettes/update.Rmd index fa395e192..863bed1b9 100644 --- a/vignettes/update.Rmd +++ b/vignettes/update.Rmd @@ -37,7 +37,7 @@ wish to make a change to the pre-processing, fitting, or post-processing. In the context of pre-processing, the goal of the update functions is to add/remove/update an `epi_recipe` or a step in it. For this, we have `add_epi_recipe()`, `update_epi_recipe()`, and `remove_epi_recipe()` to -add/update/remove an entire `epi_recipe` in an `epi_workflow` as well as +add/update/remove an entire `recipe` in an `epi_workflow` as well as `adjust_epi_recipe()` to adjust a particular step in an `epi_recipe` or `epi_workflow` by the step number or name. For a model, one may `Add_model()`, `Update_model()`, or `Remove_model()` in an `epi_workflow`.[^1] For post-processing, @@ -84,7 +84,7 @@ in all predictors and then in all outcomes (and set `skip = TRUE` to skip over this processing of the outcome variable when the recipe is baked). ```{r} -r <- epi_recipe(jhu) %>% +r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 14) %>% step_naomit(all_predictors()) %>% @@ -117,7 +117,7 @@ same. We can use the `update_epi_recipe()` function to trade our current recipe `r` for another recipe `r2` in `wf` as follows: ```{r} -r2 <- epi_recipe(jhu) %>% +r2 <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 1, 7, 14)) %>% step_epi_lag(case_rate, lag = c(0:7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% From 393e20ec3707b7b50bd303b1d1e9b1d86aa452d2 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Mon, 12 Aug 2024 16:33:03 -0700 Subject: [PATCH 07/25] suppress warnings --- R/epi_recipe.R | 2 +- tests/testthat/test-epi_recipe.R | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/R/epi_recipe.R b/R/epi_recipe.R index bd0aba28b..58f878839 100644 --- a/R/epi_recipe.R +++ b/R/epi_recipe.R @@ -1,7 +1,7 @@ #' @import recipes #' @export epi_recipe <- function(x, ...) { - # deprecate_soft("This function is being deprecated. Use `recipe()` instead.") + deprecate_soft("This function is being deprecated. Use `recipe()` instead.") UseMethod("epi_recipe") } diff --git a/tests/testthat/test-epi_recipe.R b/tests/testthat/test-epi_recipe.R index df04f6521..7794a3cda 100644 --- a/tests/testthat/test-epi_recipe.R +++ b/tests/testthat/test-epi_recipe.R @@ -5,12 +5,12 @@ test_that("recipe produces default recipe", { time_value = seq(as.Date("2020-01-01"), by = 1, length.out = 5) ) rec <- recipe(tib) - expect_identical(rec, epi_recipe(tib)) + expect_identical(rec, suppressWarnings(epi_recipe(tib))) expect_equal(nrow(rec$template), 5L) rec <- recipe(y ~ x, tib) - expect_identical(rec, epi_recipe(y ~ x, tib)) + expect_identical(rec, suppressWarnings(epi_recipe(y ~ x, tib))) expect_equal(nrow(rec$template), 5L) @@ -56,7 +56,7 @@ test_that("recipe formula works", { ) %>% epiprocess::as_epi_df(additional_metadata = list(other_keys = "z")) # with an additional key - r <- epi_recipe(y ~ x + geo_value, tib) + r <- recipe(y ~ x + geo_value, tib) ref_var_info <- ref_var_info %>% tibble::add_row( variable = "z", type = list(c("string", "unordered", "nominal")), @@ -74,7 +74,7 @@ test_that("recipe epi_df works", { geo_value = "ca" ) %>% epiprocess::as_epi_df() - r <- epi_recipe(tib) + r <- recipe(tib) ref_var_info <- tibble::tribble( ~variable, ~type, ~role, ~source, "time_value", "date", "time_value", "original", @@ -85,7 +85,7 @@ test_that("recipe epi_df works", { expect_identical(r$var_info, ref_var_info) expect_equal(nrow(r$template), 5L) - r <- epi_recipe(tib, formula = y ~ x) + r <- recipe(tib, formula = y ~ x) ref_var_info <- tibble::tribble( ~variable, ~type, ~role, ~source, "x", c("integer", "numeric"), "predictor", "original", @@ -97,7 +97,7 @@ test_that("recipe epi_df works", { expect_equal(nrow(r$template), 5L) - r <- epi_recipe( + r <- recipe( tib, roles = c("geo_value", "funny_business", "predictor", "outcome") ) @@ -115,7 +115,7 @@ test_that("add/update/adjust/remove epi_recipe works as intended", { library(workflows) jhu <- case_death_rate_subset - r <- epi_recipe(jhu) %>% + r <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 7, 14)) %>% step_epi_ahead(death_rate, ahead = 7) %>% step_epi_lag(case_rate, lag = c(0, 7, 14)) @@ -132,7 +132,7 @@ test_that("add/update/adjust/remove epi_recipe works as intended", { expect_equal(class(steps[[3]]), c("step_epi_lag", "step")) expect_equal(steps[[3]]$lag, c(0, 7, 14)) - r2 <- epi_recipe(jhu) %>% + r2 <- recipe(jhu) %>% step_epi_lag(death_rate, lag = c(0, 1)) %>% step_epi_ahead(death_rate, ahead = 1) From 7523d7c588a9c451320527daaca0528b4972299c Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Mon, 12 Aug 2024 16:33:55 -0700 Subject: [PATCH 08/25] styler --- R/blueprint-epi_recipe-default.R | 4 ++-- R/epi_recipe.R | 15 +++++++++------ R/recipe.epi_df.R | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/R/blueprint-epi_recipe-default.R b/R/blueprint-epi_recipe-default.R index 69a4dc1d1..4e72ae297 100644 --- a/R/blueprint-epi_recipe-default.R +++ b/R/blueprint-epi_recipe-default.R @@ -43,7 +43,8 @@ new_default_epi_recipe_blueprint <- function(intercept = FALSE, recipe = recipe, extra_role_ptypes = extra_role_ptypes, ..., - subclass = c(subclass, "default_epi_recipe_blueprint", "default_recipe_blueprint")) + subclass = c(subclass, "default_epi_recipe_blueprint", "default_recipe_blueprint") + ) } @@ -66,4 +67,3 @@ run_mold.default_epi_recipe_blueprint <- function(blueprint, ..., data) { refresh_blueprint.default_epi_recipe_blueprint <- function(blueprint) { do.call(new_default_epi_recipe_blueprint, as.list(blueprint)) } - diff --git a/R/epi_recipe.R b/R/epi_recipe.R index 58f878839..f870561be 100644 --- a/R/epi_recipe.R +++ b/R/epi_recipe.R @@ -226,8 +226,9 @@ adjust_epi_recipe.epi_recipe <- function(x, which_step, ..., blueprint = default prep.epi_recipe <- function( x, training = NULL, fresh = FALSE, verbose = FALSE, retain = TRUE, log_changes = FALSE, strings_as_factors = TRUE, ...) { - - if (!strings_as_factors) return(NextMethod("prep")) + if (!strings_as_factors) { + return(NextMethod("prep")) + } # workaround to avoid converting strings2factors with recipes::prep.recipe() # We do the conversion here, then set it to FALSE training <- recipes:::check_training_set(training, x, fresh) @@ -241,10 +242,12 @@ prep.epi_recipe <- function( training <- recipes:::strings2factors(training, lvls) # browser() - x <- NextMethod("prep", training = training, fresh = fresh, - verbose = verbose, - retain = retain, log_changes = log_changes, - strings_as_factors = FALSE, ...) + x <- NextMethod("prep", + training = training, fresh = fresh, + verbose = verbose, + retain = retain, log_changes = log_changes, + strings_as_factors = FALSE, ... + ) # Now, we undo the conversion. lvls <- lapply(x$template, recipes:::get_levels) diff --git a/R/recipe.epi_df.R b/R/recipe.epi_df.R index 8b7f67572..ca6332bb0 100644 --- a/R/recipe.epi_df.R +++ b/R/recipe.epi_df.R @@ -83,7 +83,7 @@ add_epi_df_roles_to_recipe <- function(r, epi_df) { source = "original" ) # reconstruct the constituents - r$template <- epi_df[ ,unique(c(edf_keys, r$var_info$variable))] + r$template <- epi_df[, unique(c(edf_keys, r$var_info$variable))] r$var_info <- r$var_info %>% dplyr::filter(!((variable %in% edf_keys) & is.na(role))) %>% dplyr::bind_rows(info) %>% From 9b6cf241176951058ff06bce0b107c554526f9d5 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Mon, 12 Aug 2024 16:54:48 -0700 Subject: [PATCH 09/25] ensure pkgdown builds --- _pkgdown.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index 308d984c2..5c2f4496b 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -78,7 +78,7 @@ reference: - smooth_quantile_reg - title: Custom panel data forecasting workflows contents: - - epi_recipe + - recipe.epi_df - epi_workflow - add_epi_recipe - adjust_epi_recipe From f79aa92a701b1451cf248d9dec8dbbef2742fd8a Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Tue, 13 Aug 2024 09:32:34 -0700 Subject: [PATCH 10/25] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index d4554cdde..cfde725de 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: epipredict Title: Basic epidemiology forecasting methods -Version: 0.0.18 +Version: 0.1.0 Authors@R: c( person("Daniel", "McDonald", , "daniel@stat.ubc.ca", role = c("aut", "cre")), person("Ryan", "Tibshirani", , "ryantibs@cmu.edu", role = "aut"), From 62e2f2694145a03e235442496486ee628c17e257 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Wed, 11 Sep 2024 12:11:48 -0700 Subject: [PATCH 11/25] pass checks --- R/recipe.epi_df.R | 4 ++-- R/step_population_scaling.R | 2 +- tests/testthat/test-key_colnames.R | 23 +++++------------------ tests/testthat/test-population_scaling.R | 4 ++-- 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/R/recipe.epi_df.R b/R/recipe.epi_df.R index ca6332bb0..b71b2a708 100644 --- a/R/recipe.epi_df.R +++ b/R/recipe.epi_df.R @@ -73,8 +73,8 @@ recipe.formula <- function(formula, data, ...) { } add_epi_df_roles_to_recipe <- function(r, epi_df) { - edf_keys <- epiprocess::key_colnames(epi_df) - edf_roles <- c("time_value", "geo_value", rep("key", length(edf_keys) - 2)) + edf_keys <- key_colnames(epi_df) + edf_roles <- c("geo_value", "time_value", rep("key", length(edf_keys) - 2)) types <- recipes:::get_types(epi_df[, edf_keys])$type info <- tibble( variable = edf_keys, diff --git a/R/step_population_scaling.R b/R/step_population_scaling.R index 839fad840..6d5570a21 100644 --- a/R/step_population_scaling.R +++ b/R/step_population_scaling.R @@ -171,7 +171,7 @@ bake.step_population_scaling <- function(object, new_data, ...) { )) } - object$df <- mutate(object$df, across(dplyr::where(is.character), tolower)) + # object$df <- mutate(object$df, across(dplyr::where(is.character), tolower)) pop_col <- rlang::sym(object$df_pop_col) suffix <- ifelse(object$create_new, object$suffix, "") diff --git a/tests/testthat/test-key_colnames.R b/tests/testthat/test-key_colnames.R index 9168a85a3..fdda59ad5 100644 --- a/tests/testthat/test-key_colnames.R +++ b/tests/testthat/test-key_colnames.R @@ -2,25 +2,12 @@ library(parsnip) library(workflows) library(dplyr) -test_that("epi_keys returns empty for an object that isn't an epi_df", { - expect_identical(epi_keys(data.frame(x = 1:3, y = 2:4)), character(0L)) -}) - -test_that("epi_keys returns possible keys if they exist", { - expect_identical( - epi_keys(data.frame(time_value = 1:3, geo_value = 2:4)), - c("time_value", "geo_value") - ) -}) - - -test_that("Extracts keys from an epi_df", { - expect_equal(epi_keys(case_death_rate_subset), c("time_value", "geo_value")) -}) - test_that("Extracts keys from a recipe", { - expect_equal(epi_keys(recipe(case_death_rate_subset)), c("time_value", "geo_value")) - expect_equal(epi_keys(recipe(cars)), character(0L)) + expect_equal( + key_colnames(recipe(case_death_rate_subset)), + c("geo_value", "time_value") + ) + expect_equal(key_colnames(recipe(cars)), character(0L)) }) test_that("epi_keys_mold extracts time_value and geo_value, but not raw", { diff --git a/tests/testthat/test-population_scaling.R b/tests/testthat/test-population_scaling.R index ce856acf2..1118ceb2d 100644 --- a/tests/testthat/test-population_scaling.R +++ b/tests/testthat/test-population_scaling.R @@ -213,8 +213,8 @@ test_that("test joining by default columns", { p <- prep(r, jhu) b <- bake(p, new_data = NULL) - expect_named( - b, + expect_setequal( + names(b), c( "geo_value", "time_value", "case_rate", "case_rate_scaled", paste0("lag_", c(0, 7, 14), "_case_rate_scaled"), From 75c5e4e52a7f5228fef23a26973419fc02ba4fcb Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Wed, 11 Sep 2024 14:00:56 -0700 Subject: [PATCH 12/25] stylr --- R/reexports-tidymodels.R | 1 - 1 file changed, 1 deletion(-) diff --git a/R/reexports-tidymodels.R b/R/reexports-tidymodels.R index a8dda5ff3..5b53914a8 100644 --- a/R/reexports-tidymodels.R +++ b/R/reexports-tidymodels.R @@ -30,4 +30,3 @@ tibble::tibble #' @importFrom generics tidy #' @export generics::tidy - From 6530c7e3ca75c7f6a2f76f8c61f9a5c5d537452e Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Fri, 13 Sep 2024 15:16:46 -0700 Subject: [PATCH 13/25] remove an unexported fun --- R/recipe.epi_df.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/recipe.epi_df.R b/R/recipe.epi_df.R index b71b2a708..36744fb6e 100644 --- a/R/recipe.epi_df.R +++ b/R/recipe.epi_df.R @@ -75,7 +75,7 @@ recipe.formula <- function(formula, data, ...) { add_epi_df_roles_to_recipe <- function(r, epi_df) { edf_keys <- key_colnames(epi_df) edf_roles <- c("geo_value", "time_value", rep("key", length(edf_keys) - 2)) - types <- recipes:::get_types(epi_df[, edf_keys])$type + types <- unname(lapply(epi_df[,edf_keys], recipes::.get_data_types)) info <- tibble( variable = edf_keys, type = types, From 36034fd8940984a636b14e83e7ddd0a62ad1d317 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Thu, 19 Sep 2024 12:21:00 -0700 Subject: [PATCH 14/25] styler again... --- R/recipe.epi_df.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/recipe.epi_df.R b/R/recipe.epi_df.R index 36744fb6e..6cfcf3170 100644 --- a/R/recipe.epi_df.R +++ b/R/recipe.epi_df.R @@ -75,7 +75,7 @@ recipe.formula <- function(formula, data, ...) { add_epi_df_roles_to_recipe <- function(r, epi_df) { edf_keys <- key_colnames(epi_df) edf_roles <- c("geo_value", "time_value", rep("key", length(edf_keys) - 2)) - types <- unname(lapply(epi_df[,edf_keys], recipes::.get_data_types)) + types <- unname(lapply(epi_df[, edf_keys], recipes::.get_data_types)) info <- tibble( variable = edf_keys, type = types, From a6a71c34f1e53d0c24000973b1128a0cd473f213 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Mon, 30 Sep 2024 14:34:59 -0700 Subject: [PATCH 15/25] update action versions --- .github/workflows/R-CMD-check.yaml | 2 +- .github/workflows/pkgdown.yaml | 2 +- .github/workflows/styler.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 1c8055ff0..7dc0f9d86 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -17,7 +17,7 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} R_KEEP_PKG_SOURCE: yes steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-r@v2 with: diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index cc940bc8b..faa92d380 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -22,7 +22,7 @@ jobs: env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-pandoc@v2 diff --git a/.github/workflows/styler.yml b/.github/workflows/styler.yml index ee1af6525..ba99f2aae 100644 --- a/.github/workflows/styler.yml +++ b/.github/workflows/styler.yml @@ -21,7 +21,7 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 @@ -54,7 +54,7 @@ jobs: shell: Rscript {0} - name: Cache styler - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ steps.styler-location.outputs.location }} key: ${{ runner.os }}-styler-${{ github.sha }} From b74c039c2881d7bc772935b34de1288e9d03a597 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Mon, 30 Sep 2024 16:12:09 -0700 Subject: [PATCH 16/25] skeleton --- DESCRIPTION | 2 +- NAMESPACE | 25 +-- R/dist_quantiles.R | 254 ++++----------------------- man/dist_quantiles.Rd | 37 ---- tests/testthat/test-dist_quantiles.R | 42 ++--- 5 files changed, 53 insertions(+), 307 deletions(-) delete mode 100644 man/dist_quantiles.Rd diff --git a/DESCRIPTION b/DESCRIPTION index d0366f22b..0aaa3afe6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -34,7 +34,7 @@ Imports: generics, ggplot2, glue, - hardhat (>= 1.3.0), + hardhat (>= 1.4.0.9002), magrittr, recipes (>= 1.0.4), rlang (>= 1.0.0), diff --git a/NAMESPACE b/NAMESPACE index c20b8c801..c4ad20cfa 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,8 +2,6 @@ S3method(Add_model,epi_workflow) S3method(Add_model,workflow) -S3method(Math,dist_quantiles) -S3method(Ops,dist_quantiles) S3method(Remove_model,epi_workflow) S3method(Remove_model,workflow) S3method(Update_model,epi_workflow) @@ -45,13 +43,9 @@ S3method(fit,epi_workflow) S3method(flusight_hub_formatter,canned_epipred) S3method(flusight_hub_formatter,data.frame) S3method(forecast,epi_workflow) -S3method(format,dist_quantiles) -S3method(is.na,dist_quantiles) -S3method(is.na,distribution) S3method(key_colnames,epi_workflow) S3method(key_colnames,recipe) -S3method(mean,dist_quantiles) -S3method(median,dist_quantiles) +S3method(mean,quantile_pred) S3method(predict,epi_workflow) S3method(predict,flatline) S3method(prep,check_enough_train_data) @@ -93,7 +87,7 @@ S3method(print,step_lag_difference) S3method(print,step_naomit) S3method(print,step_population_scaling) S3method(print,step_training_window) -S3method(quantile,dist_quantiles) +S3method(quantile,quantile_pred) S3method(recipe,epi_df) S3method(recipes::recipe,formula) S3method(refresh_blueprint,default_epi_recipe_blueprint) @@ -119,8 +113,6 @@ S3method(tidy,check_enough_train_data) S3method(tidy,frosting) S3method(tidy,layer) S3method(update,layer) -S3method(vec_ptype_abbr,dist_quantiles) -S3method(vec_ptype_full,dist_quantiles) S3method(weighted_interval_score,default) S3method(weighted_interval_score,dist_default) S3method(weighted_interval_score,dist_quantiles) @@ -150,7 +142,6 @@ export(check_enough_train_data) export(clean_f_name) export(default_epi_recipe_blueprint) export(detect_layer) -export(dist_quantiles) export(epi_recipe) export(epi_workflow) export(extract_argument) @@ -208,7 +199,6 @@ export(update_frosting) export(update_model) export(validate_layer) export(weighted_interval_score) -import(distributional) import(epiprocess) import(parsnip) import(recipes) @@ -283,24 +273,13 @@ importFrom(rlang,is_true) importFrom(rlang,set_names) importFrom(rlang,sym) importFrom(stats,as.formula) -importFrom(stats,family) importFrom(stats,lm) -importFrom(stats,median) importFrom(stats,model.frame) importFrom(stats,poly) importFrom(stats,predict) -importFrom(stats,qnorm) importFrom(stats,quantile) importFrom(stats,residuals) importFrom(tibble,as_tibble) importFrom(tibble,tibble) importFrom(tidyr,crossing) -importFrom(vctrs,as_list_of) -importFrom(vctrs,field) -importFrom(vctrs,new_rcrd) -importFrom(vctrs,new_vctr) -importFrom(vctrs,vec_cast) importFrom(vctrs,vec_data) -importFrom(vctrs,vec_ptype_abbr) -importFrom(vctrs,vec_ptype_full) -importFrom(vctrs,vec_recycle_common) diff --git a/R/dist_quantiles.R b/R/dist_quantiles.R index dd97ec809..bf32c35ec 100644 --- a/R/dist_quantiles.R +++ b/R/dist_quantiles.R @@ -1,204 +1,68 @@ -#' @importFrom vctrs field vec_cast new_rcrd -new_quantiles <- function(values = double(1), quantile_levels = double(1)) { - arg_is_probabilities(quantile_levels) - - vec_cast(values, double()) - vec_cast(quantile_levels, double()) - values <- unname(values) - if (length(values) == 0L) { - return(new_rcrd( - list( - values = rep(NA_real_, length(quantile_levels)), - quantile_levels = quantile_levels - ), - class = c("dist_quantiles", "dist_default") - )) - } - stopifnot(length(values) == length(quantile_levels)) - - stopifnot(!vctrs::vec_duplicate_any(quantile_levels)) - if (is.unsorted(quantile_levels)) { - o <- vctrs::vec_order(quantile_levels) - values <- values[o] - quantile_levels <- quantile_levels[o] - } - if (is.unsorted(values, na.rm = TRUE)) { - cli::cli_abort("`values[order(quantile_levels)]` produces unsorted quantiles.") - } - - new_rcrd(list(values = values, quantile_levels = quantile_levels), - class = c("dist_quantiles", "dist_default") - ) -} - - - -#' @importFrom vctrs vec_ptype_abbr vec_ptype_full -#' @export -vec_ptype_abbr.dist_quantiles <- function(x, ...) "dist_qntls" -#' @export -vec_ptype_full.dist_quantiles <- function(x, ...) "dist_quantiles" - -#' @export -format.dist_quantiles <- function(x, digits = 2, ...) { - m <- suppressWarnings(median(x)) - paste0("quantiles(", round(m, digits), ")[", vctrs::vec_size(x), "]") -} - - -#' A distribution parameterized by a set of quantiles -#' -#' @param values A vector (or list of vectors) of values. -#' @param quantile_levels A vector (or list of vectors) of probabilities -#' corresponding to `values`. -#' -#' When creating multiple sets of `values`/`quantile_levels` resulting in -#' different distributions, the sizes must match. See the examples below. -#' -#' @return A vector of class `"distribution"`. -#' -#' @export -#' -#' @examples -#' dist_quantiles(1:4, 1:4 / 5) -#' dist_quantiles(list(1:3, 1:4), list(1:3 / 4, 1:4 / 5)) -#' dstn <- dist_quantiles(list(1:4, 8:11), c(.2, .4, .6, .8)) -#' dstn -#' -#' quantile(dstn, p = c(.1, .25, .5, .9)) -#' median(dstn) -#' -#' # it's a bit annoying to inspect the data -#' distributional::parameters(dstn[1]) -#' nested_quantiles(dstn[1])[[1]] -#' -#' @importFrom vctrs as_list_of vec_recycle_common new_vctr -dist_quantiles <- function(values, quantile_levels) { - if (!is.list(quantile_levels)) { - assert_numeric(quantile_levels, lower = 0, upper = 1, any.missing = FALSE, min.len = 1L) - quantile_levels <- list(quantile_levels) - } - if (!is.list(values)) { - if (length(values) == 0L) values <- NA_real_ - values <- list(values) - } - - values <- as_list_of(values, .ptype = double()) - quantile_levels <- as_list_of(quantile_levels, .ptype = double()) - args <- vec_recycle_common(values = values, quantile_levels = quantile_levels) - - qntls <- as_list_of( - map2(args$values, args$quantile_levels, new_quantiles), - .ptype = new_quantiles(NA_real_, 0.5) - ) - new_vctr(qntls, class = "distribution") -} - -validate_dist_quantiles <- function(values, quantile_levels) { - map(quantile_levels, arg_is_probabilities) - common_length <- vctrs::vec_size_common( # aborts internally - values = values, - quantile_levels = quantile_levels - ) - length_diff <- vctrs::list_sizes(values) != vctrs::list_sizes(quantile_levels) - if (any(length_diff)) { - cli::cli_abort(c( - "`values` and `quantile_levels` must have common length.", - i = "Mismatches found at position(s): {.val {which(length_diff)}}." - )) - } - level_duplication <- map_lgl(quantile_levels, vctrs::vec_duplicate_any) - if (any(level_duplication)) { - cli::cli_abort(c( - "`quantile_levels` must not be duplicated.", - i = "Duplicates found at position(s): {.val {which(level_duplication)}}." - )) - } -} - - -is_dist_quantiles <- function(x) { - is_distribution(x) & all(stats::family(x) == "quantiles") -} - - - -#' @export -#' @importFrom stats median qnorm family -median.dist_quantiles <- function(x, na.rm = FALSE, ..., middle = c("cubic", "linear")) { - quantile_levels <- field(x, "quantile_levels") - values <- field(x, "values") - if (0.5 %in% quantile_levels) { - return(values[match(0.5, quantile_levels)]) - } - if (length(quantile_levels) < 2 || min(quantile_levels) > 0.5 || max(quantile_levels) < 0.5) { - return(NA) - } - if (length(quantile_levels) < 3 || min(quantile_levels) > .25 || max(quantile_levels) < .75) { - return(stats::approx(quantile_levels, values, xout = 0.5)$y) - } - quantile(x, 0.5, ..., middle = middle) -} # placeholder to avoid errors, but not ideal #' @export -mean.dist_quantiles <- function(x, na.rm = FALSE, ..., middle = c("cubic", "linear")) { - median(x, ..., middle = middle) +mean.quantile_pred <- function(x, na.rm = FALSE, ...) { + median(x, ...) } #' @export #' @importFrom stats quantile -#' @import distributional -quantile.dist_quantiles <- function(x, p, ..., middle = c("cubic", "linear")) { +quantile.quantile_pred <- function(x, p, ..., middle = c("cubic", "linear")) { arg_is_probabilities(p) p <- sort(p) - middle <- match.arg(middle) + middle <- rlang::arg_match(middle) quantile_extrapolate(x, p, middle) } quantile_extrapolate <- function(x, tau_out, middle) { - tau <- field(x, "quantile_levels") - qvals <- field(x, "values") - nas <- is.na(qvals) - qvals_out <- rep(NA, length(tau_out)) - qvals <- qvals[!nas] - tau <- tau[!nas] + tau <- x %@% "quantile_levels" + qvals <- as.matrix(x) # short circuit if we aren't actually extrapolating # matches to ~15 decimals if (all(tau_out %in% tau)) { - return(qvals[match(tau_out, tau)]) + return(hardhat::quantile_pred( + qvals[ ,match(tau_out, tau), drop = FALSE], tau_out + )) } if (length(tau) < 2) { - cli::cli_abort( - "Quantile extrapolation is not possible with fewer than 2 quantiles." - ) - return(qvals_out) + cli_abort(paste( + "Quantile extrapolation is not possible when fewer than 2 quantiles", + "are available." + )) } + qvals_out <- map( + vctrs::vec_chop(qvals), + ~ extrapolate_quantiles_single(.x, tau, tau_out, middle) + ) + hardhat::quantile_pred(qvals_out, tau_out) +} + +extrapolate_quantiles_single <- function(qvals, tau, tau_out, middle) { indl <- tau_out < min(tau) indr <- tau_out > max(tau) indm <- !indl & !indr + qvals_out <- rep(NA, length(tau_out)) if (middle == "cubic") { method <- "cubic" - result <- tryCatch( - { - Q <- stats::splinefun(tau, qvals, method = "hyman") - quartiles <- Q(c(.25, .5, .75)) - }, - error = function(e) { - return(NA) - } - ) + result <- tryCatch({ + Q <- stats::splinefun(tau, qvals, method = "hyman") + quartiles <- Q(c(.25, .5, .75)) + }, + error = function(e) { + return(NA) + }) } if (middle == "linear" || any(is.na(result))) { method <- "linear" quartiles <- stats::approx(tau, qvals, c(.25, .5, .75))$y } if (any(indm)) { - qvals_out[indm] <- switch(method, + qvals_out[indm] <- switch( + method, linear = stats::approx(tau, qvals, tau_out[indm])$y, cubic = Q(tau_out[indm]) ) @@ -237,59 +101,3 @@ tail_extrapolate <- function(tau_out, qv) { m <- diff(y) / diff(x) m * (x0 - x[1]) + y[1] } - - -#' @method Math dist_quantiles -#' @export -Math.dist_quantiles <- function(x, ...) { - quantile_levels <- field(x, "quantile_levels") - values <- field(x, "values") - values <- vctrs::vec_math(.Generic, values, ...) - new_quantiles(values = values, quantile_levels = quantile_levels) -} - -#' @method Ops dist_quantiles -#' @export -Ops.dist_quantiles <- function(e1, e2) { - is_quantiles <- c( - inherits(e1, "dist_quantiles"), - inherits(e2, "dist_quantiles") - ) - is_dist <- c(inherits(e1, "dist_default"), inherits(e2, "dist_default")) - tau1 <- tau2 <- NULL - if (is_quantiles[1]) { - q1 <- field(e1, "values") - tau1 <- field(e1, "quantile_levels") - } - if (is_quantiles[2]) { - q2 <- field(e2, "values") - tau2 <- field(e2, "quantile_levels") - } - tau <- union(tau1, tau2) - if (all(is_dist)) { - cli::cli_abort( - "You can't perform arithmetic between two distributions like this." - ) - } else { - if (is_quantiles[1]) { - q2 <- e2 - } else { - q1 <- e1 - } - } - q <- vctrs::vec_arith(.Generic, q1, q2) - new_quantiles(values = q, quantile_levels = tau) -} - -#' @method is.na distribution -#' @export -is.na.distribution <- function(x) { - sapply(vec_data(x), is.na) -} - -#' @method is.na dist_quantiles -#' @export -is.na.dist_quantiles <- function(x) { - q <- field(x, "values") - all(is.na(q)) -} diff --git a/man/dist_quantiles.Rd b/man/dist_quantiles.Rd deleted file mode 100644 index 1a3226e36..000000000 --- a/man/dist_quantiles.Rd +++ /dev/null @@ -1,37 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dist_quantiles.R -\name{dist_quantiles} -\alias{dist_quantiles} -\title{A distribution parameterized by a set of quantiles} -\usage{ -dist_quantiles(values, quantile_levels) -} -\arguments{ -\item{values}{A vector (or list of vectors) of values.} - -\item{quantile_levels}{A vector (or list of vectors) of probabilities -corresponding to \code{values}. - -When creating multiple sets of \code{values}/\code{quantile_levels} resulting in -different distributions, the sizes must match. See the examples below.} -} -\value{ -A vector of class \code{"distribution"}. -} -\description{ -A distribution parameterized by a set of quantiles -} -\examples{ -dist_quantiles(1:4, 1:4 / 5) -dist_quantiles(list(1:3, 1:4), list(1:3 / 4, 1:4 / 5)) -dstn <- dist_quantiles(list(1:4, 8:11), c(.2, .4, .6, .8)) -dstn - -quantile(dstn, p = c(.1, .25, .5, .9)) -median(dstn) - -# it's a bit annoying to inspect the data -distributional::parameters(dstn[1]) -nested_quantiles(dstn[1])[[1]] - -} diff --git a/tests/testthat/test-dist_quantiles.R b/tests/testthat/test-dist_quantiles.R index 66456ef80..4b20aa6b9 100644 --- a/tests/testthat/test-dist_quantiles.R +++ b/tests/testthat/test-dist_quantiles.R @@ -1,36 +1,32 @@ -library(distributional) -test_that("constructor returns reasonable quantiles", { - expect_error(new_quantiles(rnorm(5), rnorm(5))) - expect_silent(new_quantiles(sort(rnorm(5)), sort(runif(5)))) - expect_error(new_quantiles(sort(rnorm(5)), sort(runif(2)))) - expect_silent(new_quantiles(1:5, 1:5 / 10)) - expect_error(new_quantiles(c(2, 1, 3, 4, 5), c(.1, .1, .2, .5, .8))) - expect_error(new_quantiles(c(2, 1, 3, 4, 5), c(.1, .15, .2, .5, .8))) - expect_error(new_quantiles(c(1, 2, 3), c(.1, .2, 3))) -}) - - -test_that("single dist_quantiles works, quantiles are accessible", { - z <- new_quantiles(values = 1:5, quantile_levels = c(.2, .4, .5, .6, .8)) - expect_s3_class(z, "dist_quantiles") +test_that("single quantile_pred works, quantiles are accessible", { + z <- hardhat::quantile_pred( + values = matrix(1:5, nrow = 1), + quantile_levels = c(.2, .4, .5, .6, .8) + ) expect_equal(median(z), 3) - expect_equal(quantile(z, c(.2, .4, .5, .6, .8)), 1:5) - expect_equal(quantile(z, c(.3, .7), middle = "linear"), c(1.5, 4.5)) + expect_equal( + quantile(z, c(.2, .4, .5, .6, .8)), + hardhat::quantile_pred(matrix(1:5, nrow = 1), c(.2, .4, .5, .6, .8)) + ) + expect_equal( + quantile(z, c(.3, .7), middle = "linear"), + hardhat::quantile_pred(matrix(c(1.5, 4.5), nrow = 1), c(.3, .7)) + ) Q <- stats::splinefun(c(.2, .4, .5, .6, .8), 1:5, method = "hyman") expect_equal(quantile(z, c(.3, .7), middle = "cubic"), Q(c(.3, .7))) expect_identical( extrapolate_quantiles(z, c(.3, .7), middle = "linear"), - new_quantiles(values = c(1, 1.5, 2, 3, 4, 4.5, 5), quantile_levels = 2:8 / 10) + hardhat::quantile_pred(c(1, 1.5, 2, 3, 4, 4.5, 5), 2:8 / 10) ) # empty values slot results in a length zero distribution # see issue #361 - expect_length(dist_quantiles(list(), c(.1, .9)), 0L) - expect_identical( - dist_quantiles(list(), c(.1, .9)), - distributional::dist_degenerate(double()) - ) + # expect_length(dist_quantiles(list(), c(.1, .9)), 0L) + # expect_identical( + # dist_quantiles(list(), c(.1, .9)), + # distributional::dist_degenerate(double()) + # ) }) From 4a09c079e51f0ddff6199ea1d584c5ac8fbe215e Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Wed, 19 Feb 2025 15:04:05 -0800 Subject: [PATCH 17/25] add math ops and related tests --- NAMESPACE | 36 +++----- R/extrapolate_quantiles.R | 40 ++++----- ...st_quantiles.R => quantile_pred-methods.R} | 75 ++++++++++++++--- man/dist_quantiles.Rd | 37 --------- tests/testthat/test-dist_quantiles.R | 82 +++++++++---------- 5 files changed, 132 insertions(+), 138 deletions(-) rename R/{dist_quantiles.R => quantile_pred-methods.R} (52%) delete mode 100644 man/dist_quantiles.Rd diff --git a/NAMESPACE b/NAMESPACE index 3a1fed508..eefe36d05 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,8 +2,6 @@ S3method(Add_model,epi_workflow) S3method(Add_model,workflow) -S3method(Math,dist_quantiles) -S3method(Ops,dist_quantiles) S3method(Remove_model,epi_workflow) S3method(Remove_model,workflow) S3method(Update_model,epi_workflow) @@ -40,20 +38,14 @@ S3method(extract_frosting,default) S3method(extract_frosting,epi_workflow) S3method(extract_layers,frosting) S3method(extract_layers,workflow) -S3method(extrapolate_quantiles,dist_default) -S3method(extrapolate_quantiles,dist_quantiles) -S3method(extrapolate_quantiles,distribution) +S3method(extrapolate_quantiles,quantile_pred) S3method(fit,epi_workflow) S3method(flusight_hub_formatter,canned_epipred) S3method(flusight_hub_formatter,data.frame) S3method(forecast,epi_workflow) -S3method(format,dist_quantiles) -S3method(is.na,dist_quantiles) -S3method(is.na,distribution) S3method(key_colnames,epi_workflow) S3method(key_colnames,recipe) -S3method(mean,dist_quantiles) -S3method(median,dist_quantiles) +S3method(mean,quantile_pred) S3method(predict,epi_workflow) S3method(predict,flatline) S3method(prep,check_enough_train_data) @@ -97,7 +89,7 @@ S3method(print,step_lag_difference) S3method(print,step_naomit) S3method(print,step_population_scaling) S3method(print,step_training_window) -S3method(quantile,dist_quantiles) +S3method(quantile,quantile_pred) S3method(refresh_blueprint,default_epi_recipe_blueprint) S3method(residuals,flatline) S3method(run_mold,default_epi_recipe_blueprint) @@ -121,8 +113,10 @@ S3method(tidy,check_enough_train_data) S3method(tidy,frosting) S3method(tidy,layer) S3method(update,layer) -S3method(vec_ptype_abbr,dist_quantiles) -S3method(vec_ptype_full,dist_quantiles) +S3method(vec_arith,quantile_pred) +S3method(vec_arith.numeric,quantile_pred) +S3method(vec_arith.quantile_pred,numeric) +S3method(vec_math,quantile_pred) S3method(weighted_interval_score,default) S3method(weighted_interval_score,dist_default) S3method(weighted_interval_score,dist_quantiles) @@ -152,7 +146,6 @@ export(check_enough_train_data) export(clean_f_name) export(default_epi_recipe_blueprint) export(detect_layer) -export(dist_quantiles) export(epi_recipe) export(epi_recipe_blueprint) export(epi_workflow) @@ -213,7 +206,6 @@ export(update_frosting) export(update_model) export(validate_layer) export(weighted_interval_score) -import(distributional) import(epidatasets) import(epiprocess) import(parsnip) @@ -300,14 +292,11 @@ importFrom(rlang,list2) importFrom(rlang,set_names) importFrom(rlang,sym) importFrom(stats,as.formula) -importFrom(stats,family) importFrom(stats,lm) -importFrom(stats,median) importFrom(stats,model.frame) importFrom(stats,na.omit) importFrom(stats,poly) importFrom(stats,predict) -importFrom(stats,qnorm) importFrom(stats,quantile) importFrom(stats,residuals) importFrom(tibble,as_tibble) @@ -319,13 +308,8 @@ importFrom(tidyr,fill) importFrom(tidyr,unnest) importFrom(tidyselect,all_of) importFrom(utils,capture.output) -importFrom(vctrs,as_list_of) -importFrom(vctrs,field) -importFrom(vctrs,new_rcrd) -importFrom(vctrs,new_vctr) +importFrom(vctrs,vec_arith) +importFrom(vctrs,vec_arith.numeric) importFrom(vctrs,vec_cast) -importFrom(vctrs,vec_data) -importFrom(vctrs,vec_ptype_abbr) -importFrom(vctrs,vec_ptype_full) -importFrom(vctrs,vec_recycle_common) +importFrom(vctrs,vec_math) importFrom(workflows,extract_preprocessor) diff --git a/R/extrapolate_quantiles.R b/R/extrapolate_quantiles.R index 3362e339e..d9e899ef6 100644 --- a/R/extrapolate_quantiles.R +++ b/R/extrapolate_quantiles.R @@ -32,34 +32,28 @@ extrapolate_quantiles <- function(x, probs, replace_na = TRUE, ...) { } #' @export -#' @importFrom vctrs vec_data -extrapolate_quantiles.distribution <- function(x, probs, replace_na = TRUE, ...) { - rlang::check_dots_empty() +extrapolate_quantiles.quantile_pred <- function(x, probs, replace_na = TRUE, ...) { arg_is_lgl_scalar(replace_na) arg_is_probabilities(probs) if (is.unsorted(probs)) probs <- sort(probs) - dstn <- lapply(vec_data(x), extrapolate_quantiles, probs = probs, replace_na = replace_na) - new_vctr(dstn, vars = NULL, class = "distribution") -} - -#' @export -extrapolate_quantiles.dist_default <- function(x, probs, replace_na = TRUE, ...) { - values <- quantile(x, probs, ...) - new_quantiles(values = values, quantile_levels = probs) -} + orig_probs <- x %@% "quantile_levels" + orig_values <- as.matrix(x) -#' @export -extrapolate_quantiles.dist_quantiles <- function(x, probs, replace_na = TRUE, ...) { - orig_probs <- field(x, "quantile_levels") - orig_values <- field(x, "values") - new_probs <- c(orig_probs, probs) - dups <- duplicated(new_probs) if (!replace_na || !anyNA(orig_values)) { - new_values <- c(orig_values, quantile(x, probs, ...)) + all_values <- cbind(orig_values, quantile(x, probs, ...)) } else { - nas <- is.na(orig_values) - orig_values[nas] <- quantile(x, orig_probs[nas], ...) - new_values <- c(orig_values, quantile(x, probs, ...)) + newx <- quantile(x, orig_probs, ...) %>% + hardhat::quantile_pred(orig_probs) + all_values <- cbind(as.matrix(newx), quantile(newx, probs, ...)) } - new_quantiles(new_values[!dups], new_probs[!dups]) + all_probs <- c(orig_probs, probs) + dups <- duplicated(all_probs) + all_values <- all_values[, !dups, drop = FALSE] + all_probs <- all_probs[!dups] + o <- order(all_probs) + + hardhat::quantile_pred( + all_values[, o, drop = FALSE], + quantile_levels = all_probs[o] + ) } diff --git a/R/dist_quantiles.R b/R/quantile_pred-methods.R similarity index 52% rename from R/dist_quantiles.R rename to R/quantile_pred-methods.R index bf32c35ec..04884ccd0 100644 --- a/R/dist_quantiles.R +++ b/R/quantile_pred-methods.R @@ -5,26 +5,29 @@ mean.quantile_pred <- function(x, na.rm = FALSE, ...) { median(x, ...) } + +# quantiles by treating quantile_pred like a distribution ----------------- + + #' @export #' @importFrom stats quantile -quantile.quantile_pred <- function(x, p, ..., middle = c("cubic", "linear")) { +quantile.quantile_pred <- function(x, p, na.rm = FALSE, ..., + middle = c("cubic", "linear")) { arg_is_probabilities(p) p <- sort(p) middle <- rlang::arg_match(middle) - quantile_extrapolate(x, p, middle) + quantile_internal(x, p, middle) } -quantile_extrapolate <- function(x, tau_out, middle) { +quantile_internal <- function(x, tau_out, middle) { tau <- x %@% "quantile_levels" qvals <- as.matrix(x) # short circuit if we aren't actually extrapolating # matches to ~15 decimals - if (all(tau_out %in% tau)) { - return(hardhat::quantile_pred( - qvals[ ,match(tau_out, tau), drop = FALSE], tau_out - )) + if (all(tau_out %in% tau) && !anyNA(qvals)) { + return(qvals[ , match(tau_out, tau), drop = FALSE]) } if (length(tau) < 2) { cli_abort(paste( @@ -36,15 +39,26 @@ quantile_extrapolate <- function(x, tau_out, middle) { vctrs::vec_chop(qvals), ~ extrapolate_quantiles_single(.x, tau, tau_out, middle) ) - - hardhat::quantile_pred(qvals_out, tau_out) + qvals_out <- do.call(rbind, qvals_out) # ensure a matrix of the proper dims + qvals_out } extrapolate_quantiles_single <- function(qvals, tau, tau_out, middle) { + qvals_out <- rep(NA, length(tau_out)) + good <- !is.na(qvals) + qvals <- qvals[good] + tau <- tau[good] + + # in case we only have one point, and it matches something we wanted + if (length(good) < 2) { + matched_one <- tau_out %in% tau + qvals_out[matched_one] <- qvals[matched_one] + return(qvals_out) + } + indl <- tau_out < min(tau) indr <- tau_out > max(tau) indm <- !indl & !indr - qvals_out <- rep(NA, length(tau_out)) if (middle == "cubic") { method <- "cubic" @@ -101,3 +115,44 @@ tail_extrapolate <- function(tau_out, qv) { m <- diff(y) / diff(x) m * (x0 - x[1]) + y[1] } + + +# mathematical operations on the values ----------------------------------- + + +#' @importFrom vctrs vec_math +#' @export +#' @method vec_math quantile_pred +vec_math.quantile_pred <- function(.fn, .x, ...) { + fn <- .fn + .fn <- getExportedValue("base", .fn) + if (fn %in% c("any", "all", "prod", "sum", "cumsum", "cummax", "cummin", "cumprod")) { + cli_abort("{.fn {fn}} is not a supported operation for {.cls quantile_pred}.") + } + quantile_levels <- .x %@% "quantile_levels" + .x <- as.matrix(.x) + hardhat::quantile_pred(.fn(.x), quantile_levels) +} + +#' @importFrom vctrs vec_arith vec_arith.numeric +#' @export +#' @method vec_arith quantile_pred +vec_arith.quantile_pred <- function(op, x, y, ...) { + UseMethod("vec_arith.quantile_pred", y) +} + +#' @export +#' @method vec_arith.quantile_pred numeric +vec_arith.quantile_pred.numeric <- function(op, x, y, ...) { + op_fn <- getExportedValue("base", op) + out <- op_fn(as.matrix(x), y) + hardhat::quantile_pred(out, x %@% "quantile_levels") +} + +#' @export +#' @method vec_arith.numeric quantile_pred +vec_arith.numeric.quantile_pred <- function(op, x, y, ...) { + op_fn <- getExportedValue("base", op) + out <- op_fn(x, as.matrix(y)) + hardhat::quantile_pred(out, y %@% "quantile_levels") +} diff --git a/man/dist_quantiles.Rd b/man/dist_quantiles.Rd deleted file mode 100644 index 1a3226e36..000000000 --- a/man/dist_quantiles.Rd +++ /dev/null @@ -1,37 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dist_quantiles.R -\name{dist_quantiles} -\alias{dist_quantiles} -\title{A distribution parameterized by a set of quantiles} -\usage{ -dist_quantiles(values, quantile_levels) -} -\arguments{ -\item{values}{A vector (or list of vectors) of values.} - -\item{quantile_levels}{A vector (or list of vectors) of probabilities -corresponding to \code{values}. - -When creating multiple sets of \code{values}/\code{quantile_levels} resulting in -different distributions, the sizes must match. See the examples below.} -} -\value{ -A vector of class \code{"distribution"}. -} -\description{ -A distribution parameterized by a set of quantiles -} -\examples{ -dist_quantiles(1:4, 1:4 / 5) -dist_quantiles(list(1:3, 1:4), list(1:3 / 4, 1:4 / 5)) -dstn <- dist_quantiles(list(1:4, 8:11), c(.2, .4, .6, .8)) -dstn - -quantile(dstn, p = c(.1, .25, .5, .9)) -median(dstn) - -# it's a bit annoying to inspect the data -distributional::parameters(dstn[1]) -nested_quantiles(dstn[1])[[1]] - -} diff --git a/tests/testthat/test-dist_quantiles.R b/tests/testthat/test-dist_quantiles.R index 4b20aa6b9..18fe92ed2 100644 --- a/tests/testthat/test-dist_quantiles.R +++ b/tests/testthat/test-dist_quantiles.R @@ -5,52 +5,38 @@ test_that("single quantile_pred works, quantiles are accessible", { quantile_levels = c(.2, .4, .5, .6, .8) ) expect_equal(median(z), 3) - expect_equal( - quantile(z, c(.2, .4, .5, .6, .8)), - hardhat::quantile_pred(matrix(1:5, nrow = 1), c(.2, .4, .5, .6, .8)) - ) + expect_equal(quantile(z, c(.2, .4, .5, .6, .8)), matrix(1:5, nrow = 1)) expect_equal( quantile(z, c(.3, .7), middle = "linear"), - hardhat::quantile_pred(matrix(c(1.5, 4.5), nrow = 1), c(.3, .7)) + matrix(c(1.5, 4.5), nrow = 1) ) Q <- stats::splinefun(c(.2, .4, .5, .6, .8), 1:5, method = "hyman") - expect_equal(quantile(z, c(.3, .7), middle = "cubic"), Q(c(.3, .7))) + expect_equal(quantile(z, c(.3, .7)), Q(c(.3, .7))) expect_identical( extrapolate_quantiles(z, c(.3, .7), middle = "linear"), - hardhat::quantile_pred(c(1, 1.5, 2, 3, 4, 4.5, 5), 2:8 / 10) + hardhat::quantile_pred(matrix(c(1, 1.5, 2, 3, 4, 4.5, 5), nrow = 1), 2:8 / 10) ) - # empty values slot results in a length zero distribution - # see issue #361 - # expect_length(dist_quantiles(list(), c(.1, .9)), 0L) - # expect_identical( - # dist_quantiles(list(), c(.1, .9)), - # distributional::dist_degenerate(double()) - # ) }) test_that("quantile extrapolator works", { - dstn <- dist_normal(c(10, 2), c(5, 10)) - qq <- extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75)) - expect_s3_class(qq, "distribution") - expect_s3_class(vctrs::vec_data(qq[1])[[1]], "dist_quantiles") - expect_length(parameters(qq[1])$quantile_levels[[1]], 3L) - - dstn <- dist_quantiles(list(1:4, 8:11), list(c(.2, .4, .6, .8))) + dstn <- hardhat::quantile_pred( + matrix(c(1:4, 8:11), nrow = 2, byrow = TRUE), + c(.2, .4, .6, .8) + ) qq <- extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75)) - expect_s3_class(qq, "distribution") - expect_s3_class(vctrs::vec_data(qq[1])[[1]], "dist_quantiles") - expect_length(parameters(qq[1])$quantile_levels[[1]], 7L) + expect_s3_class(qq, c("quantile_pred", "vctrs_vctr", "list")) + expect_length(qq %@% "quantile_levels", 7L) - dstn <- dist_quantiles(1:4, 1:4 / 5) + dstn <- hardhat::quantile_pred(matrix(1:4, nrow = 1), 1:4 / 5) qq <- extrapolate_quantiles(dstn, 1:9 / 10) - dstn_na <- dist_quantiles(c(1, 2, NA, 4), 1:4 / 5) + dstn_na <- hardhat::quantile_pred(matrix(c(1, 2, NA, 4), nrow = 1), 1:4 / 5) qq2 <- extrapolate_quantiles(dstn_na, 1:9 / 10) expect_equal(qq, qq2) qq3 <- extrapolate_quantiles(dstn_na, 1:9 / 10, replace_na = FALSE) - qq2_vals <- field(vec_data(qq2)[[1]], "values") - qq3_vals <- field(vec_data(qq3)[[1]], "values") + qq2_vals <- unlist(qq2) + qq3_vals <- unlist(qq3) qq2_vals[6] <- NA expect_equal(qq2_vals, qq3_vals) }) @@ -60,7 +46,7 @@ test_that("small deviations of quantile requests work", { v <- c(0.0890306, 0.1424997, 0.1971793, 0.2850978, 0.3832912, 0.4240479) badl <- l badl[1] <- badl[1] - 1e-14 - distn <- dist_quantiles(list(v), list(l)) + distn <- hardhat::quantile_pred(matrix(v, nrow = 1), l) # was broken before, now works expect_equal(quantile(distn, l), quantile(distn, badl)) @@ -69,39 +55,51 @@ test_that("small deviations of quantile requests work", { # the smallest (largest) values or we could end up unsorted l <- 1:9 / 10 v <- 1:9 - distn <- dist_quantiles(list(v), list(l)) - expect_equal(quantile(distn, c(.25, .75)), list(c(2.5, 7.5))) - expect_equal(quantile(distn, c(.1, .9)), list(c(1, 9))) + distn <- hardhat::quantile_pred(matrix(v, nrow = 1), l) + expect_equal(quantile(distn, c(.25, .75)), matrix(c(2.5, 7.5), nrow = 1)) + expect_equal(quantile(distn, c(.1, .9)), matrix(c(1, 9), nrow = 1)) qv <- data.frame(q = l, v = v) expect_equal( - unlist(quantile(distn, c(.01, .05))), + drop(quantile(distn, c(.01, .05))), tail_extrapolate(c(.01, .05), head(qv, 2)) ) expect_equal( - unlist(quantile(distn, c(.99, .95))), + drop(quantile(distn, c(.99, .95))), tail_extrapolate(c(.95, .99), tail(qv, 2)) ) }) test_that("unary math works on quantiles", { - dstn <- dist_quantiles(list(1:4, 8:11), list(c(.2, .4, .6, .8))) - dstn2 <- dist_quantiles(list(log(1:4), log(8:11)), list(c(.2, .4, .6, .8))) + dstn <- hardhat::quantile_pred( + matrix(c(1:4, 8:11), nrow = 2, byrow = TRUE), + 1:4 / 5 + ) + dstn2 <- hardhat::quantile_pred( + log(matrix(c(1:4, 8:11), nrow = 2, byrow = TRUE)), + 1:4 / 5 + ) expect_identical(log(dstn), dstn2) - dstn2 <- dist_quantiles(list(cumsum(1:4), cumsum(8:11)), list(c(.2, .4, .6, .8))) - expect_identical(cumsum(dstn), dstn2) }) test_that("arithmetic works on quantiles", { - dstn <- dist_quantiles(list(1:4, 8:11), list(c(.2, .4, .6, .8))) - dstn2 <- dist_quantiles(list(1:4 + 1, 8:11 + 1), list(c(.2, .4, .6, .8))) + dstn <- hardhat::quantile_pred( + matrix(c(1:4, 8:11), nrow = 2, byrow = TRUE), + 1:4 / 5 + ) + dstn2 <- hardhat::quantile_pred( + matrix(c(1:4, 8:11), nrow = 2, byrow = TRUE) + 1, + 1:4 / 5 + ) expect_identical(dstn + 1, dstn2) expect_identical(1 + dstn, dstn2) - dstn2 <- dist_quantiles(list(1:4 / 4, 8:11 / 4), list(c(.2, .4, .6, .8))) + dstn2 <- hardhat::quantile_pred( + matrix(c(1:4, 8:11), nrow = 2, byrow = TRUE) / 4, + 1:4 / 5 + ) expect_identical(dstn / 4, dstn2) expect_identical((1 / 4) * dstn, dstn2) expect_error(sum(dstn)) - expect_error(suppressWarnings(dstn + distributional::dist_normal())) }) From db662a275b41df5851c88cd6c33e0b6f44bd2a57 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Wed, 19 Feb 2025 15:06:11 -0800 Subject: [PATCH 18/25] rename tests --- .../testthat/{test-dist_quantiles.R => test-quantile_pred.R} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename tests/testthat/{test-dist_quantiles.R => test-quantile_pred.R} (96%) diff --git a/tests/testthat/test-dist_quantiles.R b/tests/testthat/test-quantile_pred.R similarity index 96% rename from tests/testthat/test-dist_quantiles.R rename to tests/testthat/test-quantile_pred.R index 18fe92ed2..d7c7cc4cb 100644 --- a/tests/testthat/test-dist_quantiles.R +++ b/tests/testthat/test-quantile_pred.R @@ -12,7 +12,7 @@ test_that("single quantile_pred works, quantiles are accessible", { ) Q <- stats::splinefun(c(.2, .4, .5, .6, .8), 1:5, method = "hyman") - expect_equal(quantile(z, c(.3, .7)), Q(c(.3, .7))) + expect_equal(quantile(z, c(.3, .7)), matrix(Q(c(.3, .7)), nrow = 1)) expect_identical( extrapolate_quantiles(z, c(.3, .7), middle = "linear"), hardhat::quantile_pred(matrix(c(1, 1.5, 2, 3, 4, 4.5, 5), nrow = 1), 2:8 / 10) @@ -101,5 +101,5 @@ test_that("arithmetic works on quantiles", { expect_identical(dstn / 4, dstn2) expect_identical((1 / 4) * dstn, dstn2) - expect_error(sum(dstn)) + expect_snapshot(error = TRUE, sum(dstn)) }) From 54eb81c4b5d80d2bd2ec4bd51c21d573fc09dff5 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Wed, 19 Feb 2025 15:06:59 -0800 Subject: [PATCH 19/25] quantile pred tests pass --- tests/testthat/_snaps/quantile_pred.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/testthat/_snaps/quantile_pred.md diff --git a/tests/testthat/_snaps/quantile_pred.md b/tests/testthat/_snaps/quantile_pred.md new file mode 100644 index 000000000..dd13dcb86 --- /dev/null +++ b/tests/testthat/_snaps/quantile_pred.md @@ -0,0 +1,8 @@ +# arithmetic works on quantiles + + Code + sum(dstn) + Condition + Error in `vec_math()`: + ! `sum()` is not a supported operation for . + From 0c08cf29e10a125403c3690b89eaafe86e840d6c Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Wed, 19 Feb 2025 15:08:46 -0800 Subject: [PATCH 20/25] updates to WIS --- NAMESPACE | 5 +- R/weighted_interval_score.R | 100 +++++++++++---------------------- man/weighted_interval_score.Rd | 19 ++----- 3 files changed, 38 insertions(+), 86 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index eefe36d05..97644fda7 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -117,10 +117,7 @@ S3method(vec_arith,quantile_pred) S3method(vec_arith.numeric,quantile_pred) S3method(vec_arith.quantile_pred,numeric) S3method(vec_math,quantile_pred) -S3method(weighted_interval_score,default) -S3method(weighted_interval_score,dist_default) -S3method(weighted_interval_score,dist_quantiles) -S3method(weighted_interval_score,distribution) +S3method(weighted_interval_score,quantile_pred) export("%>%") export(Add_model) export(Remove_model) diff --git a/R/weighted_interval_score.R b/R/weighted_interval_score.R index 48741de7d..567ae4e69 100644 --- a/R/weighted_interval_score.R +++ b/R/weighted_interval_score.R @@ -13,6 +13,16 @@ #' @param actual double. Actual value(s) #' @param quantile_levels probabilities. If specified, the score will be #' computed at this set of levels. +#' @param na_handling character. Determines how `quantile_levels` without a +#' corresponding `value` are handled. For `"impute"`, missing values will be +#' calculated if possible using the available quantiles. For `"drop"`, +#' explicitly missing values are ignored in the calculation of the score, but +#' implicitly missing values are imputed if possible. +#' For `"propogate"`, the resulting score will be `NA` if any missing values +#' exist in the original `quantile_levels`. Finally, if +#' `quantile_levels` is specified, `"fail"` will result in +#' the score being `NA` when any required quantile levels (implicit or explicit) +#' are do not have corresponding values. #' @param ... not used #' #' @return a vector of nonnegative scores. @@ -44,13 +54,13 @@ #' #' # Using some actual forecasts -------- #' library(dplyr) -#' jhu <- covid_case_death_rates %>% +#' jhu <- case_death_rate_subset %>% #' filter(time_value >= "2021-10-01", time_value <= "2021-12-01") #' preds <- flatline_forecaster( #' jhu, "death_rate", #' flatline_args_list(quantile_levels = c(.01, .025, 1:19 / 20, .975, .99)) #' )$predictions -#' actuals <- covid_case_death_rates %>% +#' actuals <- case_death_rate_subset %>% #' filter(time_value == as.Date("2021-12-01") + 7) %>% #' select(geo_value, time_value, actual = death_rate) #' preds <- left_join(preds, actuals, @@ -58,90 +68,44 @@ #' ) %>% #' mutate(wis = weighted_interval_score(.pred_distn, actual)) #' preds -weighted_interval_score <- function(x, actual, quantile_levels = NULL, ...) { +weighted_interval_score <- function( + x, + actual, + quantile_levels = NULL, + na_handling = c("impute", "drop", "propagate", "fail"), + ...) { UseMethod("weighted_interval_score") } -#' @export -weighted_interval_score.default <- function(x, actual, - quantile_levels = NULL, ...) { - cli_abort(c( - "Weighted interval score can only be calculated if `x`", - "has class {.cls distribution}." - )) -} - -#' @export -weighted_interval_score.distribution <- function( - x, actual, - quantile_levels = NULL, ...) { - assert_numeric(actual, finite = TRUE) - l <- vctrs::vec_recycle_common(x = x, actual = actual) - map2_dbl( - .x = vctrs::vec_data(l$x), - .y = l$actual, - .f = weighted_interval_score, - quantile_levels = quantile_levels, - ... - ) -} - -#' @export -weighted_interval_score.dist_default <- function(x, actual, - quantile_levels = NULL, ...) { - rlang::check_dots_empty() - if (is.null(quantile_levels)) { - cli_warn(c( - "Weighted interval score isn't implemented for {.cls {class(x)}}", - "as we don't know what set of quantile levels to use.", - "Use a {.cls dist_quantiles} or pass `quantile_levels`.", - "The result for this element will be `NA`." - )) - return(NA) - } - x <- extrapolate_quantiles(x, probs = quantile_levels) - weighted_interval_score(x, actual, quantile_levels = NULL) -} -#' @param na_handling character. Determines how `quantile_levels` without a -#' corresponding `value` are handled. For `"impute"`, missing values will be -#' calculated if possible using the available quantiles. For `"drop"`, -#' explicitly missing values are ignored in the calculation of the score, but -#' implicitly missing values are imputed if possible. -#' For `"propogate"`, the resulting score will be `NA` if any missing values -#' exist in the original `quantile_levels`. Finally, if -#' `quantile_levels` is specified, `"fail"` will result in -#' the score being `NA` when any required quantile levels (implicit or explicit) -#' are do not have corresponding values. -#' @describeIn weighted_interval_score Weighted interval score with -#' `dist_quantiles` allows for different `NA` behaviours. #' @export -weighted_interval_score.dist_quantiles <- function( +weighted_interval_score.quantile_pred <- function( x, actual, quantile_levels = NULL, na_handling = c("impute", "drop", "propagate", "fail"), ...) { rlang::check_dots_empty() - if (is.na(actual)) { - return(NA) - } - if (all(is.na(vctrs::field(x, "values")))) { - return(NA) - } + n <- vctrs::vec_size(x) + if (length(actual) == 1L) actual <- rep(actual, n) + assert_numeric(actual, finite = TRUE, len = n) + assert_numeric(quantile_levels, lower = 0, upper = 1, null.ok = TRUE) na_handling <- rlang::arg_match(na_handling) - old_quantile_levels <- field(x, "quantile_levels") + old_quantile_levels <- x %@% "quantile_levels" if (na_handling == "fail") { if (is.null(quantile_levels)) { cli_abort('`na_handling = "fail"` requires `quantile_levels` to be specified.') } - old_values <- field(x, "values") - if (!all(quantile_levels %in% old_quantile_levels) || any(is.na(old_values))) { - return(NA) + if (!all(quantile_levels %in% old_quantile_levels)) { + return(rep(NA_real_, n)) } } tau <- quantile_levels %||% old_quantile_levels - x <- extrapolate_quantiles(x, probs = tau, replace_na = (na_handling == "impute")) - q <- field(x, "values")[field(x, "quantile_levels") %in% tau] + x <- extrapolate_quantiles(x, tau, replace_na = (na_handling == "impute")) + x <- as.matrix(x)[, attr(x, "quantile_levels") %in% tau] na_rm <- (na_handling == "drop") + map2_dbl(vctrs::vec_chop(x), actual, ~ wis_one_quantile(.x, tau, .y, na_rm)) +} + +wis_one_quantile <- function(q, tau, actual, na_rm) { 2 * mean(pmax(tau * (actual - q), (1 - tau) * (q - actual)), na.rm = na_rm) } diff --git a/man/weighted_interval_score.Rd b/man/weighted_interval_score.Rd index 4aac20e7d..4b7c796ea 100644 --- a/man/weighted_interval_score.Rd +++ b/man/weighted_interval_score.Rd @@ -2,12 +2,9 @@ % Please edit documentation in R/weighted_interval_score.R \name{weighted_interval_score} \alias{weighted_interval_score} -\alias{weighted_interval_score.dist_quantiles} \title{Compute weighted interval score} \usage{ -weighted_interval_score(x, actual, quantile_levels = NULL, ...) - -\method{weighted_interval_score}{dist_quantiles}( +weighted_interval_score( x, actual, quantile_levels = NULL, @@ -25,8 +22,6 @@ contains \code{dist_quantiles()}, though other distributions are supported when \item{quantile_levels}{probabilities. If specified, the score will be computed at this set of levels.} -\item{...}{not used} - \item{na_handling}{character. Determines how \code{quantile_levels} without a corresponding \code{value} are handled. For \code{"impute"}, missing values will be calculated if possible using the available quantiles. For \code{"drop"}, @@ -37,6 +32,8 @@ exist in the original \code{quantile_levels}. Finally, if \code{quantile_levels} is specified, \code{"fail"} will result in the score being \code{NA} when any required quantile levels (implicit or explicit) are do not have corresponding values.} + +\item{...}{not used} } \value{ a vector of nonnegative scores. @@ -48,12 +45,6 @@ approximation of the commonly-used continuous ranked probability score generalization of absolute error. For example, see \href{https://arxiv.org/abs/2005.12881}{Bracher et al. (2020)} for discussion in the context of COVID-19 forecasting. } -\section{Methods (by class)}{ -\itemize{ -\item \code{weighted_interval_score(dist_quantiles)}: Weighted interval score with -\code{dist_quantiles} allows for different \code{NA} behaviours. - -}} \examples{ quantile_levels <- c(.2, .4, .6, .8) predq_1 <- 1:4 # @@ -80,13 +71,13 @@ weighted_interval_score(dist_quantiles(1:4, 1:4 / 5), 2.5, 1:9 / 10, # Using some actual forecasts -------- library(dplyr) -jhu <- covid_case_death_rates \%>\% +jhu <- case_death_rate_subset \%>\% filter(time_value >= "2021-10-01", time_value <= "2021-12-01") preds <- flatline_forecaster( jhu, "death_rate", flatline_args_list(quantile_levels = c(.01, .025, 1:19 / 20, .975, .99)) )$predictions -actuals <- covid_case_death_rates \%>\% +actuals <- case_death_rate_subset \%>\% filter(time_value == as.Date("2021-12-01") + 7) \%>\% select(geo_value, time_value, actual = death_rate) preds <- left_join(preds, actuals, From 8f31f778bb7b25f02e41e250c051240b5a12faad Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Wed, 19 Feb 2025 15:55:16 -0800 Subject: [PATCH 21/25] remove the distributional package --- DESCRIPTION | 2 +- NAMESPACE | 7 +- R/autoplot.R | 2 +- R/extrapolate_quantiles.R | 32 ++-- R/flusight_hub_formatter.R | 7 +- R/layer_cdc_flatline_quantiles.R | 7 +- R/layer_predictive_distn.R | 6 + R/layer_quantile_distn.R | 20 ++- R/layer_residual_quantiles.R | 15 +- R/layer_threshold_preds.R | 27 +-- R/make_grf_quantiles.R | 4 +- R/make_quantile_reg.R | 20 +-- R/make_smooth_quantile_reg.R | 4 +- R/pivot_quantiles.R | 158 +++++------------- R/quantile_pred-methods.R | 14 +- R/weighted_interval_score.R | 34 ++-- man/extrapolate_quantiles.Rd | 32 ++-- man/layer_cdc_flatline_quantiles.Rd | 2 +- man/nested_quantiles.Rd | 26 --- man/pivot_quantiles_longer.Rd | 26 +-- man/pivot_quantiles_wider.Rd | 20 +-- man/smooth_quantile_reg.Rd | 2 +- man/weighted_interval_score.Rd | 32 ++-- tests/testthat/_snaps/pivot_quantiles.md | 33 ++-- tests/testthat/_snaps/wis-quantile_pred.md | 16 ++ .../testthat/test-layer_residual_quantiles.R | 6 +- tests/testthat/test-layer_threshold_preds.R | 9 +- tests/testthat/test-pivot_quantiles.R | 72 +++----- ...t-quantiles.R => test-wis-quantile_pred.R} | 27 ++- 29 files changed, 244 insertions(+), 418 deletions(-) delete mode 100644 man/nested_quantiles.Rd create mode 100644 tests/testthat/_snaps/wis-quantile_pred.md rename tests/testthat/{test-wis-dist-quantiles.R => test-wis-quantile_pred.R} (65%) diff --git a/DESCRIPTION b/DESCRIPTION index 9b62b1749..b2ac37755 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -31,7 +31,6 @@ Depends: Imports: checkmate, cli, - distributional, dplyr, generics, ggplot2, @@ -50,6 +49,7 @@ Imports: workflows (>= 1.0.0) Suggests: data.table, + distributional, epidatr (>= 1.0.0), fs, grf, diff --git a/NAMESPACE b/NAMESPACE index 97644fda7..0e944941a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -106,9 +106,7 @@ S3method(slather,layer_residual_quantiles) S3method(slather,layer_threshold) S3method(slather,layer_unnest) S3method(snap,default) -S3method(snap,dist_default) -S3method(snap,dist_quantiles) -S3method(snap,distribution) +S3method(snap,quantile_pred) S3method(tidy,check_enough_train_data) S3method(tidy,frosting) S3method(tidy,layer) @@ -174,7 +172,6 @@ export(layer_quantile_distn) export(layer_residual_quantiles) export(layer_threshold) export(layer_unnest) -export(nested_quantiles) export(new_default_epi_recipe_blueprint) export(new_epi_recipe_blueprint) export(pivot_quantiles_longer) @@ -187,6 +184,7 @@ export(remove_frosting) export(remove_model) export(slather) export(smooth_quantile_reg) +export(snap) export(step_adjust_latency) export(step_epi_ahead) export(step_epi_lag) @@ -259,6 +257,7 @@ importFrom(ggplot2,geom_point) importFrom(ggplot2,geom_ribbon) importFrom(glue,glue) importFrom(hardhat,extract_recipe) +importFrom(hardhat,quantile_pred) importFrom(hardhat,refresh_blueprint) importFrom(hardhat,run_mold) importFrom(magrittr,"%>%") diff --git a/R/autoplot.R b/R/autoplot.R index c0e3c68dd..cbe74049e 100644 --- a/R/autoplot.R +++ b/R/autoplot.R @@ -243,7 +243,7 @@ plot_bands <- function( ntarget_dates <- dplyr::n_distinct(predictions$time_value) predictions <- predictions %>% - mutate(.pred_distn = dist_quantiles(quantile(.pred_distn, levels), levels)) %>% + mutate(.pred_distn = quantile_pred(quantile(.pred_distn, levels), levels)) %>% pivot_quantiles_wider(.pred_distn) qnames <- setdiff(names(predictions), innames) diff --git a/R/extrapolate_quantiles.R b/R/extrapolate_quantiles.R index d9e899ef6..82116c1d3 100644 --- a/R/extrapolate_quantiles.R +++ b/R/extrapolate_quantiles.R @@ -1,32 +1,26 @@ #' Summarize a distribution with a set of quantiles #' -#' @param x a `distribution` vector +#' This function takes a `quantile_pred` vector and returns the same +#' type of object, expanded to include +#' *additional* quantiles computed at `probs`. If you want behaviour more +#' similar to [stats::quantile()], then `quantile(x,...)` may be more +#' appropriate. +#' +#' @param x A vector of class `quantile_pred`. #' @param probs a vector of probabilities at which to calculate quantiles #' @param replace_na logical. If `x` contains `NA`'s, these are imputed if -#' possible (if `TRUE`) or retained (if `FALSE`). This only effects -#' elements of class `dist_quantiles`. +#' possible (if `TRUE`) or retained (if `FALSE`). #' @param ... additional arguments passed on to the `quantile` method #' -#' @return a `distribution` vector containing `dist_quantiles`. Any elements -#' of `x` which were originally `dist_quantiles` will now have a superset +#' @return a `quantile_pred` vector. Each element +#' of `x` will now have a superset #' of the original `quantile_values` (the union of those and `probs`). #' @export #' #' @examples -#' library(distributional) -#' dstn <- dist_normal(c(10, 2), c(5, 10)) -#' extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75)) -#' -#' dstn <- dist_quantiles(list(1:4, 8:11), list(c(.2, .4, .6, .8))) -#' # because this distribution is already quantiles, any extra quantiles are -#' # appended -#' extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75)) -#' -#' dstn <- c( -#' dist_normal(c(10, 2), c(5, 10)), -#' dist_quantiles(list(1:4, 8:11), list(c(.2, .4, .6, .8))) -#' ) -#' extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75)) +#' dstn <- quantile_dstn(rbind(1:4, 8:11), c(.2, .4, .6, .8)) +#' # extra quantiles are appended +#' as.tibble(extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75))) extrapolate_quantiles <- function(x, probs, replace_na = TRUE, ...) { UseMethod("extrapolate_quantiles") } diff --git a/R/flusight_hub_formatter.R b/R/flusight_hub_formatter.R index b3e31822c..9e16019d1 100644 --- a/R/flusight_hub_formatter.R +++ b/R/flusight_hub_formatter.R @@ -103,12 +103,11 @@ flusight_hub_formatter.data.frame <- function( object <- object %>% # combine the predictions and the distribution - mutate(.pred_distn = nested_quantiles(.pred_distn)) %>% - tidyr::unnest(.pred_distn) %>% + pivot_quantiles_longer(.pred_distn) %>% # now we create the correct column names rename( - value = values, - output_type_id = quantile_levels, + value = .pred_distn_value, + output_type_id = .pred_distn_quantile_level, reference_date = forecast_date ) %>% # convert to fips codes, and add any constant cols passed in ... diff --git a/R/layer_cdc_flatline_quantiles.R b/R/layer_cdc_flatline_quantiles.R index 13938d837..c85230f93 100644 --- a/R/layer_cdc_flatline_quantiles.R +++ b/R/layer_cdc_flatline_quantiles.R @@ -51,7 +51,7 @@ #' in an additional `` named `.pred_distn_all` containing 2-column #' [tibble::tibble()]'s. For each #' desired combination of `key`'s, the tibble will contain one row per ahead -#' with the associated [dist_quantiles()]. +#' with the associated [quantile_pred()]. #' @export #' #' @examples @@ -266,11 +266,10 @@ propagate_samples <- function( } } res <- res[aheads] + res_quantiles <- map(res, quantile, probs = quantile_levels) list(tibble( ahead = aheads, - .pred_distn = map_vec( - res, ~ dist_quantiles(quantile(.x, quantile_levels), quantile_levels) - ) + .pred_distn = quantile_pred(do.call(rbind, res_quantiles), quantile_levels) )) } diff --git a/R/layer_predictive_distn.R b/R/layer_predictive_distn.R index 2b18fbf8e..8ce55e1c3 100644 --- a/R/layer_predictive_distn.R +++ b/R/layer_predictive_distn.R @@ -45,6 +45,12 @@ layer_predictive_distn <- function(frosting, truncate = c(-Inf, Inf), name = ".pred_distn", id = rand_id("predictive_distn")) { + if (!requireNamespace("distributional", quietly = TRUE)) { + cli_abort(paste( + "You must install the {.pkg distributional} package for", + "this functionality." + )) + } rlang::check_dots_empty() arg_is_chr_scalar(name, id) dist_type <- match.arg(dist_type) diff --git a/R/layer_quantile_distn.R b/R/layer_quantile_distn.R index b39b58f4a..9cec6ac41 100644 --- a/R/layer_quantile_distn.R +++ b/R/layer_quantile_distn.R @@ -79,15 +79,23 @@ layer_quantile_distn_new <- function(quantile_levels, truncate, name, id) { slather.layer_quantile_distn <- function(object, components, workflow, new_data, ...) { dstn <- components$predictions$.pred - if (!inherits(dstn, "distribution")) { - cli_abort(c( - "`layer_quantile_distn()` requires distributional predictions.", - "These are of class {.cls {class(dstn)}}." - )) + is_supported <- inherits(dstn, "distribution") || + inherits(dstn, "quantile_pred") + if (!is_supported) { + cli_abort( + "`layer_quantile_distn()` requires distributional or quantile + predictions. These are of class {.cls {class(dstn)}}." + ) + } + if (inherits(dstn, "distribution") && !requireNamespace("distributional", quietly = TRUE)) { + cli_abort( + "You must install the {.pkg distributional} package for this + functionality." + ) } rlang::check_dots_empty() - dstn <- dist_quantiles( + dstn <- quantile_pred( quantile(dstn, object$quantile_levels), object$quantile_levels ) diff --git a/R/layer_residual_quantiles.R b/R/layer_residual_quantiles.R index 96ad88411..28076b69a 100644 --- a/R/layer_residual_quantiles.R +++ b/R/layer_residual_quantiles.R @@ -126,14 +126,11 @@ slather.layer_residual_quantiles <- } r <- r %>% - summarise( - dstn = list(quantile( - c(.resid, s * .resid), - probs = object$quantile_levels, na.rm = TRUE - )) - ) + summarize(dstn = quantile_pred(matrix(quantile( + c(.resid, s * .resid), probs = object$quantile_levels, na.rm = TRUE + ), nrow = 1), quantile_levels = object$quantile_levels)) # Check for NA - if (any(sapply(r$dstn, is.na))) { + if (anyNA(as.matrix(r$dstn))) { cli_abort(c( "Residual quantiles could not be calculated due to missing residuals.", i = "This may be due to `n_train` < `ahead` in your {.cls epi_recipe}." @@ -141,9 +138,7 @@ slather.layer_residual_quantiles <- } estimate <- components$predictions$.pred - res <- tibble( - .pred_distn = dist_quantiles(map2(estimate, r$dstn, "+"), object$quantile_levels) - ) + res <- tibble(.pred_distn = r$dstn + estimate) res <- check_pname(res, components$predictions, object) components$predictions <- mutate(components$predictions, !!!res) components diff --git a/R/layer_threshold_preds.R b/R/layer_threshold_preds.R index 7b8ca0252..bdc334b63 100644 --- a/R/layer_threshold_preds.R +++ b/R/layer_threshold_preds.R @@ -59,8 +59,7 @@ layer_threshold_new <- layer("threshold", terms = terms, lower = lower, upper = upper, id = id) } - - +#' @export snap <- function(x, lower, upper, ...) { UseMethod("snap") } @@ -73,25 +72,11 @@ snap.default <- function(x, lower, upper, ...) { } #' @export -snap.distribution <- function(x, lower, upper, ...) { - rlang::check_dots_empty() - arg_is_scalar(lower, upper) - dstn <- lapply(vec_data(x), snap, lower = lower, upper = upper) - distributional:::wrap_dist(dstn) -} - -#' @export -snap.dist_default <- function(x, lower, upper, ...) { - rlang::check_dots_empty() - x -} - -#' @export -snap.dist_quantiles <- function(x, lower, upper, ...) { - values <- field(x, "values") - quantile_levels <- field(x, "quantile_levels") - values <- snap(values, lower, upper) - new_quantiles(values = values, quantile_levels = quantile_levels) +snap.quantile_pred <- function(x, lower, upper, ...) { + values <- as.matrix(x) + quantile_levels <- x %@% "quantile_levels" + values <- map(vctrs::vec_chop(values), ~ snap(.x, lower, upper)) + quantile_pred(do.call(rbind, values), quantile_levels = quantile_levels) } #' @export diff --git a/R/make_grf_quantiles.R b/R/make_grf_quantiles.R index fbd221d22..0b40da321 100644 --- a/R/make_grf_quantiles.R +++ b/R/make_grf_quantiles.R @@ -163,12 +163,12 @@ make_grf_quantiles <- function() { ) ) - # turn the predictions into a tibble with a dist_quantiles column + # turn the predictions into a tibble with a quantile_pred column process_qrf_preds <- function(x, object) { quantile_levels <- parsnip::extract_fit_engine(object)$quantiles.orig %>% sort() x <- x$predictions out <- lapply(vctrs::vec_chop(x), function(x) sort(drop(x))) - out <- dist_quantiles(out, list(quantile_levels)) + out <- hardhat::quantile_pred(do.call(rbind, out), quantile_levels) return(dplyr::tibble(.pred = out)) } diff --git a/R/make_quantile_reg.R b/R/make_quantile_reg.R index 223881c85..bc2d322bf 100644 --- a/R/make_quantile_reg.R +++ b/R/make_quantile_reg.R @@ -110,21 +110,11 @@ make_quantile_reg <- function() { process_rq_preds <- function(x, object) { object <- parsnip::extract_fit_engine(object) - type <- class(object)[1] - - # can't make a method because object is second - out <- switch(type, - rq = dist_quantiles(unname(as.list(x)), object$tau), # one quantile - rqs = { - x <- lapply(vctrs::vec_chop(x), function(x) sort(drop(x))) - dist_quantiles(x, list(object$tau)) - }, - cli_abort(c( - "Prediction is not implemented for this `rq` type.", - i = "See {.fun quantreg::rq}." - )) - ) - return(dplyr::tibble(.pred = out)) + if (!is.matrix(x)) x <- as.matrix(x) + rownames(x) <- NULL + n_pred_quantiles <- ncol(x) + quantile_levels <- object$tau + tibble(.pred = hardhat::quantile_pred(x, quantile_levels)) } parsnip::set_pred( diff --git a/R/make_smooth_quantile_reg.R b/R/make_smooth_quantile_reg.R index f31ade3cb..b5081129f 100644 --- a/R/make_smooth_quantile_reg.R +++ b/R/make_smooth_quantile_reg.R @@ -49,7 +49,7 @@ #' x = x[length(x) - 20] + ahead / 100 * 2 * pi, #' ahead = NULL #' ) %>% -#' pivot_wider(names_from = quantile_levels, values_from = values) +#' pivot_wider(names_from = distn_quantile_levels, values_from = distn_value) #' plot(x, y, pch = 16, xlim = c(pi, 2 * pi), col = "lightgrey") #' curve(sin(x), add = TRUE) #' abline(v = fd, lty = 2) @@ -173,7 +173,7 @@ make_smooth_quantile_reg <- function() { x <- lapply(unname(split( p, seq(nrow(p)) )), function(q) unname(sort(q, na.last = TRUE))) - dist_quantiles(x, list(object$tau)) + quantile_pred(do.call(rbind, x), object$tau) }) n_preds <- length(list_of_pred_distns[[1]]) nout <- length(list_of_pred_distns) diff --git a/R/pivot_quantiles.R b/R/pivot_quantiles.R index 2a9e0d4e0..37f08b46f 100644 --- a/R/pivot_quantiles.R +++ b/R/pivot_quantiles.R @@ -1,146 +1,65 @@ -#' Turn a vector of quantile distributions into a list-col +#' Pivot a column containing `quantile_pred` longer #' -#' @param x a `distribution` containing `dist_quantiles` -#' -#' @return a list-col -#' @export -#' -#' @examples -#' library(dplyr) -#' library(tidyr) -#' edf <- covid_case_death_rates[1:3, ] -#' edf$q <- dist_quantiles(list(1:5, 2:4, 3:10), list(1:5 / 6, 2:4 / 5, 3:10 / 11)) -#' -#' edf_nested <- edf %>% mutate(q = nested_quantiles(q)) -#' edf_nested %>% unnest(q) -nested_quantiles <- function(x) { - stopifnot(is_dist_quantiles(x)) - distributional:::dist_apply(x, .f = function(z) { - as_tibble(vec_data(z)) %>% - mutate(across(everything(), as.double)) %>% - vctrs::list_of() - }) -} - - -#' Pivot columns containing `dist_quantile` longer -#' -#' Selected columns that contain `dist_quantiles` will be "lengthened" with +#' A column that contains `quantile_pred` will be "lengthened" with #' the quantile levels serving as 1 column and the values as another. If #' multiple columns are selected, these will be prefixed with the column name. #' #' @param .data A data frame, or a data frame extension such as a tibble or #' epi_df. -#' @param ... <[`tidy-select`][dplyr::dplyr_tidy_select]> One or more unquoted +#' @param ... <[`tidy-select`][dplyr::dplyr_tidy_select]> One unquoted #' expressions separated by commas. Variable names can be used as if they -#' were positions in the data frame, so expressions like `x:y` can -#' be used to select a range of variables. -#' @param .ignore_length_check If multiple columns are selected, as long as -#' each row has contains the same number of quantiles, the result will be -#' reasonable. But if, for example, `var1[1]` has 5 quantiles while `var2[1]` -#' has 7, then the only option would be to recycle everything, creating a -#' _very_ long result. By default, this would throw an error. But if this is -#' really the goal, then the error can be bypassed by setting this argument -#' to `TRUE`. The quantiles in the first selected column will vary the fastest. +#' were positions in the data frame. Note that only one variable +#' can be selected for this operation. #' #' @return An object of the same class as `.data`. #' @export #' #' @examples -#' d1 <- c(dist_quantiles(1:3, 1:3 / 4), dist_quantiles(2:4, 1:3 / 4)) -#' d2 <- c(dist_quantiles(2:4, 2:4 / 5), dist_quantiles(3:5, 2:4 / 5)) +#' d1 <- quantile_pred(rbind(1:3, 2:4), 1:3 / 4) +#' d2 <- quantile_pred(rbind(2:4, 3:5), 2:4 / 5) #' tib <- tibble(g = c("a", "b"), d1 = d1, d2 = d2) #' #' pivot_quantiles_longer(tib, "d1") #' pivot_quantiles_longer(tib, dplyr::ends_with("1")) -#' pivot_quantiles_longer(tib, d1, d2) -pivot_quantiles_longer <- function(.data, ..., .ignore_length_check = FALSE) { - cols <- validate_pivot_quantiles(.data, ...) - .data <- .data %>% mutate(across(all_of(cols), nested_quantiles)) - if (length(cols) > 1L) { - lengths_check <- .data %>% - dplyr::transmute(across(all_of(cols), ~ map_int(.x, vctrs::vec_size))) %>% - as.matrix() %>% - apply(1, function(x) dplyr::n_distinct(x) == 1L) %>% - all() - if (lengths_check) { - .data <- tidyr::unnest(.data, all_of(cols), names_sep = "_") - } else { - if (.ignore_length_check) { - for (col in cols) { - .data <- .data %>% tidyr::unnest(all_of(col), names_sep = "_") - } - } else { - cli_abort(paste( - "Some selected columns contain different numbers of quantiles.", - "The result would be a {.emph very} long {.cls tibble}.", - "To do this anyway, rerun with `.ignore_length_check = TRUE`." - )) - } - } - } else { - .data <- .data %>% tidyr::unnest(all_of(cols)) - } - .data +#' pivot_quantiles_longer(tib, d2) +pivot_quantiles_longer <- function(.data, ...) { + col <- validate_pivot_quantiles(.data, ...) + .data$.row <- seq_len(vctrs::vec_size(.data)) + long_tib <- as_tibble(.data[[col]]) + .data <- select(.data, !all_of(col)) + names(long_tib)[1:2] <- c(glue::glue("{col}_value"), glue::glue("{col}_quantile_level")) + left_join(.data, long_tib, by = ".row") %>% + select(!.row) } -#' Pivot columns containing `dist_quantile` wider +#' Pivot a column containing `quantile_pred` wider #' -#' Any selected columns that contain `dist_quantiles` will be "widened" with +#' Any selected columns that contain `quantile_pred` will be "widened" with #' the "taus" (quantile) serving as names and the values in the data frame. #' When pivoting multiple columns, the original column name will be used as #' a prefix. #' -#' @param .data A data frame, or a data frame extension such as a tibble or -#' epi_df. -#' @param ... <[`tidy-select`][dplyr::dplyr_tidy_select]> One or more unquoted -#' expressions separated by commas. Variable names can be used as if they -#' were positions in the data frame, so expressions like `x:y` can -#' be used to select a range of variables. +#' @inheritParams pivot_quantiles_longer #' #' @return An object of the same class as `.data` #' @export #' #' @examples -#' d1 <- c(dist_quantiles(1:3, 1:3 / 4), dist_quantiles(2:4, 1:3 / 4)) -#' d2 <- c(dist_quantiles(2:4, 2:4 / 5), dist_quantiles(3:5, 2:4 / 5)) -#' tib <- tibble::tibble(g = c("a", "b"), d1 = d1, d2 = d2) +#' d1 <- quantile_pred(rbind(1:3, 2:4), 1:3 / 4) +#' d2 <- quantile_pred(rbind(2:4, 3:5), 2:4 / 5) +#' tib <- tibble(g = c("a", "b"), d1 = d1, d2 = d2) #' -#' pivot_quantiles_wider(tib, c("d1", "d2")) -#' pivot_quantiles_wider(tib, dplyr::starts_with("d")) +#' pivot_quantiles_wider(tib, "d1") +#' pivot_quantiles_wider(tib, dplyr::ends_with("2")) #' pivot_quantiles_wider(tib, d2) pivot_quantiles_wider <- function(.data, ...) { - cols <- validate_pivot_quantiles(.data, ...) - .data <- .data %>% mutate(across(all_of(cols), nested_quantiles)) - checks <- map_lgl(cols, ~ diff(range(vctrs::list_sizes(.data[[.x]]))) == 0L) - if (!all(checks)) { - nms <- cols[!checks] - cli_abort(c( - "Quantiles must be the same length and have the same set of taus.", - i = "Check failed for variables(s) {.var {nms}}." - )) - } - - # tidyr::pivot_wider can crash if there are duplicates, this generally won't - # happen in our context. To avoid, silently add an index column and remove it - # later - .hidden_index <- seq_len(nrow(.data)) - .data <- tibble::add_column(.data, .hidden_index = .hidden_index) - if (length(cols) > 1L) { - for (col in cols) { - .data <- .data %>% - tidyr::unnest(all_of(col)) %>% - tidyr::pivot_wider( - names_from = "quantile_levels", values_from = "values", - names_prefix = paste0(col, "_") - ) - } - } else { - .data <- .data %>% - tidyr::unnest(all_of(cols)) %>% - tidyr::pivot_wider(names_from = "quantile_levels", values_from = "values") - } - select(.data, -.hidden_index) + col <- validate_pivot_quantiles(.data, ...) + .data$.row <- seq_len(vctrs::vec_size(.data)) + wide_tib <- as_tibble(.data[[col]]) %>% + tidyr::pivot_wider(names_from = .quantile_levels, values_from = .pred_quantile) + .data <- select(.data, !all_of(col)) + left_join(.data, wide_tib, by = ".row") %>% + select(!.row) } pivot_quantiles <- function(.data, ...) { @@ -151,14 +70,19 @@ pivot_quantiles <- function(.data, ...) { lifecycle::deprecate_stop(msg) } -validate_pivot_quantiles <- function(.data, ...) { +validate_pivot_quantiles <- function(.data, ..., call = caller_env()) { expr <- rlang::expr(c(...)) cols <- names(tidyselect::eval_select(expr, .data)) - dqs <- map_lgl(cols, ~ is_dist_quantiles(.data[[.x]])) - if (!all(dqs)) { - nms <- cols[!dqs] + if (length(cols) > 1L) { + cli_abort( + "Only one column can be pivotted. Can not pivot all of: {.var {cols}}.", + call = call + ) + } + if (!inherits(.data[[cols]], "quantile_pred")) { cli_abort( - "Variables(s) {.var {nms}} are not `dist_quantiles`. Cannot pivot them." + "{.var {cols}} is not {.cls `quantile_pred`}. Cannot pivot it.", + call = call ) } cols diff --git a/R/quantile_pred-methods.R b/R/quantile_pred-methods.R index 04884ccd0..1f86052d1 100644 --- a/R/quantile_pred-methods.R +++ b/R/quantile_pred-methods.R @@ -1,5 +1,6 @@ # placeholder to avoid errors, but not ideal +#' @importFrom hardhat quantile_pred #' @export mean.quantile_pred <- function(x, na.rm = FALSE, ...) { median(x, ...) @@ -46,6 +47,7 @@ quantile_internal <- function(x, tau_out, middle) { extrapolate_quantiles_single <- function(qvals, tau, tau_out, middle) { qvals_out <- rep(NA, length(tau_out)) good <- !is.na(qvals) + if (!any(good)) return(qvals_out) qvals <- qvals[good] tau <- tau[good] @@ -131,7 +133,7 @@ vec_math.quantile_pred <- function(.fn, .x, ...) { } quantile_levels <- .x %@% "quantile_levels" .x <- as.matrix(.x) - hardhat::quantile_pred(.fn(.x), quantile_levels) + quantile_pred(.fn(.x), quantile_levels) } #' @importFrom vctrs vec_arith vec_arith.numeric @@ -145,14 +147,16 @@ vec_arith.quantile_pred <- function(op, x, y, ...) { #' @method vec_arith.quantile_pred numeric vec_arith.quantile_pred.numeric <- function(op, x, y, ...) { op_fn <- getExportedValue("base", op) - out <- op_fn(as.matrix(x), y) - hardhat::quantile_pred(out, x %@% "quantile_levels") + l <- vctrs::vec_recycle_common(x = x, y = y) + out <- op_fn(as.matrix(l$x), l$y) + quantile_pred(out, x %@% "quantile_levels") } #' @export #' @method vec_arith.numeric quantile_pred vec_arith.numeric.quantile_pred <- function(op, x, y, ...) { op_fn <- getExportedValue("base", op) - out <- op_fn(x, as.matrix(y)) - hardhat::quantile_pred(out, y %@% "quantile_levels") + l <- vctrs::vec_recycle_common(x = x, y = y) + out <- op_fn(l$x, as.matrix(l$y)) + quantile_pred(out, y %@% "quantile_levels") } diff --git a/R/weighted_interval_score.R b/R/weighted_interval_score.R index 567ae4e69..aa0c816a3 100644 --- a/R/weighted_interval_score.R +++ b/R/weighted_interval_score.R @@ -7,22 +7,21 @@ #' al. (2020)](https://arxiv.org/abs/2005.12881) for discussion in the context #' of COVID-19 forecasting. #' -#' @param x distribution. A vector of class distribution. Ideally, this vector -#' contains `dist_quantiles()`, though other distributions are supported when -#' `quantile_levels` is specified. See below. +#' @param x A vector of class `quantile_pred`. #' @param actual double. Actual value(s) #' @param quantile_levels probabilities. If specified, the score will be -#' computed at this set of levels. -#' @param na_handling character. Determines how `quantile_levels` without a -#' corresponding `value` are handled. For `"impute"`, missing values will be +#' computed at this set of levels. Otherwise, those present in `x` will be +#' used. +#' @param na_handling character. Determines missing values are handled. +#' For `"impute"`, missing values will be #' calculated if possible using the available quantiles. For `"drop"`, #' explicitly missing values are ignored in the calculation of the score, but #' implicitly missing values are imputed if possible. #' For `"propogate"`, the resulting score will be `NA` if any missing values -#' exist in the original `quantile_levels`. Finally, if +#' exist. Finally, if #' `quantile_levels` is specified, `"fail"` will result in #' the score being `NA` when any required quantile levels (implicit or explicit) -#' are do not have corresponding values. +#' do not have corresponding values. #' @param ... not used #' #' @return a vector of nonnegative scores. @@ -30,24 +29,23 @@ #' @export #' @examples #' quantile_levels <- c(.2, .4, .6, .8) -#' predq_1 <- 1:4 # -#' predq_2 <- 8:11 -#' dstn <- dist_quantiles(list(predq_1, predq_2), quantile_levels) +#' predq1 <- 1:4 # +#' predq2 <- 8:11 +#' dstn <- quantile_pred(rbind(predq1, predq2), quantile_levels) #' actual <- c(3.3, 7.1) #' weighted_interval_score(dstn, actual) #' weighted_interval_score(dstn, actual, c(.25, .5, .75)) #' -#' library(distributional) -#' dstn <- dist_normal(c(.75, 2)) -#' weighted_interval_score(dstn, 1, c(.25, .5, .75)) -#' #' # Missing value behaviours -#' dstn <- dist_quantiles(c(1, 2, NA, 4), 1:4 / 5) +#' dstn <- quantile_pred(matrix(c(1, 2, NA, 4), nrow = 1), 1:4 / 5) #' weighted_interval_score(dstn, 2.5) #' weighted_interval_score(dstn, 2.5, 1:9 / 10) #' weighted_interval_score(dstn, 2.5, 1:9 / 10, na_handling = "drop") #' weighted_interval_score(dstn, 2.5, na_handling = "propagate") -#' weighted_interval_score(dist_quantiles(1:4, 1:4 / 5), 2.5, 1:9 / 10, +#' weighted_interval_score( +#' quantile_pred(matrix(1:4, nrow = 1), 1:4 / 5), +#' actual = 2.5, +#' quantile_levels = 1:9 / 10, #' na_handling = "fail" #' ) #' @@ -101,7 +99,7 @@ weighted_interval_score.quantile_pred <- function( } tau <- quantile_levels %||% old_quantile_levels x <- extrapolate_quantiles(x, tau, replace_na = (na_handling == "impute")) - x <- as.matrix(x)[, attr(x, "quantile_levels") %in% tau] + x <- as.matrix(x)[, attr(x, "quantile_levels") %in% tau, drop = FALSE] na_rm <- (na_handling == "drop") map2_dbl(vctrs::vec_chop(x), actual, ~ wis_one_quantile(.x, tau, .y, na_rm)) } diff --git a/man/extrapolate_quantiles.Rd b/man/extrapolate_quantiles.Rd index 4b1d1282c..b645b85fa 100644 --- a/man/extrapolate_quantiles.Rd +++ b/man/extrapolate_quantiles.Rd @@ -7,37 +7,29 @@ extrapolate_quantiles(x, probs, replace_na = TRUE, ...) } \arguments{ -\item{x}{a \code{distribution} vector} +\item{x}{A vector of class \code{quantile_pred}.} \item{probs}{a vector of probabilities at which to calculate quantiles} \item{replace_na}{logical. If \code{x} contains \code{NA}'s, these are imputed if -possible (if \code{TRUE}) or retained (if \code{FALSE}). This only effects -elements of class \code{dist_quantiles}.} +possible (if \code{TRUE}) or retained (if \code{FALSE}).} \item{...}{additional arguments passed on to the \code{quantile} method} } \value{ -a \code{distribution} vector containing \code{dist_quantiles}. Any elements -of \code{x} which were originally \code{dist_quantiles} will now have a superset +a \code{quantile_pred} vector. Each element +of \code{x} will now have a superset of the original \code{quantile_values} (the union of those and \code{probs}). } \description{ -Summarize a distribution with a set of quantiles +This function takes a \code{quantile_pred} vector and returns the same +type of object, expanded to include +\emph{additional} quantiles computed at \code{probs}. If you want behaviour more +similar to \code{\link[stats:quantile]{stats::quantile()}}, then \code{quantile(x,...)} may be more +appropriate. } \examples{ -library(distributional) -dstn <- dist_normal(c(10, 2), c(5, 10)) -extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75)) - -dstn <- dist_quantiles(list(1:4, 8:11), list(c(.2, .4, .6, .8))) -# because this distribution is already quantiles, any extra quantiles are -# appended -extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75)) - -dstn <- c( - dist_normal(c(10, 2), c(5, 10)), - dist_quantiles(list(1:4, 8:11), list(c(.2, .4, .6, .8))) -) -extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75)) +dstn <- quantile_dstn(rbind(1:4, 8:11), c(.2, .4, .6, .8)) +# extra quantiles are appended +as.tibble(extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75))) } diff --git a/man/layer_cdc_flatline_quantiles.Rd b/man/layer_cdc_flatline_quantiles.Rd index 632fdb65e..3c094b0d8 100644 --- a/man/layer_cdc_flatline_quantiles.Rd +++ b/man/layer_cdc_flatline_quantiles.Rd @@ -62,7 +62,7 @@ an updated \code{frosting} postprocessor. Calling \code{\link[=predict]{predict( in an additional \verb{} named \code{.pred_distn_all} containing 2-column \code{\link[tibble:tibble]{tibble::tibble()}}'s. For each desired combination of \code{key}'s, the tibble will contain one row per ahead -with the associated \code{\link[=dist_quantiles]{dist_quantiles()}}. +with the associated \code{\link[=quantile_pred]{quantile_pred()}}. } \description{ This layer creates quantile forecasts by taking a sample from the diff --git a/man/nested_quantiles.Rd b/man/nested_quantiles.Rd deleted file mode 100644 index 0fa0fe8cc..000000000 --- a/man/nested_quantiles.Rd +++ /dev/null @@ -1,26 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pivot_quantiles.R -\name{nested_quantiles} -\alias{nested_quantiles} -\title{Turn a vector of quantile distributions into a list-col} -\usage{ -nested_quantiles(x) -} -\arguments{ -\item{x}{a \code{distribution} containing \code{dist_quantiles}} -} -\value{ -a list-col -} -\description{ -Turn a vector of quantile distributions into a list-col -} -\examples{ -library(dplyr) -library(tidyr) -edf <- covid_case_death_rates[1:3, ] -edf$q <- dist_quantiles(list(1:5, 2:4, 3:10), list(1:5 / 6, 2:4 / 5, 3:10 / 11)) - -edf_nested <- edf \%>\% mutate(q = nested_quantiles(q)) -edf_nested \%>\% unnest(q) -} diff --git a/man/pivot_quantiles_longer.Rd b/man/pivot_quantiles_longer.Rd index 9879d5d07..b872d0c97 100644 --- a/man/pivot_quantiles_longer.Rd +++ b/man/pivot_quantiles_longer.Rd @@ -2,41 +2,33 @@ % Please edit documentation in R/pivot_quantiles.R \name{pivot_quantiles_longer} \alias{pivot_quantiles_longer} -\title{Pivot columns containing \code{dist_quantile} longer} +\title{Pivot a column containing \code{quantile_pred} longer} \usage{ -pivot_quantiles_longer(.data, ..., .ignore_length_check = FALSE) +pivot_quantiles_longer(.data, ...) } \arguments{ \item{.data}{A data frame, or a data frame extension such as a tibble or epi_df.} -\item{...}{<\code{\link[dplyr:dplyr_tidy_select]{tidy-select}}> One or more unquoted +\item{...}{<\code{\link[dplyr:dplyr_tidy_select]{tidy-select}}> One unquoted expressions separated by commas. Variable names can be used as if they -were positions in the data frame, so expressions like \code{x:y} can -be used to select a range of variables.} - -\item{.ignore_length_check}{If multiple columns are selected, as long as -each row has contains the same number of quantiles, the result will be -reasonable. But if, for example, \code{var1[1]} has 5 quantiles while \code{var2[1]} -has 7, then the only option would be to recycle everything, creating a -\emph{very} long result. By default, this would throw an error. But if this is -really the goal, then the error can be bypassed by setting this argument -to \code{TRUE}. The quantiles in the first selected column will vary the fastest.} +were positions in the data frame. Note that only one variable +can be selected for this operation.} } \value{ An object of the same class as \code{.data}. } \description{ -Selected columns that contain \code{dist_quantiles} will be "lengthened" with +A column that contains \code{quantile_pred} will be "lengthened" with the quantile levels serving as 1 column and the values as another. If multiple columns are selected, these will be prefixed with the column name. } \examples{ -d1 <- c(dist_quantiles(1:3, 1:3 / 4), dist_quantiles(2:4, 1:3 / 4)) -d2 <- c(dist_quantiles(2:4, 2:4 / 5), dist_quantiles(3:5, 2:4 / 5)) +d1 <- quantile_pred(rbind(1:3, 2:4), 1:3 / 4) +d2 <- quantile_pred(rbind(2:4, 3:5), 2:4 / 5) tib <- tibble(g = c("a", "b"), d1 = d1, d2 = d2) pivot_quantiles_longer(tib, "d1") pivot_quantiles_longer(tib, dplyr::ends_with("1")) -pivot_quantiles_longer(tib, d1, d2) +pivot_quantiles_longer(tib, d2) } diff --git a/man/pivot_quantiles_wider.Rd b/man/pivot_quantiles_wider.Rd index e477777ca..01f85a70a 100644 --- a/man/pivot_quantiles_wider.Rd +++ b/man/pivot_quantiles_wider.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/pivot_quantiles.R \name{pivot_quantiles_wider} \alias{pivot_quantiles_wider} -\title{Pivot columns containing \code{dist_quantile} wider} +\title{Pivot a column containing \code{quantile_pred} wider} \usage{ pivot_quantiles_wider(.data, ...) } @@ -10,26 +10,26 @@ pivot_quantiles_wider(.data, ...) \item{.data}{A data frame, or a data frame extension such as a tibble or epi_df.} -\item{...}{<\code{\link[dplyr:dplyr_tidy_select]{tidy-select}}> One or more unquoted +\item{...}{<\code{\link[dplyr:dplyr_tidy_select]{tidy-select}}> One unquoted expressions separated by commas. Variable names can be used as if they -were positions in the data frame, so expressions like \code{x:y} can -be used to select a range of variables.} +were positions in the data frame. Note that only one variable +can be selected for this operation.} } \value{ An object of the same class as \code{.data} } \description{ -Any selected columns that contain \code{dist_quantiles} will be "widened" with +Any selected columns that contain \code{quantile_pred} will be "widened" with the "taus" (quantile) serving as names and the values in the data frame. When pivoting multiple columns, the original column name will be used as a prefix. } \examples{ -d1 <- c(dist_quantiles(1:3, 1:3 / 4), dist_quantiles(2:4, 1:3 / 4)) -d2 <- c(dist_quantiles(2:4, 2:4 / 5), dist_quantiles(3:5, 2:4 / 5)) -tib <- tibble::tibble(g = c("a", "b"), d1 = d1, d2 = d2) +d1 <- quantile_pred(rbind(1:3, 2:4), 1:3 / 4) +d2 <- quantile_pred(rbind(2:4, 3:5), 2:4 / 5) +tib <- tibble(g = c("a", "b"), d1 = d1, d2 = d2) -pivot_quantiles_wider(tib, c("d1", "d2")) -pivot_quantiles_wider(tib, dplyr::starts_with("d")) +pivot_quantiles_wider(tib, "d1") +pivot_quantiles_wider(tib, dplyr::ends_with("2")) pivot_quantiles_wider(tib, d2) } diff --git a/man/smooth_quantile_reg.Rd b/man/smooth_quantile_reg.Rd index 90b2c104f..3ac83d62a 100644 --- a/man/smooth_quantile_reg.Rd +++ b/man/smooth_quantile_reg.Rd @@ -68,7 +68,7 @@ pl <- pl \%>\% x = x[length(x) - 20] + ahead / 100 * 2 * pi, ahead = NULL ) \%>\% - pivot_wider(names_from = quantile_levels, values_from = values) + pivot_wider(names_from = distn_quantile_levels, values_from = distn_value) plot(x, y, pch = 16, xlim = c(pi, 2 * pi), col = "lightgrey") curve(sin(x), add = TRUE) abline(v = fd, lty = 2) diff --git a/man/weighted_interval_score.Rd b/man/weighted_interval_score.Rd index 4b7c796ea..22a616b70 100644 --- a/man/weighted_interval_score.Rd +++ b/man/weighted_interval_score.Rd @@ -13,25 +13,24 @@ weighted_interval_score( ) } \arguments{ -\item{x}{distribution. A vector of class distribution. Ideally, this vector -contains \code{dist_quantiles()}, though other distributions are supported when -\code{quantile_levels} is specified. See below.} +\item{x}{A vector of class \code{quantile_pred}.} \item{actual}{double. Actual value(s)} \item{quantile_levels}{probabilities. If specified, the score will be -computed at this set of levels.} +computed at this set of levels. Otherwise, those present in \code{x} will be +used.} -\item{na_handling}{character. Determines how \code{quantile_levels} without a -corresponding \code{value} are handled. For \code{"impute"}, missing values will be +\item{na_handling}{character. Determines missing values are handled. +For \code{"impute"}, missing values will be calculated if possible using the available quantiles. For \code{"drop"}, explicitly missing values are ignored in the calculation of the score, but implicitly missing values are imputed if possible. For \code{"propogate"}, the resulting score will be \code{NA} if any missing values -exist in the original \code{quantile_levels}. Finally, if +exist. Finally, if \code{quantile_levels} is specified, \code{"fail"} will result in the score being \code{NA} when any required quantile levels (implicit or explicit) -are do not have corresponding values.} +do not have corresponding values.} \item{...}{not used} } @@ -47,24 +46,23 @@ of COVID-19 forecasting. } \examples{ quantile_levels <- c(.2, .4, .6, .8) -predq_1 <- 1:4 # -predq_2 <- 8:11 -dstn <- dist_quantiles(list(predq_1, predq_2), quantile_levels) +predq1 <- 1:4 # +predq2 <- 8:11 +dstn <- quantile_pred(rbind(predq1, predq2), quantile_levels) actual <- c(3.3, 7.1) weighted_interval_score(dstn, actual) weighted_interval_score(dstn, actual, c(.25, .5, .75)) -library(distributional) -dstn <- dist_normal(c(.75, 2)) -weighted_interval_score(dstn, 1, c(.25, .5, .75)) - # Missing value behaviours -dstn <- dist_quantiles(c(1, 2, NA, 4), 1:4 / 5) +dstn <- quantile_pred(matrix(c(1, 2, NA, 4), nrow = 1), 1:4 / 5) weighted_interval_score(dstn, 2.5) weighted_interval_score(dstn, 2.5, 1:9 / 10) weighted_interval_score(dstn, 2.5, 1:9 / 10, na_handling = "drop") weighted_interval_score(dstn, 2.5, na_handling = "propagate") -weighted_interval_score(dist_quantiles(1:4, 1:4 / 5), 2.5, 1:9 / 10, +weighted_interval_score( + quantile_pred(matrix(1:4, nrow = 1), 1:4 / 5), + actual = 2.5, + quantile_levels = 1:9 / 10, na_handling = "fail" ) diff --git a/tests/testthat/_snaps/pivot_quantiles.md b/tests/testthat/_snaps/pivot_quantiles.md index ca775a18f..13dd81916 100644 --- a/tests/testthat/_snaps/pivot_quantiles.md +++ b/tests/testthat/_snaps/pivot_quantiles.md @@ -3,47 +3,38 @@ Code pivot_quantiles_wider(tib, a) Condition - Error in `UseMethod()`: - ! no applicable method for 'family' applied to an object of class "c('integer', 'numeric')" + Error in `pivot_quantiles_wider()`: + ! `a` is not <`quantile_pred`>. Cannot pivot it. --- Code - pivot_quantiles_wider(tib, c) + pivot_quantiles_wider(tib, d1, d2) Condition - Error in `validate_pivot_quantiles()`: - ! Variables(s) `c` are not `dist_quantiles`. Cannot pivot them. + Error in `pivot_quantiles_wider()`: + ! Only one column can be pivotted. Can not pivot all of: `d1` and `d2`. --- Code - pivot_quantiles_wider(tib, d1) + pivot_quantiles_longer(tib, d1, d2) Condition - Error in `pivot_quantiles_wider()`: - ! Quantiles must be the same length and have the same set of taus. - i Check failed for variables(s) `d1`. + Error in `pivot_quantiles_longer()`: + ! Only one column can be pivotted. Can not pivot all of: `d1` and `d2`. # quantile pivotting longer behaves Code pivot_quantiles_longer(tib, a) Condition - Error in `UseMethod()`: - ! no applicable method for 'family' applied to an object of class "c('integer', 'numeric')" - ---- - - Code - pivot_quantiles_longer(tib, c) - Condition - Error in `validate_pivot_quantiles()`: - ! Variables(s) `c` are not `dist_quantiles`. Cannot pivot them. + Error in `pivot_quantiles_longer()`: + ! `a` is not <`quantile_pred`>. Cannot pivot it. --- Code - pivot_quantiles_longer(tib, d1, d3) + pivot_quantiles_longer(tib, d1, d2) Condition Error in `pivot_quantiles_longer()`: - ! Some selected columns contain different numbers of quantiles. The result would be a very long . To do this anyway, rerun with `.ignore_length_check = TRUE`. + ! Only one column can be pivotted. Can not pivot all of: `d1` and `d2`. diff --git a/tests/testthat/_snaps/wis-quantile_pred.md b/tests/testthat/_snaps/wis-quantile_pred.md new file mode 100644 index 000000000..f13bd74db --- /dev/null +++ b/tests/testthat/_snaps/wis-quantile_pred.md @@ -0,0 +1,16 @@ +# wis dispatches and produces the correct values + + Code + weighted_interval_score(1:10, 10) + Condition + Error in `UseMethod()`: + ! no applicable method for 'weighted_interval_score' applied to an object of class "c('integer', 'numeric')" + +--- + + Code + weighted_interval_score(quantile_pred(rbind(1:4, 8:11), 1:4 / 5), 1:3) + Condition + Error in `weighted_interval_score.quantile_pred()`: + ! Assertion on 'actual' failed: Must have length 2, but has length 3. + diff --git a/tests/testthat/test-layer_residual_quantiles.R b/tests/testthat/test-layer_residual_quantiles.R index 1736ded2d..2941037f5 100644 --- a/tests/testthat/test-layer_residual_quantiles.R +++ b/tests/testthat/test-layer_residual_quantiles.R @@ -23,11 +23,9 @@ test_that("Returns expected number or rows and columns", { expect_equal(nrow(p), 3L) expect_named(p, c("geo_value", "time_value", ".pred", ".pred_distn")) - nested <- p %>% dplyr::mutate(.quantiles = nested_quantiles(.pred_distn)) - unnested <- nested %>% tidyr::unnest(.quantiles) - + unnested <- p %>% pivot_quantiles_longer(.pred_distn) expect_equal(nrow(unnested), 12L) - expect_equal(unique(unnested$quantile_levels), c(.0275, .5, .8, .95)) + expect_equal(unique(unnested$.pred_distn_quantile_level), c(.0275, 0.5, .8, .95)) }) diff --git a/tests/testthat/test-layer_threshold_preds.R b/tests/testthat/test-layer_threshold_preds.R index 2ff43a165..64e8608b2 100644 --- a/tests/testthat/test-layer_threshold_preds.R +++ b/tests/testthat/test-layer_threshold_preds.R @@ -56,11 +56,10 @@ test_that("thresholds additional columns", { expect_equal(round(p$.pred, digits = 3), c(0.180, 0.180, 0.310)) expect_named(p, c("geo_value", "time_value", ".pred", ".pred_distn")) p <- p %>% - dplyr::mutate(.quantiles = nested_quantiles(.pred_distn)) %>% - tidyr::unnest(.quantiles) + pivot_quantiles_longer(.pred_distn) expect_equal( - round(p$values, digits = 3), - c(0.180, 0.180, 0.31, 0.180, 0.180, .18, 0.310, .31, .31) + round(p$.pred_distn_value, digits = 3), + c(0.180, 0.180, 0.31, 0.180, .18, .18, .31, 0.310, .31) ) - expect_equal(p$quantile_levels, rep(c(.1, 0.5, .9), times = 3)) + expect_equal(p$.pred_distn_quantile_level, rep(c(.1, 0.5, .9), times = 3)) }) diff --git a/tests/testthat/test-pivot_quantiles.R b/tests/testthat/test-pivot_quantiles.R index 1639058e2..a4362cffb 100644 --- a/tests/testthat/test-pivot_quantiles.R +++ b/tests/testthat/test-pivot_quantiles.R @@ -1,76 +1,44 @@ test_that("quantile pivotting wider behaves", { tib <- tibble::tibble(a = 1:5, b = 6:10) expect_snapshot(error = TRUE, pivot_quantiles_wider(tib, a)) - tib$c <- rep(dist_normal(), 5) - expect_snapshot(error = TRUE, pivot_quantiles_wider(tib, c)) - d1 <- c(dist_quantiles(1:3, 1:3 / 4), dist_quantiles(2:5, 1:4 / 5)) - # different quantiles - tib <- tib[1:2, ] - tib$d1 <- d1 - expect_snapshot(error = TRUE, pivot_quantiles_wider(tib, d1)) - - d1 <- c(dist_quantiles(1:3, 1:3 / 4), dist_quantiles(2:4, 2:4 / 4)) - tib$d1 <- d1 - # would want to error (mismatched quantiles), but hard to check efficiently - expect_silent(pivot_quantiles_wider(tib, d1)) + d1 <- quantile_pred(rbind(1:3, 2:4), 1:3 / 4) + d2 <- quantile_pred(rbind(2:4, 3:5), 2:4 / 5) + tib <- tibble(g = c("a", "b"), d1 = d1, d2 = d2) - d1 <- c(dist_quantiles(1:3, 1:3 / 4), dist_quantiles(2:4, 1:3 / 4)) - d2 <- c(dist_quantiles(2:4, 2:4 / 5), dist_quantiles(3:5, 2:4 / 5)) - tib <- tibble::tibble(g = c("a", "b"), d1 = d1, d2 = d2) + # too many columns + expect_snapshot(error = TRUE, pivot_quantiles_wider(tib, d1, d2)) + expect_snapshot(error = TRUE, pivot_quantiles_longer(tib, d1, d2)) - expect_length(pivot_quantiles_wider(tib, c("d1", "d2")), 7L) - expect_length(pivot_quantiles_wider(tib, tidyselect::starts_with("d")), 7L) - expect_length(pivot_quantiles_wider(tib, d2), 5L) + expect_length(pivot_quantiles_wider(tib, d1), 5L) + expect_length(pivot_quantiles_wider(tib, tidyselect::ends_with("1")), 5L) + expect_equal(vctrs::vec_size(pivot_quantiles_longer(tib, d2)), 6L) }) test_that("pivotting wider still works if there are duplicates", { # previously this would produce a warning if pivotted because the # two rows of the result are identical - tb <- tibble(.pred = dist_quantiles(list(1:3, 1:3), list(c(.1, .5, .9)))) + tb <- tibble(.pred = quantile_pred(rbind(1:3, 1:3), c(.1, .5, .9))) res <- tibble(`0.1` = c(1, 1), `0.5` = c(2, 2), `0.9` = c(3, 3)) - expect_identical(tb %>% pivot_quantiles_wider(.pred), res) + expect_equal(tb %>% pivot_quantiles_wider(.pred), res) }) test_that("quantile pivotting longer behaves", { tib <- tibble::tibble(a = 1:5, b = 6:10) expect_snapshot(error = TRUE, pivot_quantiles_longer(tib, a)) - tib$c <- rep(dist_normal(), 5) - expect_snapshot(error = TRUE, pivot_quantiles_longer(tib, c)) - - d1 <- c(dist_quantiles(1:3, 1:3 / 4), dist_quantiles(2:5, 1:4 / 5)) - # different quantiles - tib <- tib[1:2, ] - tib$d1 <- d1 - expect_length(pivot_quantiles_longer(tib, d1), 5L) - expect_identical(nrow(pivot_quantiles_longer(tib, d1)), 7L) - expect_identical(pivot_quantiles_longer(tib, d1)$values, as.double(c(1:3, 2:5))) - - d1 <- c(dist_quantiles(1:3, 1:3 / 4), dist_quantiles(2:4, 2:4 / 4)) - tib$d1 <- d1 - expect_silent(pivot_quantiles_longer(tib, d1)) - d1 <- c(dist_quantiles(1:3, 1:3 / 4), dist_quantiles(2:4, 1:3 / 4)) - d2 <- c(dist_quantiles(2:4, 2:4 / 5), dist_quantiles(3:5, 2:4 / 5)) - tib <- tibble::tibble(g = c("a", "b"), d1 = d1, d2 = d2) + d1 <- quantile_pred(rbind(1:3, 2:4), 1:3 / 4) + d2 <- quantile_pred(rbind(2:4, 3:5), 2:4 / 5) + tib <- tibble(g = c("a", "b"), d1 = d1, d2 = d2) + # too many columns + expect_snapshot(error = TRUE, pivot_quantiles_longer(tib, d1, d2)) - expect_length(pivot_quantiles_longer(tib, c("d1", "d2")), 5L) - expect_identical(nrow(pivot_quantiles_longer(tib, c("d1", "d2"))), 6L) - expect_silent(pivot_quantiles_longer(tib, tidyselect::starts_with("d"))) - expect_length(pivot_quantiles_longer(tib, d2), 4L) + # different quantiles + expect_length(pivot_quantiles_longer(tib, d1), 4L) + expect_identical(nrow(pivot_quantiles_longer(tib, d1)), 6L) + expect_identical(pivot_quantiles_longer(tib, d1)$d1_value, c(1:3, 2:4)) - tib$d3 <- c(dist_quantiles(2:5, 2:5 / 6), dist_quantiles(3:6, 2:5 / 6)) - # now the cols have different numbers of quantiles - expect_snapshot(error = TRUE, pivot_quantiles_longer(tib, d1, d3)) - expect_length( - pivot_quantiles_longer(tib, d1, d3, .ignore_length_check = TRUE), - 6L - ) - expect_identical( - pivot_quantiles_longer(tib, d1, d3, .ignore_length_check = TRUE)$d1_values, - as.double(rep(c(1:3, 2:4), each = 4)) - ) }) diff --git a/tests/testthat/test-wis-dist-quantiles.R b/tests/testthat/test-wis-quantile_pred.R similarity index 65% rename from tests/testthat/test-wis-dist-quantiles.R rename to tests/testthat/test-wis-quantile_pred.R index 937793189..187344af9 100644 --- a/tests/testthat/test-wis-dist-quantiles.R +++ b/tests/testthat/test-wis-quantile_pred.R @@ -8,45 +8,38 @@ test_that("wis dispatches and produces the correct values", { actual <- 5 expected <- c(wis_one_pred(q1, tau, actual), wis_one_pred(q2, tau, actual)) - dstn <- dist_quantiles(list(q1, q2), tau) + dstn <- quantile_pred(rbind(q1, q2), tau) expect_equal(weighted_interval_score(dstn, actual), expected) # works with a single dstn q <- sort(10 * rexp(23)) tau0 <- c(.01, .025, 1:19 / 20, .975, .99) - dst <- dist_quantiles(q, tau0) + dst <- quantile_pred(rbind(q), tau0) expect_equal(weighted_interval_score(dst, 10), wis_one_pred(q, tau0, 10)) # returns NA when expected - dst <- dist_quantiles(rep(NA, 3), c(.2, .5, .95)) + dst <- quantile_pred(rbind(rep(NA, 3)), c(.2, .5, .95)) expect_true(is.na(weighted_interval_score(dst, 10))) expect_equal( weighted_interval_score(dstn, c(NA, actual)), c(NA, wis_one_pred(q2, tau, actual)) ) - # errors for non distributions + # errors for non quantile_pred expect_snapshot(error = TRUE, weighted_interval_score(1:10, 10)) - expect_warning(w <- weighted_interval_score(dist_normal(1), 10)) - expect_true(all(is.na(w))) - expect_warning(w <- weighted_interval_score( - c(dist_normal(), dist_quantiles(1:5, 1:5 / 6)), - 10 - )) - expect_equal(w, c(NA, wis_one_pred(1:5, 1:5 / 6, 10))) # errors if sizes don't match expect_snapshot(error = TRUE, weighted_interval_score( - dist_quantiles(list(1:4, 8:11), 1:4 / 5), # length 2 + quantile_pred(rbind(1:4, 8:11), 1:4 / 5), # length 2 1:3 )) #' # Missing value behaviours - dstn <- dist_quantiles(c(1, 2, NA, 4), 1:4 / 5) + dstn <- quantile_pred(rbind(c(1, 2, NA, 4)), 1:4 / 5) expect_equal(weighted_interval_score(dstn, 2.5), 0.5) expect_equal(weighted_interval_score(dstn, 2.5, c(2, 4, 5, 6, 8) / 10), 0.4) expect_equal( - weighted_interval_score(dist_quantiles(c(1, 2, NA, 4), 1:4 / 5), 3, na_handling = "drop"), + weighted_interval_score(dstn, 3, na_handling = "drop"), 2 / 3 ) expect_equal( @@ -56,5 +49,9 @@ test_that("wis dispatches and produces the correct values", { expect_true(is.na( weighted_interval_score(dstn, 2.5, na_handling = "propagate") )) - weighted_interval_score(dist_quantiles(1:4, 1:4 / 5), 2.5, 1:9 / 10, na_handling = "fail") + expect_true(is.na( + weighted_interval_score( + quantile_pred(rbind(1:4), 1:4 / 5), 2.5, 1:9 / 10, na_handling = "fail" + ) + )) }) From 8d87c8e59f24c394b60eb68823dc213bc161f8a3 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Mon, 24 Feb 2025 18:01:51 -0800 Subject: [PATCH 22/25] tests pass, checks don't --- NAMESPACE | 12 + R/epipredict-package.R | 1 + R/extrapolate_quantiles.R | 4 +- R/layer_point_from_distn.R | 6 +- R/layer_threshold_preds.R | 1 + R/pivot_quantiles.R | 50 + R/quantile_pred-methods.R | 105 ++ R/reexports-tidymodels.R | 12 +- R/utils-misc.R | 2 +- man/dist_quantiles.Rd | 28 + man/extrapolate_quantiles.Rd | 4 +- man/figures/lifecycle-deprecated.svg | 21 + man/figures/lifecycle-experimental.svg | 21 + man/figures/lifecycle-stable.svg | 29 + man/figures/lifecycle-superseded.svg | 21 + man/nested_quantiles.Rd | 31 + man/reexports.Rd | 7 +- tests/testthat/_snaps/dist_quantiles.md | 56 - tests/testthat/_snaps/pivot_quantiles.md | 18 + tests/testthat/_snaps/snapshots.md | 1484 +++++++------------ tests/testthat/_snaps/wis-dist-quantiles.md | 17 - tests/testthat/test-grf_quantiles.R | 2 +- tests/testthat/test-pivot_quantiles.R | 9 + tests/testthat/test-population_scaling.R | 13 +- tests/testthat/test-step_adjust_latency.R | 8 +- 25 files changed, 896 insertions(+), 1066 deletions(-) create mode 100644 man/dist_quantiles.Rd create mode 100644 man/figures/lifecycle-deprecated.svg create mode 100644 man/figures/lifecycle-experimental.svg create mode 100644 man/figures/lifecycle-stable.svg create mode 100644 man/figures/lifecycle-superseded.svg create mode 100644 man/nested_quantiles.Rd delete mode 100644 tests/testthat/_snaps/dist_quantiles.md delete mode 100644 tests/testthat/_snaps/wis-dist-quantiles.md diff --git a/NAMESPACE b/NAMESPACE index 0e944941a..9116bb71e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -115,6 +115,7 @@ S3method(vec_arith,quantile_pred) S3method(vec_arith.numeric,quantile_pred) S3method(vec_arith.quantile_pred,numeric) S3method(vec_math,quantile_pred) +S3method(vec_proxy_equal,quantile_pred) S3method(weighted_interval_score,quantile_pred) export("%>%") export(Add_model) @@ -133,6 +134,7 @@ export(arx_class_epi_workflow) export(arx_classifier) export(arx_fcast_epi_workflow) export(arx_forecaster) +export(as_tibble) export(autoplot) export(bake) export(cdc_baseline_args_list) @@ -141,12 +143,14 @@ export(check_enough_train_data) export(clean_f_name) export(default_epi_recipe_blueprint) export(detect_layer) +export(dist_quantiles) export(epi_recipe) export(epi_recipe_blueprint) export(epi_workflow) export(extract_argument) export(extract_frosting) export(extract_layers) +export(extract_quantile_levels) export(extrapolate_quantiles) export(fit) export(flatline) @@ -172,11 +176,13 @@ export(layer_quantile_distn) export(layer_residual_quantiles) export(layer_threshold) export(layer_unnest) +export(nested_quantiles) export(new_default_epi_recipe_blueprint) export(new_epi_recipe_blueprint) export(pivot_quantiles_longer) export(pivot_quantiles_wider) export(prep) +export(quantile_pred) export(quantile_reg) export(rand_id) export(remove_epi_recipe) @@ -256,10 +262,12 @@ importFrom(ggplot2,geom_linerange) importFrom(ggplot2,geom_point) importFrom(ggplot2,geom_ribbon) importFrom(glue,glue) +importFrom(hardhat,extract_quantile_levels) importFrom(hardhat,extract_recipe) importFrom(hardhat,quantile_pred) importFrom(hardhat,refresh_blueprint) importFrom(hardhat,run_mold) +importFrom(lifecycle,deprecated) importFrom(magrittr,"%>%") importFrom(magrittr,extract2) importFrom(recipes,bake) @@ -304,8 +312,12 @@ importFrom(tidyr,fill) importFrom(tidyr,unnest) importFrom(tidyselect,all_of) importFrom(utils,capture.output) +importFrom(vctrs,as_list_of) +importFrom(vctrs,new_vctr) importFrom(vctrs,vec_arith) importFrom(vctrs,vec_arith.numeric) importFrom(vctrs,vec_cast) importFrom(vctrs,vec_math) +importFrom(vctrs,vec_proxy_equal) +importFrom(vctrs,vec_recycle_common) importFrom(workflows,extract_preprocessor) diff --git a/R/epipredict-package.R b/R/epipredict-package.R index b4b9973bf..5d4139242 100644 --- a/R/epipredict-package.R +++ b/R/epipredict-package.R @@ -9,6 +9,7 @@ #' @importFrom dplyr full_join relocate summarise everything #' @importFrom dplyr inner_join #' @importFrom dplyr summarize filter mutate select left_join rename ungroup +#' @importFrom lifecycle deprecated #' @importFrom magrittr extract2 #' @importFrom rlang := !! %||% as_function global_env set_names !!! caller_arg #' @importFrom rlang is_logical is_true inject enquo enquos expr sym arg_match diff --git a/R/extrapolate_quantiles.R b/R/extrapolate_quantiles.R index 82116c1d3..c7a9a3b6b 100644 --- a/R/extrapolate_quantiles.R +++ b/R/extrapolate_quantiles.R @@ -18,9 +18,9 @@ #' @export #' #' @examples -#' dstn <- quantile_dstn(rbind(1:4, 8:11), c(.2, .4, .6, .8)) +#' dstn <- quantile_pred(rbind(1:4, 8:11), c(.2, .4, .6, .8)) #' # extra quantiles are appended -#' as.tibble(extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75))) +#' as_tibble(extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75))) extrapolate_quantiles <- function(x, probs, replace_na = TRUE, ...) { UseMethod("extrapolate_quantiles") } diff --git a/R/layer_point_from_distn.R b/R/layer_point_from_distn.R index c433717bb..ae1c56dbe 100644 --- a/R/layer_point_from_distn.R +++ b/R/layer_point_from_distn.R @@ -79,10 +79,10 @@ layer_point_from_distn_new <- function(type, name, id) { slather.layer_point_from_distn <- function(object, components, workflow, new_data, ...) { dstn <- components$predictions$.pred - if (!inherits(dstn, "distribution")) { - rlang::warn( + if (!(inherits(dstn, "quantile_pred") | inherits(dstn, "distribution"))) { + cli_warn( c("`layer_point_from_distn` requires distributional predictions.", - i = "These are of class {class(dstn)}. Ignoring this layer." + i = "These are of class {.cls {class(dstn)}}. Ignoring this layer." ) ) return(components) diff --git a/R/layer_threshold_preds.R b/R/layer_threshold_preds.R index bdc334b63..ce02fe24a 100644 --- a/R/layer_threshold_preds.R +++ b/R/layer_threshold_preds.R @@ -60,6 +60,7 @@ layer_threshold_new <- } #' @export +#' @keywords internal snap <- function(x, lower, upper, ...) { UseMethod("snap") } diff --git a/R/pivot_quantiles.R b/R/pivot_quantiles.R index 37f08b46f..8e846d7e6 100644 --- a/R/pivot_quantiles.R +++ b/R/pivot_quantiles.R @@ -1,3 +1,53 @@ +#' Turn a vector of quantile distributions into a list-col +#' +#' `r lifecycle::badge("deprecated")` +#' +#' This function is deprecated. The recommended alternative is +#' [hardhat::quantile_pred()] with [tibble::as_tibble()] + +#' +#' @param x a `distribution` containing `dist_quantiles` +#' +#' @return a list-col +#' @export +#' +#' @examples +#' .pred_quantile <- quantile_pred(matrix(rnorm(20), 5), c(.2, .4, .6, .8)) +#' nested_quantiles(.pred_quantile) +#' +#' .pred_quantile %>% +#' as_tibble() %>% +#' tidyr::nest(.by = .row) %>% +#' dplyr::select(-.row) +#' +nested_quantiles <- function(x) { + lifecycle::deprecate_warn("0.1.11", "nested_quantiles()", "hardhat::quantile_pred()") + if (inherits(x, "distribution")) { + if (requireNamespace("distributional")) { + x <- vctrs::vec_data(x) + return(distributional:::dist_apply(x, .f = function(z) { + as_tibble(vctrs::vec_data(z)) %>% + mutate(across(everything(), as.double)) %>% + vctrs::list_of() + })) + } else { + cli_abort(c( + "`nested_quantiles()` is deprecated and the {.pkg distributional}", + `!` = "package is not installed.", + i = "See {.fn hardhat::quantile_pred}." + )) + } + } + if (inherits(x, "quantile_pred")) { + return(x %>% as_tibble() %>% tidyr::nest(.by = .row) %>% + dplyr::select(data)) + } + cli_abort(c( + "`nested_quantiles()` is deprecated. See {.fn hardhat::quantile_pred}." + )) +} + + #' Pivot a column containing `quantile_pred` longer #' #' A column that contains `quantile_pred` will be "lengthened" with diff --git a/R/quantile_pred-methods.R b/R/quantile_pred-methods.R index 1f86052d1..90313c9ef 100644 --- a/R/quantile_pred-methods.R +++ b/R/quantile_pred-methods.R @@ -1,3 +1,40 @@ +#' A distribution parameterized by a set of quantiles +#' +#' `r lifecycle::badge("deprecated")` +#' +#' This function is deprecated. The recommended alternative is +#' [hardhat::quantile_pred()]. +#' +#' @param values A vector (or list of vectors) of values. +#' @param quantile_levels A vector (or list of vectors) of probabilities +#' corresponding to `values`. +#' +#' When creating multiple sets of `values`/`quantile_levels` resulting in +#' different distributions, the sizes must match. See the examples below. +#' +#' @return A vector of class `"distribution"`. +#' +#' @export +#' @keywords internal +#' +#' @importFrom vctrs as_list_of vec_recycle_common new_vctr +dist_quantiles <- function(values, quantile_levels) { + lifecycle::deprecate_warn("0.1.11", "dist_quantiles()", "hardhat::quantile_pred()") + if (is.list(values)) { + n <- length(values) + values <- unlist(values) + return(quantile_pred(matrix(values, nrow = n, byrow = TRUE), quantile_levels)) + } else if (is.matrix(values)) { + return(quantile_pred(values, quantile_levels)) + } else if (is.vector(values)) { + return(quantile_pred(matrix(values, nrow = 1), quantile_levels)) + } + cli_abort(c( + "`dist_quantiles()` is deprecated and the format of `values` could not", + `!` = "be automatically converted to work with the replacement.", + i = "See {.fn hardhat::quantile_pred}." + )) +} # placeholder to avoid errors, but not ideal #' @importFrom hardhat quantile_pred @@ -6,6 +43,74 @@ mean.quantile_pred <- function(x, na.rm = FALSE, ...) { median(x, ...) } +# These next 3 functions should probably be added via PR to {hardhat} +# Only the third is actually *needed* at the moment. +# The second doesn't work correctly (not sure why), but leaving here for the +# future. +# +# We only export the third. +# +# self-self method, should work only if attr(quantile_levels) are compatible +# #' @importFrom vctrs vec_ptype2 vec_cast +# #' @importFrom hardhat extract_quantile_levels +# #' @export +# #' @keywords internal +# vec_ptype2.quantile_pred.quantile_pred <- function( +# x, y, ..., x_arg = "", y_arg = "", call = caller_env() +# ) { +# if (all(extract_quantile_levels(y) %in% extract_quantile_levels(x))) { +# return(x) +# } +# if (all(extract_quantile_levels(x) %in% extract_quantile_levels(y))) { +# return(y) +# } +# vctrs::stop_incompatible_type( +# x, y, x_arg = x_arg, y_arg = y_arg, +# details = "`quantile_levels` must be compatible (a superset/subset relation)." +# ) +# } + +# currently doesn't work +# #' @export +# vec_cast.quantile_pred.quantile_pred <- function( +# x, to, ..., x_arg = caller_arg(x), to_arg = caller_arg(to), +# call = caller_env() +# ) { +# to_ql <- extract_quantile_levels(to) +# x_ql <- extract_quantile_levels(x) +# x_in_to <- x_ql %in% to_ql +# to_in_x <- to_ql %in% x_ql +# if (all(x_in_to)) { +# mat <- matrix(NA, ncol = length(to_ql)) +# mat[ , to_in_x] <- c(as.matrix(x)) +# } else if (all(to_in_x)) { +# mat <- as.matrix(x)[ , x_in_to, drop = FALSE] +# } else { +# vctrs::stop_incompatible_type( +# x, to, x_arg = x_arg, y_arg = to_arg, +# details = "`quantile_levels` must be compatible (a superset/subset relation)." +# ) +# } +# quantile_pred(mat, to_ql) +# } + + +# Convert the quantile_pred to a data frame (named with the .quantile_levels) +# This powers vec_proxy_equal (and hence ==, !=, is.na, etc) +# It also powers vec_proxy_compare, so, given matching colnames, these should +# work out of the box. +# +#' @importFrom vctrs vec_proxy_equal +#' @export +vec_proxy_equal.quantile_pred <- function(x, ...) { + as_tibble(x) %>% + tidyr::pivot_wider( + names_from = .quantile_levels, + values_from = .pred_quantile + ) %>% + dplyr::select(-.row) +} + # quantiles by treating quantile_pred like a distribution ----------------- diff --git a/R/reexports-tidymodels.R b/R/reexports-tidymodels.R index 3b28ac5c5..00cd7e4fd 100644 --- a/R/reexports-tidymodels.R +++ b/R/reexports-tidymodels.R @@ -18,10 +18,20 @@ recipes::bake #' @export recipes::rand_id -#' @importFrom tibble tibble +#' @importFrom tibble tibble as_tibble #' @export tibble::tibble +#' @export +tibble::as_tibble + #' @importFrom generics tidy #' @export generics::tidy + +#' @importFrom hardhat quantile_pred extract_quantile_levels +#' @export +hardhat::quantile_pred + +#' @export +hardhat::extract_quantile_levels diff --git a/R/utils-misc.R b/R/utils-misc.R index fec707913..bdb35a9eb 100644 --- a/R/utils-misc.R +++ b/R/utils-misc.R @@ -47,7 +47,7 @@ format_varnames <- function(x, empty = "*none*") { if (length(x) == 0L) { empty } else { - as.character(syms(x)) + as.character(rlang::syms(x)) } } diff --git a/man/dist_quantiles.Rd b/man/dist_quantiles.Rd new file mode 100644 index 000000000..1bfa437b0 --- /dev/null +++ b/man/dist_quantiles.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/quantile_pred-methods.R +\name{dist_quantiles} +\alias{dist_quantiles} +\title{A distribution parameterized by a set of quantiles} +\usage{ +dist_quantiles(values, quantile_levels) +} +\arguments{ +\item{values}{A vector (or list of vectors) of values.} + +\item{quantile_levels}{A vector (or list of vectors) of probabilities +corresponding to \code{values}. + +When creating multiple sets of \code{values}/\code{quantile_levels} resulting in +different distributions, the sizes must match. See the examples below.} +} +\value{ +A vector of class \code{"distribution"}. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} +} +\details{ +This function is deprecated. The recommended alternative is +\code{\link[hardhat:quantile_pred]{hardhat::quantile_pred()}}. +} +\keyword{internal} diff --git a/man/extrapolate_quantiles.Rd b/man/extrapolate_quantiles.Rd index b645b85fa..bd460dbe9 100644 --- a/man/extrapolate_quantiles.Rd +++ b/man/extrapolate_quantiles.Rd @@ -29,7 +29,7 @@ similar to \code{\link[stats:quantile]{stats::quantile()}}, then \code{quantile( appropriate. } \examples{ -dstn <- quantile_dstn(rbind(1:4, 8:11), c(.2, .4, .6, .8)) +dstn <- quantile_pred(rbind(1:4, 8:11), c(.2, .4, .6, .8)) # extra quantiles are appended -as.tibble(extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75))) +as_tibble(extrapolate_quantiles(dstn, probs = c(.25, 0.5, .75))) } diff --git a/man/figures/lifecycle-deprecated.svg b/man/figures/lifecycle-deprecated.svg new file mode 100644 index 000000000..b61c57c3f --- /dev/null +++ b/man/figures/lifecycle-deprecated.svg @@ -0,0 +1,21 @@ + + lifecycle: deprecated + + + + + + + + + + + + + + + lifecycle + + deprecated + + diff --git a/man/figures/lifecycle-experimental.svg b/man/figures/lifecycle-experimental.svg new file mode 100644 index 000000000..5d88fc2c6 --- /dev/null +++ b/man/figures/lifecycle-experimental.svg @@ -0,0 +1,21 @@ + + lifecycle: experimental + + + + + + + + + + + + + + + lifecycle + + experimental + + diff --git a/man/figures/lifecycle-stable.svg b/man/figures/lifecycle-stable.svg new file mode 100644 index 000000000..9bf21e76b --- /dev/null +++ b/man/figures/lifecycle-stable.svg @@ -0,0 +1,29 @@ + + lifecycle: stable + + + + + + + + + + + + + + + + lifecycle + + + + stable + + + diff --git a/man/figures/lifecycle-superseded.svg b/man/figures/lifecycle-superseded.svg new file mode 100644 index 000000000..db8d757f7 --- /dev/null +++ b/man/figures/lifecycle-superseded.svg @@ -0,0 +1,21 @@ + + lifecycle: superseded + + + + + + + + + + + + + + + lifecycle + + superseded + + diff --git a/man/nested_quantiles.Rd b/man/nested_quantiles.Rd new file mode 100644 index 000000000..4b666ee32 --- /dev/null +++ b/man/nested_quantiles.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/pivot_quantiles.R +\name{nested_quantiles} +\alias{nested_quantiles} +\title{Turn a vector of quantile distributions into a list-col} +\usage{ +nested_quantiles(x) +} +\arguments{ +\item{x}{a \code{distribution} containing \code{dist_quantiles}} +} +\value{ +a list-col +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} +} +\details{ +This function is deprecated. The recommended alternative is +\code{\link[hardhat:quantile_pred]{hardhat::quantile_pred()}} with \code{\link[tibble:as_tibble]{tibble::as_tibble()}} +} +\examples{ +.pred_quantile <- quantile_pred(matrix(rnorm(20), 5), c(.2, .4, .6, .8)) +nested_quantiles(.pred_quantile) + +.pred_quantile \%>\% + as_tibble() \%>\% + tidyr::nest(.by = .row) \%>\% + dplyr::select(-.row) + +} diff --git a/man/reexports.Rd b/man/reexports.Rd index f6849a53c..abbba28b3 100644 --- a/man/reexports.Rd +++ b/man/reexports.Rd @@ -10,7 +10,10 @@ \alias{bake} \alias{rand_id} \alias{tibble} +\alias{as_tibble} \alias{tidy} +\alias{quantile_pred} +\alias{extract_quantile_levels} \title{Objects exported from other packages} \keyword{internal} \description{ @@ -22,8 +25,10 @@ below to see their documentation. \item{ggplot2}{\code{\link[ggplot2]{autoplot}}} + \item{hardhat}{\code{\link[hardhat:quantile_pred]{extract_quantile_levels}}, \code{\link[hardhat]{quantile_pred}}} + \item{recipes}{\code{\link[recipes]{bake}}, \code{\link[recipes]{prep}}, \code{\link[recipes]{rand_id}}} - \item{tibble}{\code{\link[tibble]{tibble}}} + \item{tibble}{\code{\link[tibble]{as_tibble}}, \code{\link[tibble]{tibble}}} }} diff --git a/tests/testthat/_snaps/dist_quantiles.md b/tests/testthat/_snaps/dist_quantiles.md deleted file mode 100644 index 1d626e089..000000000 --- a/tests/testthat/_snaps/dist_quantiles.md +++ /dev/null @@ -1,56 +0,0 @@ -# constructor returns reasonable quantiles - - Code - new_quantiles(rnorm(5), c(-2, -1, 0, 1, 2)) - Condition - Error in `new_quantiles()`: - ! `quantile_levels` must lie in [0, 1]. - ---- - - Code - new_quantiles(sort(rnorm(5)), sort(runif(2))) - Condition - Error in `new_quantiles()`: - ! length(values) == length(quantile_levels) is not TRUE - ---- - - Code - new_quantiles(c(2, 1, 3, 4, 5), c(0.1, 0.1, 0.2, 0.5, 0.8)) - Condition - Error in `new_quantiles()`: - ! !vctrs::vec_duplicate_any(quantile_levels) is not TRUE - ---- - - Code - new_quantiles(c(2, 1, 3, 4, 5), c(0.1, 0.15, 0.2, 0.5, 0.8)) - Condition - Error in `new_quantiles()`: - ! `values[order(quantile_levels)]` produces unsorted quantiles. - ---- - - Code - new_quantiles(c(1, 2, 3), c(0.1, 0.2, 3)) - Condition - Error in `new_quantiles()`: - ! `quantile_levels` must lie in [0, 1]. - -# arithmetic works on quantiles - - Code - sum(dstn) - Condition - Error in `mapply()`: - ! You can't perform arithmetic between two distributions like this. - ---- - - Code - suppressWarnings(dstn + distributional::dist_normal()) - Condition - Error: - ! non-numeric argument to binary operator - diff --git a/tests/testthat/_snaps/pivot_quantiles.md b/tests/testthat/_snaps/pivot_quantiles.md index 13dd81916..ea027d50c 100644 --- a/tests/testthat/_snaps/pivot_quantiles.md +++ b/tests/testthat/_snaps/pivot_quantiles.md @@ -38,3 +38,21 @@ Error in `pivot_quantiles_longer()`: ! Only one column can be pivotted. Can not pivot all of: `d1` and `d2`. +# nested_quantiles is deprecated, but works where possible + + Code + d <- dist_quantiles(list(1:4, 2:5), 1:4 / 5) + Condition + Warning: + `dist_quantiles()` was deprecated in epipredict 0.1.11. + i Please use `hardhat::quantile_pred()` instead. + +--- + + Code + o <- nested_quantiles(d) + Condition + Warning: + `nested_quantiles()` was deprecated in epipredict 0.1.11. + i Please use `hardhat::quantile_pred()` instead. + diff --git a/tests/testthat/_snaps/snapshots.md b/tests/testthat/_snaps/snapshots.md index d1cf2df7c..4476c49ec 100644 --- a/tests/testthat/_snaps/snapshots.md +++ b/tests/testthat/_snaps/snapshots.md @@ -2,30 +2,16 @@ structure(list(geo_value = c("ca", "fl", "ga", "ny", "pa", "tx" ), .pred = c(0.1393442, 0.103199, 0.3121244, 0.4218461, 0.7319844, - 0.1975426), .pred_distn = structure(list(structure(list(values = c(0, - 0.00989957999999999, 0.09353595, 0.1393442, 0.18515245, 0.26878882, - 0.34820911), quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, - 0.9, 0.95)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0.05739075, 0.103199, - 0.14900725, 0.23264362, 0.31206391), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.10325949, 0.18267978, 0.26631615, 0.3121244, - 0.35793265, 0.44156902, 0.52098931), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.21298119, 0.29240148, 0.37603785, 0.4218461, - 0.46765435, 0.55129072, 0.63071101), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.52311949, 0.60253978, 0.68617615, 0.7319844, - 0.77779265, 0.86142902, 0.94084931), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0.06809798, 0.15173435, 0.1975426, 0.24335085, - 0.32698722, 0.40640751), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr"))), class = c("distribution", "vctrs_vctr", + 0.1975426), .pred_distn = structure(list(c(0, 0.00989957999999999, + 0.09353595, 0.1393442, 0.18515245, 0.26878882, 0.34820911), c(0, + 0, 0.05739075, 0.103199, 0.14900725, 0.23264362, 0.31206391), + c(0.10325949, 0.18267978, 0.26631615, 0.3121244, 0.35793265, + 0.44156902, 0.52098931), c(0.21298119, 0.29240148, 0.37603785, + 0.4218461, 0.46765435, 0.55129072, 0.63071101), c(0.52311949, + 0.60253978, 0.68617615, 0.7319844, 0.77779265, 0.86142902, + 0.94084931), c(0, 0.06809798, 0.15173435, 0.1975426, 0.24335085, + 0.32698722, 0.40640751)), quantile_levels = c(0.05, 0.1, + 0.25, 0.5, 0.75, 0.9, 0.95), class = c("quantile_pred", "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, 18992, 18992, 18992, 18992), class = "Date"), target_date = structure(c(18999, 18999, 18999, 18999, 18999, 18999), class = "Date")), row.names = c(NA, @@ -35,31 +21,18 @@ structure(list(geo_value = c("ca", "fl", "ga", "ny", "pa", "tx" ), .pred = c(0.1393442, 0.103199, 0.3121244, 0.4218461, 0.7319844, - 0.1975426), .pred_distn = structure(list(structure(list(values = c(0.084583345, - 0.1073314, 0.1292864, 0.1393442, 0.149402, 0.171357, 0.194105055 - ), quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.048438145, 0.0711862, 0.0931412, 0.103199, 0.1132568, - 0.1352118, 0.157959855), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0.257363545, - 0.2801116, 0.3020666, 0.3121244, 0.3221822, 0.3441372, 0.366885255 - ), quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.367085245, 0.3898333, 0.4117883, 0.4218461, - 0.4319039, 0.4538589, 0.476606955), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.677223545, 0.6999716, 0.7219266, 0.7319844, - 0.7420422, 0.7639972, 0.786745255), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.142781745, 0.1655298, 0.1874848, 0.1975426, - 0.2076004, 0.2295554, 0.252303455), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr"))), class = c("distribution", - "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, - 18992, 18992, 18992, 18992), class = "Date"), target_date = structure(c(18993, + 0.1975426), .pred_distn = structure(list(c(0.084583345, 0.1073314, + 0.1292864, 0.1393442, 0.149402, 0.171357, 0.194105055), c(0.048438145, + 0.0711862, 0.0931412, 0.103199, 0.1132568, 0.1352118, 0.157959855 + ), c(0.257363545, 0.2801116, 0.3020666, 0.3121244, 0.3221822, + 0.3441372, 0.366885255), c(0.367085245, 0.3898333, 0.4117883, + 0.4218461, 0.4319039, 0.4538589, 0.476606955), c(0.677223545, + 0.6999716, 0.7219266, 0.7319844, 0.7420422, 0.7639972, 0.786745255 + ), c(0.142781745, 0.1655298, 0.1874848, 0.1975426, 0.2076004, + 0.2295554, 0.252303455)), quantile_levels = c(0.05, 0.1, 0.25, + 0.5, 0.75, 0.9, 0.95), class = c("quantile_pred", "vctrs_vctr", + "list")), forecast_date = structure(c(18992, 18992, 18992, 18992, + 18992, 18992), class = "Date"), target_date = structure(c(18993, 18993, 18993, 18993, 18993, 18993), class = "Date")), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame")) @@ -67,30 +40,16 @@ structure(list(geo_value = c("ca", "fl", "ga", "ny", "pa", "tx" ), .pred = c(0.1393442, 0.103199, 0.3121244, 0.4218461, 0.7319844, - 0.1975426), .pred_distn = structure(list(structure(list(values = c(0, - 0.00989957999999999, 0.09353595, 0.1393442, 0.18515245, 0.26878882, - 0.34820911), quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, - 0.9, 0.95)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0.05739075, 0.103199, - 0.14900725, 0.23264362, 0.31206391), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.10325949, 0.18267978, 0.26631615, 0.3121244, - 0.35793265, 0.44156902, 0.52098931), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.21298119, 0.29240148, 0.37603785, 0.4218461, - 0.46765435, 0.55129072, 0.63071101), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.52311949, 0.60253978, 0.68617615, 0.7319844, - 0.77779265, 0.86142902, 0.94084931), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0.06809798, 0.15173435, 0.1975426, 0.24335085, - 0.32698722, 0.40640751), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr"))), class = c("distribution", "vctrs_vctr", + 0.1975426), .pred_distn = structure(list(c(0, 0.00989957999999999, + 0.09353595, 0.1393442, 0.18515245, 0.26878882, 0.34820911), c(0, + 0, 0.05739075, 0.103199, 0.14900725, 0.23264362, 0.31206391), + c(0.10325949, 0.18267978, 0.26631615, 0.3121244, 0.35793265, + 0.44156902, 0.52098931), c(0.21298119, 0.29240148, 0.37603785, + 0.4218461, 0.46765435, 0.55129072, 0.63071101), c(0.52311949, + 0.60253978, 0.68617615, 0.7319844, 0.77779265, 0.86142902, + 0.94084931), c(0, 0.06809798, 0.15173435, 0.1975426, 0.24335085, + 0.32698722, 0.40640751)), quantile_levels = c(0.05, 0.1, + 0.25, 0.5, 0.75, 0.9, 0.95), class = c("quantile_pred", "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, 18992, 18992, 18992, 18992), class = "Date"), target_date = structure(c(18999, 18999, 18999, 18999, 18999, 18999), class = "Date")), row.names = c(NA, @@ -100,30 +59,16 @@ structure(list(geo_value = c("ca", "fl", "ga", "ny", "pa", "tx" ), .pred = c(0.1393442, 0.103199, 0.3121244, 0.4218461, 0.7319844, - 0.1975426), .pred_distn = structure(list(structure(list(values = c(0, - 0.00989957999999999, 0.09353595, 0.1393442, 0.18515245, 0.26878882, - 0.34820911), quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, - 0.9, 0.95)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0.05739075, 0.103199, - 0.14900725, 0.23264362, 0.31206391), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.10325949, 0.18267978, 0.26631615, 0.3121244, - 0.35793265, 0.44156902, 0.52098931), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.21298119, 0.29240148, 0.37603785, 0.4218461, - 0.46765435, 0.55129072, 0.63071101), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.52311949, 0.60253978, 0.68617615, 0.7319844, - 0.77779265, 0.86142902, 0.94084931), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0.06809798, 0.15173435, 0.1975426, 0.24335085, - 0.32698722, 0.40640751), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr"))), class = c("distribution", "vctrs_vctr", + 0.1975426), .pred_distn = structure(list(c(0, 0.00989957999999999, + 0.09353595, 0.1393442, 0.18515245, 0.26878882, 0.34820911), c(0, + 0, 0.05739075, 0.103199, 0.14900725, 0.23264362, 0.31206391), + c(0.10325949, 0.18267978, 0.26631615, 0.3121244, 0.35793265, + 0.44156902, 0.52098931), c(0.21298119, 0.29240148, 0.37603785, + 0.4218461, 0.46765435, 0.55129072, 0.63071101), c(0.52311949, + 0.60253978, 0.68617615, 0.7319844, 0.77779265, 0.86142902, + 0.94084931), c(0, 0.06809798, 0.15173435, 0.1975426, 0.24335085, + 0.32698722, 0.40640751)), quantile_levels = c(0.05, 0.1, + 0.25, 0.5, 0.75, 0.9, 0.95), class = c("quantile_pred", "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, 18992, 18992, 18992, 18992), class = "Date"), target_date = structure(c(18993, 18993, 18993, 18993, 18993, 18993), class = "Date")), row.names = c(NA, @@ -141,279 +86,160 @@ 0.7319844, 0.7319844, 0.7319844, 0.1975426, 0.1975426, 0.1975426, 0.1975426, 0.1975426), ahead = c(1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, - 4L, 5L, 1L, 2L, 3L, 4L, 5L), .pred_distn = structure(list(structure(list( - values = c(0, 0, 0, 0.05519342, 0.082372705, 0.0936219, 0.1048711, - 0.1157573, 0.12317806, 0.1302723, 0.1353526, 0.1393442, 0.1433358, - 0.1484161, 0.15551034, 0.1629311, 0.1738173, 0.1850665, 0.196315695, - 0.22349498, 0.309768685, 0.3567520625, 0.439580229), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0.0335550493877939, + 4L, 5L, 1L, 2L, 3L, 4L, 5L), .pred_distn = structure(list(c(0, + 0, 0, 0.05519342, 0.082372705, 0.0936219, 0.1048711, 0.1157573, + 0.12317806, 0.1302723, 0.1353526, 0.1393442, 0.1433358, 0.1484161, + 0.15551034, 0.1629311, 0.1738173, 0.1850665, 0.196315695, 0.22349498, + 0.309768685, 0.3567520625, 0.439580229), c(0, 0, 0, 0, 0.0335550493877939, 0.0604073208819088, 0.0796881899581496, 0.0945180888333883, 0.107218788833388, 0.118830788833388, 0.129717088833388, 0.1393442, 0.148949488833388, 0.159110072060821, 0.171080110623306, 0.184009705322953, 0.19866346102411, 0.218798896615666, 0.250961850618106, 0.300471354816148, 0.368582781136862, - 0.43909595699107, 0.520101234797705), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0.0310685196688967, + 0.43909595699107, 0.520101234797705), c(0, 0, 0, 0, 0, 0.0310685196688967, 0.0565901050435504, 0.0768417663716637, 0.0947104815343153, 0.110553706525765, 0.125192081534315, 0.1393442, 0.153133424194392, 0.167807181271713, 0.183769310145952, 0.202099979390294, 0.224139947221972, 0.252840918770688, 0.291417895572206, 0.341073550318203, 0.420604597710477, 0.494523225410904, - 0.573647294116801), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0.00623643594225938, 0.0360877950479505, - 0.0604332430739307, 0.0824028153516535, 0.102509343235732, - 0.121439405653606, 0.1393442, 0.15780837904264, 0.176333479766098, - 0.1971089199637, 0.219859545844459, 0.246500872561225, 0.279163385675357, - 0.320379296602716, 0.374497727839579, 0.458894379633346, - 0.535545067037845, 0.628776504364044), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0, 0.0192048017017668, - 0.0478501821296211, 0.0723167026720766, 0.0958385084225842, 0.11812331897399, - 0.1393442, 0.161074539705197, 0.184026763327133, 0.207844848454635, - 0.23407004803228, 0.265166265836908, 0.302137478236883, 0.346008752873429, - 0.403205598400084, 0.495260096430714, 0.574198142463125, 0.672941852619816 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, - 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0, 0, - 0, 0, 0.016465765, 0.03549514, 0.05225675, 0.0644172, 0.0749343000000001, + 0.573647294116801), c(0, 0, 0, 0, 0, 0.00623643594225938, 0.0360877950479505, + 0.0604332430739307, 0.0824028153516535, 0.102509343235732, 0.121439405653606, + 0.1393442, 0.15780837904264, 0.176333479766098, 0.1971089199637, + 0.219859545844459, 0.246500872561225, 0.279163385675357, 0.320379296602716, + 0.374497727839579, 0.458894379633346, 0.535545067037845, 0.628776504364044 + ), c(0, 0, 0, 0, 0, 0, 0.0192048017017668, 0.0478501821296211, + 0.0723167026720766, 0.0958385084225842, 0.11812331897399, 0.1393442, + 0.161074539705197, 0.184026763327133, 0.207844848454635, 0.23407004803228, + 0.265166265836908, 0.302137478236883, 0.346008752873429, 0.403205598400084, + 0.495260096430714, 0.574198142463125, 0.672941852619816), c(0, + 0, 0, 0, 0.016465765, 0.03549514, 0.05225675, 0.0644172, 0.0749343, 0.0847941, 0.0966258, 0.103199, 0.1097722, 0.1216039, 0.1314637, 0.1419808, 0.15414125, 0.17090286, 0.189932235, 0.22848398, 0.30542311, - 0.40216399, 0.512353658), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0.00331296053340532, 0.0234804643776438, - 0.0414109089650896, 0.0579040140087902, 0.0738391473860739, - 0.0882882738549385, 0.103199, 0.118522737211872, 0.134217143129031, - 0.15174910202592, 0.17076597900759, 0.192368859892349, 0.218887, - 0.254338497855279, 0.307871753369934, 0.407530532639726, - 0.506824682189646, 0.607973477267732), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0, 0, - 0.0185864520320203, 0.0411215858914089, 0.062281046686267, 0.0828222124563246, - 0.103199, 0.123575888447284, 0.144785989158292, 0.167277039342293, - 0.192536265178252, 0.221677797769728, 0.256887836856768, 0.302366681512415, - 0.3669383199518, 0.476508917333523, 0.574293059865274, 0.69194511433946 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, - 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0, 0, - 0, 0, 0, 0, 0, 0, 0.0271019287070871, 0.0535555494987951, 0.0785514374097741, - 0.103199, 0.128043832742677, 0.154157375592856, 0.181874602598776, - 0.212708648669987, 0.247608381738568, 0.289082621291513, 0.342486159511745, - 0.41300665395314, 0.52870334697862, 0.634316186092986, 0.767614547228429 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, - 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0, 0, - 0, 0, 0, 0, 0, 0, 0.0118725894981448, 0.0439446210512103, 0.0736366703227029, - 0.103199, 0.133138617710077, 0.16357656105121, 0.19575459701827, - 0.230475760859608, 0.269323345322203, 0.314976554734947, 0.373424338576786, - 0.452807955824158, 0.578141866759416, 0.690542571738594, 0.837295153768033 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, - 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0, 0, - 0.0813658, 0.14899276, 0.1960782, 0.22542314, 0.2414296, 0.25890318, - 0.2747762, 0.2881148, 0.3027873, 0.3121244, 0.3214615, 0.336134, - 0.3494726, 0.36534562, 0.3828192, 0.39882566, 0.4281706, 0.47525604, - 0.542883, 0.682805397499999, 0.798878314999999), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0.0706949, - 0.1267172, 0.1667331, 0.198582473624236, 0.225423180397104, 0.2494327, - 0.2707747, 0.292116312116921, 0.3121244, 0.3321324, 0.353072222341423, - 0.375089999249792, 0.3988256, 0.425831930221552, 0.459232792604326, - 0.501467782274773, 0.562188443556836, 0.685648485782108, 0.80647163752115, - 0.939224788489265), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0.0704696868359684, 0.121407167925079, - 0.161930580284053, 0.197682797539976, 0.228361656891269, - 0.257706650923509, 0.285717780926109, 0.3121244, 0.338115598498035, - 0.365749693067931, 0.395921877240673, 0.427437934626446, - 0.462388578749537, 0.504066064225642, 0.558443518811788, - 0.636013559040791, 0.771225883005179, 0.89210797204162, 1.02314875759509 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, - 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, - 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0.0247190015881658, 0.0834693973257732, - 0.131490031120311, 0.173258318827988, 0.211213742349423, - 0.246202447408474, 0.279926744217642, 0.3121244, 0.344908347408474, - 0.378255200773608, 0.412935547408474, 0.45191576510605, 0.494757615230152, - 0.545060918490786, 0.609312182129471, 0.69704881099591, 0.838550239412991, - 0.962653262246773, 1.11351403170759), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0.0501392705767058, - 0.104248897713977, 0.151994400390804, 0.195087767727627, 0.235544124698047, - 0.274058107118071, 0.3121244, 0.350571341810268, 0.390274666572666, - 0.43048632300908, 0.474320393891039, 0.523839613390634, 0.581010268149082, - 0.652137495469405, 0.748428674762348, 0.898563270096551, 1.03273295410124, - 1.19211145220822), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0.2148017, 0.31250597, 0.350183905, 0.3745639, - 0.3884161, 0.39746621, 0.404854, 0.4115031, 0.417413315, - 0.4218461, 0.426278885, 0.4321891, 0.4388382, 0.44622599, - 0.4552761, 0.4691283, 0.493508295, 0.53118623, 0.628890499999999, - 1.22043540499999, 1.95905017899999), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0.212369462232823, - 0.289571577546325, 0.324446887783878, 0.351262144469445, 0.37087, - 0.3863844, 0.399682509835098, 0.411036898891089, 0.4218461, 0.432927818676137, - 0.444338520819208, 0.4573077, 0.4728222, 0.492817749438994, 0.519442857224172, - 0.556165331447064, 0.635946057886079, 1.18402232252562, 1.7827032389242, - 2.5561261649726), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0.0413098183761837, 0.216633655848608, - 0.28006329699657, 0.3175577049983, 0.345923291761818, 0.368957399144641, - 0.38804556403724, 0.405400893204282, 0.4218461, 0.43864616004845, - 0.456105937661177, 0.475585378227632, 0.499018124730147, - 0.5270891900114, 0.564293444378844, 0.630730263388634, 0.898212235100651, - 1.53976520159876, 2.08228809477582, 2.80588762256078), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0.114729892920429, - 0.227785958288583, 0.282278878729037, 0.320407599201492, 0.350577823459785, - 0.376652303049231, 0.39981364198757, 0.4218461, 0.444009706175862, - 0.466962725214852, 0.493098379685547, 0.523708407392674, 0.562100740111401, - 0.619050517814778, 0.754868363055733, 1.1177263295869, 1.76277018354499, - 2.37278671910076, 2.9651652434047), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0.0100954501382014, - 0.165091099860099, 0.244964334392844, 0.294577054174442, 0.333357739419644, - 0.365251480804308, 0.394198909379894, 0.4218461, 0.449607812233022, - 0.479120513116631, 0.511271131674317, 0.5506402899964, 0.60295411796593, - 0.690751300611906, 0.913578722060166, 1.30856988553206, 1.94020220543606, - 2.57104934168037, 3.07139639379724), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.303454977, 0.3982330425, - 0.46791125, 0.57642367, 0.631462275, 0.6694025, 0.685048, 0.69857015, - 0.7085162, 0.71633898, 0.7252792, 0.7319844, 0.7386896, 0.74762982, - 0.7554526, 0.76539865, 0.7789208, 0.7945663, 0.832506525, 0.88754513, - 0.99605755, 1.0657357575, 1.160513823), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.188727136659627, - 0.292714653217782, 0.380882595473705, 0.476427609604196, 0.5464739, - 0.6001155, 0.636506664263643, 0.6638148, 0.684726301742618, 0.701811, - 0.7174565, 0.7319844, 0.7465124, 0.7621578, 0.779322149415794, - 0.800154, 0.826981204292293, 0.8649709, 0.918345662372574, 0.987315641681917, - 1.08210087899389, 1.17564510102166, 1.27428433325155), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.0928040444059739, - 0.212569233904214, 0.310718449102641, 0.418013562853928, 0.489917936424114, - 0.546885925424654, 0.593410228218282, 0.631406259421094, 0.661579628218282, - 0.687282906872069, 0.710456666258662, 0.7319844, 0.754131389282943, - 0.776685628218282, 0.802388976168662, 0.832758896293562, 0.869440928218282, - 0.916359694097141, 0.97403912794778, 1.04529048496565, 1.15710382277548, - 1.25675656404419, 1.37098330871205), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.0108404989744699, - 0.144337973117581, 0.250292371898569, 0.367310419323293, 0.44444044802193, - 0.506592035751958, 0.558428768125431, 0.602035095628756, 0.64112383905529, - 0.674354964141041, 0.703707875219752, 0.7319844, 0.760702196782168, - 0.789758264058441, 0.823427572594726, 0.860294897090771, 0.904032120658957, - 0.955736581115011, 1.0165945004053, 1.09529786576616, 1.21614421175967, - 1.32331604019295, 1.45293812780298), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0.0783919019408445, - 0.19440762901709, 0.323264916745368, 0.407999619319143, 0.474764568463685, - 0.530890671381964, 0.580852443909739, 0.623441748828038, 0.661393469870099, - 0.69827126098506, 0.7319844, 0.766440770218252, 0.802260162496625, - 0.840536805657307, 0.883133954556946, 0.931565607767828, 0.98815401699637, - 1.05406790404239, 1.138596250043, 1.27030064370239, 1.39007785503355, - 1.5343628053761), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0.012845105, 0.07040502, 0.09495188, 0.12669976, - 0.1502248, 0.1659163, 0.1761341, 0.18586528, 0.191290375, - 0.1975426, 0.203794825, 0.20921992, 0.2189511, 0.2291689, - 0.2448604, 0.26838544, 0.30013332, 0.32468018, 0.382240095, - 0.5020427625, 0.590302013999998), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0.0133856545472455, + 0.40216399, 0.512353658), c(0, 0, 0, 0, 0, 0.00331296053340532, + 0.0234804643776438, 0.0414109089650896, 0.0579040140087902, 0.0738391473860739, + 0.0882882738549385, 0.103199, 0.118522737211872, 0.134217143129031, + 0.15174910202592, 0.17076597900759, 0.192368859892349, 0.218887, + 0.254338497855279, 0.307871753369934, 0.407530532639726, 0.506824682189646, + 0.607973477267732), c(0, 0, 0, 0, 0, 0, 0, 0.0185864520320203, + 0.0411215858914089, 0.062281046686267, 0.0828222124563246, 0.103199, + 0.123575888447284, 0.144785989158292, 0.167277039342293, 0.192536265178252, + 0.221677797769728, 0.256887836856768, 0.302366681512415, 0.3669383199518, + 0.476508917333523, 0.574293059865274, 0.69194511433946), c(0, + 0, 0, 0, 0, 0, 0, 0, 0.0271019287070871, 0.0535555494987951, + 0.0785514374097741, 0.103199, 0.128043832742677, 0.154157375592856, + 0.181874602598776, 0.212708648669987, 0.247608381738568, 0.289082621291513, + 0.342486159511745, 0.41300665395314, 0.52870334697862, 0.634316186092986, + 0.767614547228429), c(0, 0, 0, 0, 0, 0, 0, 0, 0.0118725894981448, + 0.0439446210512103, 0.0736366703227029, 0.103199, 0.133138617710077, + 0.16357656105121, 0.19575459701827, 0.230475760859608, 0.269323345322203, + 0.314976554734947, 0.373424338576786, 0.452807955824158, 0.578141866759416, + 0.690542571738594, 0.837295153768033), c(0, 0, 0.0813658, 0.14899276, + 0.1960782, 0.22542314, 0.2414296, 0.25890318, 0.2747762, 0.2881148, + 0.3027873, 0.3121244, 0.3214615, 0.336134, 0.3494726, 0.36534562, + 0.3828192, 0.39882566, 0.4281706, 0.47525604, 0.542883, 0.682805397499999, + 0.798878314999999), c(0, 0, 0, 0.0706949, 0.1267172, 0.1667331, + 0.198582473624236, 0.225423180397104, 0.2494327, 0.2707747, 0.292116312116921, + 0.3121244, 0.3321324, 0.353072222341423, 0.375089999249792, 0.3988256, + 0.425831930221552, 0.459232792604326, 0.501467782274773, 0.562188443556836, + 0.685648485782108, 0.80647163752115, 0.939224788489265), c(0, + 0, 0, 0, 0.0704696868359684, 0.121407167925079, 0.161930580284053, + 0.197682797539976, 0.228361656891269, 0.257706650923509, 0.285717780926109, + 0.3121244, 0.338115598498035, 0.365749693067931, 0.395921877240673, + 0.427437934626446, 0.462388578749537, 0.504066064225642, 0.558443518811788, + 0.636013559040791, 0.771225883005179, 0.89210797204162, 1.02314875759509 + ), c(0, 0, 0, 0, 0.0247190015881658, 0.0834693973257732, 0.131490031120311, + 0.173258318827988, 0.211213742349423, 0.246202447408474, 0.279926744217642, + 0.3121244, 0.344908347408474, 0.378255200773608, 0.412935547408474, + 0.45191576510605, 0.494757615230152, 0.545060918490786, 0.609312182129471, + 0.69704881099591, 0.838550239412991, 0.962653262246773, 1.11351403170759 + ), c(0, 0, 0, 0, 0, 0.0501392705767058, 0.104248897713977, 0.151994400390804, + 0.195087767727627, 0.235544124698047, 0.274058107118071, 0.3121244, + 0.350571341810268, 0.390274666572666, 0.43048632300908, 0.474320393891039, + 0.523839613390634, 0.581010268149082, 0.652137495469405, 0.748428674762348, + 0.898563270096551, 1.03273295410124, 1.19211145220822), c(0, + 0, 0.2148017, 0.31250597, 0.350183905, 0.3745639, 0.3884161, + 0.39746621, 0.404854, 0.4115031, 0.417413315, 0.4218461, 0.426278885, + 0.4321891, 0.4388382, 0.44622599, 0.4552761, 0.4691283, 0.493508295, + 0.53118623, 0.628890499999999, 1.22043540499999, 1.95905017899999 + ), c(0, 0, 0, 0.212369462232823, 0.289571577546325, 0.324446887783878, + 0.351262144469445, 0.37087, 0.3863844, 0.399682509835098, 0.411036898891089, + 0.4218461, 0.432927818676137, 0.444338520819208, 0.4573077, 0.4728222, + 0.492817749438994, 0.519442857224172, 0.556165331447064, 0.635946057886079, + 1.18402232252562, 1.7827032389242, 2.5561261649726), c(0, 0, + 0, 0.0413098183761837, 0.216633655848608, 0.28006329699657, 0.3175577049983, + 0.345923291761818, 0.368957399144641, 0.38804556403724, 0.405400893204282, + 0.4218461, 0.43864616004845, 0.456105937661177, 0.475585378227632, + 0.499018124730147, 0.5270891900114, 0.564293444378844, 0.630730263388634, + 0.898212235100651, 1.53976520159876, 2.08228809477582, 2.80588762256078 + ), c(0, 0, 0, 0, 0.114729892920429, 0.227785958288583, 0.282278878729037, + 0.320407599201492, 0.350577823459785, 0.37665230304923, 0.39981364198757, + 0.4218461, 0.444009706175862, 0.466962725214852, 0.493098379685547, + 0.523708407392674, 0.562100740111401, 0.619050517814778, 0.754868363055733, + 1.1177263295869, 1.76277018354499, 2.37278671910076, 2.9651652434047 + ), c(0, 0, 0, 0, 0.0100954501382014, 0.165091099860099, 0.244964334392844, + 0.294577054174442, 0.333357739419644, 0.365251480804308, 0.394198909379894, + 0.4218461, 0.449607812233022, 0.479120513116631, 0.511271131674317, + 0.5506402899964, 0.60295411796593, 0.690751300611906, 0.913578722060166, + 1.30856988553206, 1.94020220543606, 2.57104934168037, 3.07139639379724 + ), c(0.303454977, 0.3982330425, 0.46791125, 0.57642367, 0.631462275, + 0.6694025, 0.685048, 0.69857015, 0.7085162, 0.71633898, 0.7252792, + 0.7319844, 0.7386896, 0.74762982, 0.7554526, 0.76539865, 0.7789208, + 0.7945663, 0.832506525, 0.88754513, 0.99605755, 1.0657357575, + 1.160513823), c(0.188727136659627, 0.292714653217782, 0.380882595473705, + 0.476427609604196, 0.5464739, 0.6001155, 0.636506664263643, 0.6638148, + 0.684726301742618, 0.701811, 0.7174565, 0.7319844, 0.7465124, + 0.7621578, 0.779322149415794, 0.800154, 0.826981204292293, 0.8649709, + 0.918345662372574, 0.987315641681917, 1.08210087899389, 1.17564510102166, + 1.27428433325155), c(0.0928040444059739, 0.212569233904214, 0.310718449102641, + 0.418013562853928, 0.489917936424114, 0.546885925424654, 0.593410228218282, + 0.631406259421094, 0.661579628218282, 0.687282906872069, 0.710456666258662, + 0.7319844, 0.754131389282943, 0.776685628218282, 0.802388976168662, + 0.832758896293562, 0.869440928218282, 0.916359694097141, 0.97403912794778, + 1.04529048496565, 1.15710382277548, 1.25675656404419, 1.37098330871205 + ), c(0.0108404989744699, 0.144337973117581, 0.250292371898569, + 0.367310419323293, 0.44444044802193, 0.506592035751958, 0.558428768125431, + 0.602035095628756, 0.64112383905529, 0.674354964141041, 0.703707875219752, + 0.7319844, 0.760702196782168, 0.78975826405844, 0.823427572594726, + 0.860294897090771, 0.904032120658957, 0.955736581115011, 1.0165945004053, + 1.09529786576616, 1.21614421175967, 1.32331604019295, 1.45293812780298 + ), c(0, 0.0783919019408445, 0.19440762901709, 0.323264916745368, + 0.407999619319143, 0.474764568463685, 0.530890671381964, 0.580852443909739, + 0.623441748828038, 0.661393469870099, 0.69827126098506, 0.7319844, + 0.766440770218252, 0.802260162496625, 0.840536805657307, 0.883133954556946, + 0.931565607767828, 0.98815401699637, 1.05406790404239, 1.138596250043, + 1.27030064370239, 1.39007785503355, 1.5343628053761), c(0, 0, + 0.012845105, 0.07040502, 0.09495188, 0.12669976, 0.1502248, 0.1659163, + 0.1761341, 0.18586528, 0.191290375, 0.1975426, 0.203794825, 0.20921992, + 0.2189511, 0.2291689, 0.2448604, 0.26838544, 0.30013332, 0.32468018, + 0.382240095, 0.5020427625, 0.590302013999998), c(0, 0, 0, 0.0133856545472455, 0.0528330564916649, 0.0825071163605637, 0.107217748074731, 0.130397558147181, 0.151367721571716, 0.1688357, 0.183736649076791, 0.1975426, 0.2111662, 0.226622576069161, 0.244738709634746, 0.265660771838618, 0.289502, 0.3157762, 0.347933515877459, 0.395446576674467, 0.494033943284933, - 0.586036939413118, 0.696507800090321), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0.0119984314577645, + 0.586036939413118, 0.696507800090321), c(0, 0, 0, 0, 0.0119984314577645, 0.0497573816250162, 0.081255049503995, 0.108502307388674, 0.132961558931189, 0.156011650575706, 0.177125892134071, 0.1975426, 0.217737120618906, 0.239458499211792, 0.263562581820818, 0.289525383565136, 0.31824420000725, - 0.351413051940519, 0.393862560773808, 0.453538799225292, 0.558631806850418, - 0.657452391363313, 0.767918764883928), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0.0189057930465303, + 0.35141305194052, 0.393862560773808, 0.453538799225292, 0.558631806850418, + 0.657452391363313, 0.767918764883928), c(0, 0, 0, 0, 0, 0.0189057930465303, 0.0558619823820737, 0.0885055048481483, 0.117823094349893, 0.145878789120691, 0.171852417645726, 0.1975426, 0.222526993865839, 0.249029206661066, 0.27731797305948, 0.306704680469104, 0.340659034209842, 0.379550761828618, 0.429562304567396, 0.499209921951019, 0.612206099576094, 0.713714149138691, - 0.835600324727346), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0, 0.0331956220262204, 0.0710455499705998, - 0.105140687231072, 0.136976315413355, 0.167518817907279, - 0.1975426, 0.226974062486675, 0.257640196272163, 0.289459502055271, - 0.323342029611596, 0.361500312536625, 0.407123841331413, - 0.46286764504675, 0.538379175655057, 0.659249503348734, 0.768470658367656, - 0.898774707571334), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr"))), class = c("distribution", - "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, + 0.835600324727346), c(0, 0, 0, 0, 0, 0, 0.0331956220262204, 0.0710455499705998, + 0.105140687231072, 0.136976315413355, 0.167518817907279, 0.1975426, + 0.226974062486675, 0.257640196272163, 0.289459502055271, 0.323342029611596, + 0.361500312536625, 0.407123841331413, 0.46286764504675, 0.538379175655057, + 0.659249503348734, 0.768470658367656, 0.898774707571334)), quantile_levels = c(0.01, + 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, + 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 + ), class = c("quantile_pred", "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, - 18992), class = "Date"), target_date = structure(c(18999, 19006, - 19013, 19020, 19027, 18999, 19006, 19013, 19020, 19027, 18999, + 18992, 18992), class = "Date"), target_date = structure(c(18999, 19006, 19013, 19020, 19027, 18999, 19006, 19013, 19020, 19027, 18999, 19006, 19013, 19020, 19027, 18999, 19006, 19013, 19020, - 19027), class = "Date")), row.names = c(NA, -30L), class = c("tbl_df", + 19027, 18999, 19006, 19013, 19020, 19027, 18999, 19006, 19013, + 19020, 19027), class = "Date")), row.names = c(NA, -30L), class = c("tbl_df", "tbl", "data.frame")) --- @@ -428,290 +254,167 @@ 0.7319844, 0.7319844, 0.7319844, 0.1975426, 0.1975426, 0.1975426, 0.1975426, 0.1975426), ahead = c(2L, 3L, 4L, 5L, 6L, 2L, 3L, 4L, 5L, 6L, 2L, 3L, 4L, 5L, 6L, 2L, 3L, 4L, 5L, 6L, 2L, 3L, 4L, - 5L, 6L, 2L, 3L, 4L, 5L, 6L), .pred_distn = structure(list(structure(list( - values = c(0, 0, 0, 0, 0.0344362435566855, 0.0610170086495865, - 0.0798865084778347, 0.0944014546310463, 0.107339121226462, - 0.11899734099851, 0.129600408649586, 0.1393442, 0.149195708649586, - 0.159627982246122, 0.170968308649587, 0.184031805880359, - 0.198909658094331, 0.219058736130861, 0.250692448549235, - 0.300646382944129, 0.368938143197633, 0.440038195052124, - 0.51997011826723), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0.0303364052628526, 0.0557306728227282, - 0.0766736159703596, 0.0942284381264812, 0.11050757203172, - 0.125214601455714, 0.1393442, 0.15359732398729, 0.168500447692877, - 0.184551468093631, 0.202926420944109, 0.22476606802393, 0.253070223293233, - 0.291229953951089, 0.341963643747938, 0.419747975311502, - 0.495994046054689, 0.5748791770223), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0.00603076915889168, - 0.0356039073625737, 0.0609470811194113, 0.0833232869645198, 0.103265350891109, - 0.121507077706427, 0.1393442, 0.157305073932789, 0.176004666813668, - 0.196866917086671, 0.219796529731897, 0.247137200365254, 0.280371254591746, - 0.320842872758278, 0.374783454750148, 0.461368597638526, 0.539683256474915, - 0.632562403391324), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0, 0.018869505399304, 0.0471517885822858, - 0.0732707765908659, 0.0969223475714758, 0.118188509171441, - 0.1393442, 0.161036861715017, 0.183255665579256, 0.207206810683007, - 0.23409988698267, 0.265549713886389, 0.302197074524145, 0.346715970732557, - 0.40460690801818, 0.498076490174802, 0.580016068409433, 0.680138975526255 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, - 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, - 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0, 0.00232218982614828, 0.0342017690820909, - 0.062828756299263, 0.0893725834453345, 0.114623710996309, - 0.1393442, 0.163790622390774, 0.189495107256772, 0.216754530328403, - 0.247065337260473, 0.281410456107061, 0.32037037400004, 0.367018829587046, - 0.431198706165962, 0.52829547296083, 0.619021148955337, 0.728730172315724 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, - 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, - 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0.00233673672776743, 0.0223488000000001, - 0.040304673503435, 0.0576262998104982, 0.0732741199141993, - 0.088455610793058, 0.103199, 0.118707592060121, 0.134185928864089, - 0.151183139276793, 0.1702454, 0.191937, 0.2182298, 0.253577609846549, - 0.307351538752588, 0.407165223924639, 0.502529513927214, - 0.605582108686126), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0, 0, 0.0190621000375005, 0.0420071558734088, - 0.0629230825705257, 0.0833688260410605, 0.103199, 0.124118509153392, - 0.145401945823358, 0.168667287877079, 0.1939090000375, 0.222597428173282, - 0.256984900377504, 0.301709122144422, 0.366495424858649, - 0.475152766217062, 0.572497835146252, 0.693762274318904), - quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, - 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0, 0, 0, 0.0269530072946728, 0.0530040092850928, - 0.0782481277003769, 0.103199, 0.12816325599641, 0.154866111682517, - 0.182302899107341, 0.213783044306043, 0.248363904708547, - 0.28995690796288, 0.341627908394784, 0.413707680386504, 0.528381820556805, - 0.635771182105746, 0.77652465912812), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0, 0, + 5L, 6L, 2L, 3L, 4L, 5L, 6L), .pred_distn = structure(list(c(0, + 0, 0, 0, 0.0344362435566855, 0.0610170086495865, 0.0798865084778347, + 0.0944014546310463, 0.107339121226462, 0.11899734099851, 0.129600408649586, + 0.1393442, 0.149195708649586, 0.159627982246122, 0.170968308649587, + 0.184031805880359, 0.198909658094331, 0.219058736130861, 0.250692448549235, + 0.300646382944129, 0.368938143197633, 0.440038195052124, 0.51997011826723 + ), c(0, 0, 0, 0, 0, 0.0303364052628526, 0.0557306728227282, 0.0766736159703596, + 0.0942284381264812, 0.11050757203172, 0.125214601455714, 0.1393442, + 0.15359732398729, 0.168500447692877, 0.184551468093631, 0.202926420944109, + 0.22476606802393, 0.253070223293233, 0.29122995395109, 0.341963643747938, + 0.419747975311502, 0.495994046054689, 0.5748791770223), c(0, + 0, 0, 0, 0, 0.00603076915889168, 0.0356039073625737, 0.0609470811194113, + 0.0833232869645198, 0.103265350891109, 0.121507077706427, 0.1393442, + 0.157305073932789, 0.176004666813668, 0.196866917086671, 0.219796529731897, + 0.247137200365254, 0.280371254591746, 0.320842872758278, 0.374783454750148, + 0.461368597638526, 0.539683256474915, 0.632562403391324), c(0, + 0, 0, 0, 0, 0, 0.018869505399304, 0.0471517885822858, 0.0732707765908659, + 0.0969223475714758, 0.118188509171441, 0.1393442, 0.161036861715017, + 0.183255665579256, 0.207206810683007, 0.23409988698267, 0.265549713886389, + 0.302197074524145, 0.346715970732557, 0.40460690801818, 0.498076490174802, + 0.580016068409433, 0.680138975526255), c(0, 0, 0, 0, 0, 0, 0.00232218982614828, + 0.0342017690820909, 0.062828756299263, 0.0893725834453345, 0.114623710996309, + 0.1393442, 0.163790622390774, 0.189495107256772, 0.216754530328403, + 0.247065337260473, 0.281410456107061, 0.32037037400004, 0.367018829587046, + 0.431198706165962, 0.52829547296083, 0.619021148955337, 0.728730172315724 + ), c(0, 0, 0, 0, 0, 0.00233673672776743, 0.0223488000000001, + 0.040304673503435, 0.0576262998104982, 0.0732741199141993, 0.088455610793058, + 0.103199, 0.118707592060121, 0.134185928864089, 0.151183139276793, + 0.1702454, 0.191937, 0.2182298, 0.253577609846549, 0.307351538752588, + 0.407165223924639, 0.502529513927214, 0.605582108686126), c(0, + 0, 0, 0, 0, 0, 0, 0.0190621000375005, 0.0420071558734088, 0.0629230825705257, + 0.0833688260410605, 0.103199, 0.124118509153392, 0.145401945823358, + 0.168667287877079, 0.1939090000375, 0.222597428173282, 0.256984900377504, + 0.301709122144422, 0.366495424858649, 0.475152766217062, 0.572497835146252, + 0.693762274318904), c(0, 0, 0, 0, 0, 0, 0, 0, 0.0269530072946728, + 0.0530040092850928, 0.0782481277003769, 0.103199, 0.12816325599641, + 0.154866111682517, 0.182302899107341, 0.213783044306043, 0.248363904708547, + 0.28995690796288, 0.341627908394784, 0.413707680386504, 0.528381820556805, + 0.635771182105746, 0.77652465912812), c(0, 0, 0, 0, 0, 0, 0, 0, 0.0133969262208122, 0.0447913089328894, 0.0739787251314013, 0.103199, 0.132965213784838, 0.163644939246192, 0.196475575572506, 0.231647450729907, 0.271208219491195, 0.317741925837459, 0.376214875186902, 0.454693715463155, 0.578781950822058, 0.695278060333427, 0.835521146843828 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, - 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0, 0, - 0, 0, 0, 0, 0, 0, 0.000725156354313476, 0.036290207696477, 0.0701157049196494, - 0.103199, 0.136581757676227, 0.170980571439515, 0.20778982998995, - 0.247087076718167, 0.291689672899979, 0.343587258527985, 0.406717577407724, - 0.490437549306793, 0.620305872542078, 0.740730855925609, 0.888992767585756 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, - 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0, 0, - 0, 0.0701359181289814, 0.126021564763798, 0.165542973066331, - 0.197412078824538, 0.2254231, 0.24849244896414, 0.271074448350284, - 0.292116376731667, 0.3121244, 0.3321324, 0.3534741, 0.375505591313813, - 0.4001594, 0.4268368, 0.459466546351464, 0.501142770839258, 0.562143084394445, - 0.686511993260583, 0.808747521078011, 0.936070949770187), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0.00157374045240457, - 0.0698662194634446, 0.120287640452405, 0.16090076400914, 0.195966561494315, - 0.227802919628796, 0.257250456567366, 0.284352940452404, 0.3121244, - 0.338954445099751, 0.366682808562485, 0.395431772465525, 0.428410340452405, - 0.464424683613586, 0.505774640452405, 0.559060310062401, 0.635868688255882, - 0.771213743700187, 0.895124744284645, 1.02835689610128), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0.0203251909788099, - 0.0807941084801849, 0.131156594663197, 0.173483742579226, 0.211670557196072, - 0.246244078609487, 0.278363918673537, 0.3121244, 0.345057130768308, - 0.378403757196072, 0.414130127568126, 0.451969178608786, 0.495598517595426, - 0.545136665227352, 0.60807806098831, 0.695394235571256, 0.837130344811698, - 0.966111057134121, 1.11185508502426), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0.0477276069251695, - 0.103509981435814, 0.15221877094871, 0.195952578625286, 0.236147272793828, - 0.274650521629366, 0.3121244, 0.349346986282313, 0.388561057230272, - 0.429378978625286, 0.474721256740267, 0.523806740641156, 0.581962784214742, - 0.652062951302463, 0.746838578625286, 0.896492945755508, 1.0340527654686, - 1.19219029825678), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0.0166039560593608, 0.0776387168354182, - 0.132003170161801, 0.180530886857168, 0.22594722201882, 0.268822337600976, - 0.3121244, 0.354489864523245, 0.398378553881739, 0.444274543339083, - 0.494499388431484, 0.548837448212482, 0.612239188685087, - 0.690272902609576, 0.790473599123991, 0.950950996975469, - 1.09638828065763, 1.26930966690442), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0.214450885057551, - 0.288864871241312, 0.3250653, 0.3516615, 0.3716087, 0.386718885323753, - 0.399682691320713, 0.411042976158862, 0.4218461, 0.4329278, 0.444139278140181, - 0.456951313505885, 0.4720835, 0.4920307, 0.518626803531635, 0.555566110165902, - 0.636745822624727, 1.18069710590251, 1.79487371178211, 2.55270530204625 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, - 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0, 0, + ), c(0, 0, 0, 0, 0, 0, 0, 0, 0.000725156354313476, 0.036290207696477, + 0.0701157049196494, 0.103199, 0.136581757676227, 0.170980571439515, + 0.20778982998995, 0.247087076718167, 0.291689672899979, 0.343587258527985, + 0.406717577407724, 0.490437549306793, 0.620305872542078, 0.740730855925609, + 0.888992767585756), c(0, 0, 0, 0.0701359181289814, 0.126021564763798, + 0.165542973066331, 0.197412078824538, 0.2254231, 0.24849244896414, + 0.271074448350284, 0.292116376731667, 0.3121244, 0.3321324, 0.3534741, + 0.375505591313813, 0.4001594, 0.4268368, 0.459466546351464, 0.501142770839258, + 0.562143084394445, 0.686511993260583, 0.808747521078011, 0.936070949770187 + ), c(0, 0, 0, 0.00157374045240457, 0.0698662194634446, 0.120287640452405, + 0.16090076400914, 0.195966561494315, 0.227802919628796, 0.257250456567366, + 0.284352940452404, 0.3121244, 0.338954445099751, 0.366682808562485, + 0.395431772465525, 0.428410340452405, 0.464424683613586, 0.505774640452405, + 0.559060310062401, 0.635868688255882, 0.771213743700187, 0.895124744284645, + 1.02835689610128), c(0, 0, 0, 0, 0.0203251909788099, 0.0807941084801849, + 0.131156594663197, 0.173483742579226, 0.211670557196072, 0.246244078609487, + 0.278363918673537, 0.3121244, 0.345057130768308, 0.378403757196072, + 0.414130127568126, 0.451969178608786, 0.495598517595426, 0.545136665227352, + 0.60807806098831, 0.695394235571256, 0.837130344811698, 0.966111057134121, + 1.11185508502426), c(0, 0, 0, 0, 0, 0.0477276069251695, 0.103509981435814, + 0.15221877094871, 0.195952578625286, 0.236147272793828, 0.274650521629366, + 0.3121244, 0.349346986282313, 0.388561057230272, 0.429378978625286, + 0.474721256740267, 0.523806740641156, 0.581962784214742, 0.652062951302463, + 0.746838578625286, 0.896492945755508, 1.0340527654686, 1.19219029825678 + ), c(0, 0, 0, 0, 0, 0.0166039560593608, 0.0776387168354182, 0.132003170161801, + 0.180530886857168, 0.22594722201882, 0.268822337600976, 0.3121244, + 0.354489864523245, 0.398378553881739, 0.444274543339083, 0.494499388431484, + 0.548837448212482, 0.612239188685087, 0.690272902609576, 0.790473599123991, + 0.950950996975469, 1.09638828065763, 1.26930966690442), c(0, + 0, 0, 0.214450885057551, 0.288864871241312, 0.3250653, 0.3516615, + 0.3716087, 0.386718885323753, 0.399682691320713, 0.411042976158862, + 0.4218461, 0.4329278, 0.444139278140181, 0.456951313505885, 0.4720835, + 0.4920307, 0.518626803531635, 0.555566110165902, 0.636745822624727, + 1.18069710590251, 1.79487371178211, 2.55270530204625), c(0, 0, 0, 0.0412188277837779, 0.218851219710947, 0.281178109847399, 0.318187061211362, 0.346336916208562, 0.368500427783778, 0.387753955899259, 0.405439627783778, 0.4218461, 0.438238911502765, 0.455473161565916, 0.474946888792488, 0.497793222697627, 0.526600327783778, 0.565677321171112, 0.632773149305243, 0.891087255237454, 1.53723873883164, 2.07877430490449, - 2.80265665435411), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0.11916637099981, 0.229217761668717, - 0.283591182792578, 0.32089403701397, 0.351025234947199, 0.376764238355684, - 0.399580647158371, 0.4218461, 0.44387311299288, 0.466809871716417, - 0.493008689720547, 0.523409488360383, 0.563157298622986, - 0.621505313473235, 0.756485815282202, 1.12190615310943, 1.76010655352564, - 2.36678033794496, 2.94420631979259), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0.0166944520132201, - 0.165418069472795, 0.245206977511275, 0.294705591133411, 0.333122440419504, - 0.365628706470365, 0.393898304736197, 0.4218461, 0.449111464628896, - 0.478419567119571, 0.511583967360174, 0.551380591704217, 0.602914542469175, - 0.695207681738717, 0.912006796599716, 1.31516316514125, 1.94296465866439, - 2.56528565211139, 3.07364144272118), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0.095868346511765, - 0.20216012803078, 0.267545492825128, 0.314290150935209, 0.353895445422154, - 0.388115128404834, 0.4218461, 0.455823761272913, 0.49135719600286, - 0.53249009905049, 0.582341165610556, 0.654473427614026, 0.784511194125441, - 1.05644872659752, 1.47044175860169, 2.09183984013705, 2.69484857437112, - 3.1694157654766), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.189889609612846, 0.28831400446517, 0.378590156778518, - 0.474951757151471, 0.546550271666467, 0.599713541496415, - 0.636994072140471, 0.663814888730087, 0.6839305, 0.701811, - 0.71711131701917, 0.7319844, 0.746512343291783, 0.7621579, - 0.7800383, 0.800154, 0.826974702066021, 0.86472325100111, - 0.918612458720487, 0.988605006042461, 1.08324298909714, 1.1736324426019, - 1.27400190201593), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.0970521814156041, 0.21019273451422, 0.3073217, - 0.418096666577866, 0.489016664299943, 0.547102113575136, - 0.594490775323003, 0.63162246104581, 0.661579866583116, 0.687283, - 0.709633785855109, 0.7319844, 0.754030577281223, 0.776967707389074, - 0.802389, 0.832791429272493, 0.870576437517875, 0.917019363782438, - 0.973069487834329, 1.04481411391714, 1.15502640396814, 1.25613855529213, - 1.37419193312441), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.0121672025865257, 0.139873460696682, 0.245836896475015, - 0.366700877088971, 0.445024777793378, 0.506295707796278, - 0.557812941319663, 0.601634091201612, 0.639324955546405, - 0.673001603565436, 0.702827370737707, 0.7319844, 0.760387153293983, - 0.790515252114921, 0.823330663438584, 0.86065768198682, 0.904468070814958, - 0.954989716167962, 1.01626566701207, 1.09352836237872, 1.21548452077266, - 1.32239947141536, 1.46006378366371), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0.0755189873928237, - 0.192404624794198, 0.322282766861868, 0.409749729479745, 0.475729034228042, - 0.531171513462134, 0.579442333436034, 0.623023292701627, 0.662178609529395, - 0.697968947885378, 0.7319844, 0.766345465406154, 0.80256496503135, - 0.841452466611966, 0.884524366576965, 0.93218174000415, 0.988252217755677, - 1.05297410373014, 1.13838991320473, 1.27210128334768, 1.38822119412612, - 1.53603026586717), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0.0137515321313713, 0.140785106599616, 0.283710273212032, - 0.374321519596796, 0.446394180252102, 0.505830587319873, - 0.559570052916329, 0.606684360953109, 0.65111343293503, 0.692845474832798, - 0.7319844, 0.771333743893139, 0.812267094081241, 0.855930534362644, - 0.903545840608706, 0.955193592261423, 1.01560313647486, 1.08583632750787, - 1.17818451335943, 1.31856131315813, 1.44615719776698, 1.60468791291453 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, - 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, - 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0.0124103998425985, 0.0518320161167612, - 0.0822283734557346, 0.106956582246572, 0.130236689538895, - 0.150852198845738, 0.168835673455735, 0.183678547429124, - 0.1975426, 0.211166273455735, 0.226249473455735, 0.243919155834858, - 0.265304527061771, 0.289781663064881, 0.315985067670677, - 0.347644682675627, 0.394981842425824, 0.491215248628636, - 0.584975102439074, 0.694697494489265), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0.0106056685868359, + 2.80265665435411), c(0, 0, 0, 0, 0.11916637099981, 0.229217761668717, + 0.283591182792578, 0.32089403701397, 0.351025234947199, 0.376764238355684, + 0.399580647158371, 0.4218461, 0.44387311299288, 0.466809871716417, + 0.493008689720547, 0.523409488360383, 0.563157298622986, 0.621505313473235, + 0.756485815282202, 1.12190615310943, 1.76010655352564, 2.36678033794496, + 2.94420631979259), c(0, 0, 0, 0, 0.0166944520132201, 0.165418069472795, + 0.245206977511275, 0.294705591133411, 0.333122440419504, 0.365628706470365, + 0.393898304736197, 0.4218461, 0.449111464628896, 0.478419567119571, + 0.511583967360174, 0.551380591704217, 0.602914542469175, 0.695207681738717, + 0.912006796599716, 1.31516316514125, 1.94296465866439, 2.56528565211139, + 3.07364144272118), c(0, 0, 0, 0, 0, 0.095868346511765, 0.20216012803078, + 0.267545492825128, 0.314290150935209, 0.353895445422154, 0.388115128404834, + 0.4218461, 0.455823761272913, 0.49135719600286, 0.53249009905049, + 0.582341165610556, 0.654473427614026, 0.784511194125441, 1.05644872659752, + 1.47044175860169, 2.09183984013705, 2.69484857437112, 3.1694157654766 + ), c(0.189889609612846, 0.28831400446517, 0.378590156778518, + 0.474951757151471, 0.546550271666467, 0.599713541496415, 0.636994072140471, + 0.663814888730087, 0.6839305, 0.701811, 0.71711131701917, 0.7319844, + 0.746512343291783, 0.7621579, 0.7800383, 0.800154, 0.826974702066021, + 0.86472325100111, 0.918612458720487, 0.988605006042461, 1.08324298909714, + 1.1736324426019, 1.27400190201593), c(0.0970521814156041, 0.21019273451422, + 0.3073217, 0.418096666577866, 0.489016664299943, 0.547102113575136, + 0.594490775323003, 0.63162246104581, 0.661579866583116, 0.687283, + 0.709633785855109, 0.7319844, 0.754030577281223, 0.776967707389074, + 0.802389, 0.832791429272493, 0.870576437517875, 0.917019363782438, + 0.973069487834329, 1.04481411391714, 1.15502640396814, 1.25613855529213, + 1.37419193312441), c(0.0121672025865257, 0.139873460696682, 0.245836896475015, + 0.366700877088971, 0.445024777793378, 0.506295707796278, 0.557812941319663, + 0.601634091201612, 0.639324955546405, 0.673001603565436, 0.702827370737707, + 0.7319844, 0.760387153293983, 0.790515252114921, 0.823330663438584, + 0.86065768198682, 0.904468070814958, 0.954989716167962, 1.01626566701207, + 1.09352836237872, 1.21548452077266, 1.32239947141536, 1.46006378366371 + ), c(0, 0.0755189873928237, 0.192404624794198, 0.322282766861868, + 0.409749729479745, 0.475729034228042, 0.531171513462134, 0.579442333436034, + 0.623023292701627, 0.662178609529395, 0.697968947885378, 0.7319844, + 0.766345465406154, 0.80256496503135, 0.841452466611966, 0.884524366576965, + 0.93218174000415, 0.988252217755677, 1.05297410373014, 1.13838991320473, + 1.27210128334768, 1.38822119412612, 1.53603026586717), c(0, 0.0137515321313713, + 0.140785106599616, 0.283710273212032, 0.374321519596796, 0.446394180252102, + 0.505830587319873, 0.559570052916329, 0.606684360953109, 0.65111343293503, + 0.692845474832798, 0.7319844, 0.771333743893139, 0.812267094081241, + 0.855930534362644, 0.903545840608706, 0.955193592261423, 1.01560313647486, + 1.08583632750787, 1.17818451335943, 1.31856131315813, 1.44615719776698, + 1.60468791291453), c(0, 0, 0, 0.0124103998425985, 0.0518320161167612, + 0.0822283734557346, 0.106956582246572, 0.130236689538895, 0.150852198845738, + 0.168835673455735, 0.183678547429124, 0.1975426, 0.211166273455735, + 0.226249473455735, 0.243919155834858, 0.265304527061771, 0.289781663064881, + 0.315985067670677, 0.347644682675627, 0.394981842425824, 0.491215248628636, + 0.584975102439074, 0.694697494489265), c(0, 0, 0, 0, 0.0106056685868359, 0.0491424720812208, 0.0803975947094471, 0.108060576398464, 0.133638500841809, 0.155968088623186, 0.177107275224252, 0.1975426, 0.218180906543366, 0.239601831646016, 0.262811949904799, 0.28886838404664, 0.317235975224252, 0.350545157867879, 0.393998327257523, 0.454550976564066, 0.558555075803007, - 0.656859449317743, 0.763718974419534), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0.0185370189554894, + 0.656859449317743, 0.763718974419534), c(0, 0, 0, 0, 0, 0.0185370189554894, 0.0562218087603375, 0.0890356919950198, 0.118731362266373, 0.146216910144001, 0.172533896645116, 0.1975426, 0.223021121504065, 0.249412654553045, 0.277680444480195, 0.308522683806638, 0.342270845449704, 0.382702709814398, - 0.433443929063141, 0.501610622734127, 0.614175801063261, 0.715138862353848, - 0.833535553075286), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0, 0.0346528073343234, 0.0723584880324803, - 0.106222897173122, 0.138467941096611, 0.167844669490445, - 0.1975426, 0.227591504589096, 0.258479799230192, 0.290862843650987, - 0.325718759418194, 0.364163081687565, 0.409581315443156, - 0.46531554698862, 0.54043504498905, 0.659111642885379, 0.761453612496025, - 0.889794566241181), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0, 0.0134397969692197, 0.0557212574100741, - 0.0941597345954959, 0.130401776157262, 0.164200585080601, - 0.1975426, 0.231566981332063, 0.265597088493385, 0.30192115798073, - 0.341652226704467, 0.384249568152932, 0.43541812199952, 0.495340659591346, - 0.575765691755518, 0.703032070294999, 0.815605113815338, - 0.955488202108743), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr"))), class = c("distribution", - "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, + 0.433443929063141, 0.501610622734127, 0.61417580106326, 0.715138862353848, + 0.833535553075286), c(0, 0, 0, 0, 0, 0, 0.0346528073343234, 0.0723584880324803, + 0.106222897173122, 0.138467941096611, 0.167844669490445, 0.1975426, + 0.227591504589096, 0.258479799230192, 0.290862843650987, 0.325718759418194, + 0.364163081687565, 0.409581315443156, 0.46531554698862, 0.54043504498905, + 0.659111642885379, 0.761453612496025, 0.889794566241181), c(0, + 0, 0, 0, 0, 0, 0.0134397969692197, 0.0557212574100741, 0.0941597345954959, + 0.130401776157262, 0.164200585080601, 0.1975426, 0.231566981332063, + 0.265597088493385, 0.30192115798073, 0.341652226704467, 0.384249568152932, + 0.43541812199952, 0.495340659591346, 0.575765691755518, 0.703032070294999, + 0.815605113815338, 0.955488202108743)), quantile_levels = c(0.01, + 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, + 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 + ), class = c("quantile_pred", "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, - 18992), class = "Date"), target_date = structure(c(19006, 19013, - 19020, 19027, 19034, 19006, 19013, 19020, 19027, 19034, 19006, + 18992, 18992), class = "Date"), target_date = structure(c(19006, 19013, 19020, 19027, 19034, 19006, 19013, 19020, 19027, 19034, 19006, 19013, 19020, 19027, 19034, 19006, 19013, 19020, 19027, - 19034), class = "Date")), row.names = c(NA, -30L), class = c("tbl_df", + 19034, 19006, 19013, 19020, 19027, 19034, 19006, 19013, 19020, + 19027, 19034), class = "Date")), row.names = c(NA, -30L), class = c("tbl_df", "tbl", "data.frame")) --- @@ -726,287 +429,180 @@ 0.7319844, 0.7319844, 0.7319844, 0.1975426, 0.1975426, 0.1975426, 0.1975426, 0.1975426), ahead = c(1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, - 4L, 5L, 1L, 2L, 3L, 4L, 5L), .pred_distn = structure(list(structure(list( - values = c(0, 0, 0.00812835000000001, 0.07297428, 0.0936219, - 0.10421786, 0.1121285, 0.1201118, 0.1273693, 0.1317238, 0.1360783, - 0.1393442, 0.1426101, 0.1469646, 0.1513191, 0.1585766, 0.1665599, - 0.17447054, 0.1850665, 0.20571412, 0.27056005, 0.313941744999999, - 0.384931126999997), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0.0250982954899548, 0.0576421230361804, - 0.0776985410529105, 0.0929731777892779, 0.104205115094451, - 0.114209292598776, 0.123365027741977, 0.131496226094211, - 0.1393442, 0.147007648291083, 0.154990950042, 0.16406284204392, - 0.173835548288583, 0.185472494222942, 0.200167568392984, - 0.221760005190952, 0.260313716029161, 0.318794320716957, - 0.376941794597195, 0.461705276864399), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0.028693230499105, - 0.055453963203632, 0.0755679534410344, 0.0913921813275133, 0.104804902302573, - 0.117142722458225, 0.128444430213702, 0.1393442, 0.150479535783308, - 0.161776522458225, 0.173925041831968, 0.187540579925299, 0.204200618941439, - 0.225353161205212, 0.253695961466565, 0.294498109305393, 0.358245879234942, - 0.427563795224327, 0.501665748776186), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0.00587171510650109, - 0.0364866623781238, 0.0602683002957529, 0.0794861096145961, 0.0963414561651617, - 0.111439230212802, 0.125394639614746, 0.1393442, 0.153216527502025, - 0.167801944181742, 0.183359587288923, 0.200880434888349, 0.221656465706657, - 0.24743726609676, 0.279449270180852, 0.322415149384594, 0.395367499639696, - 0.464904880713406, 0.539558052669137), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0.019055042091221, - 0.0457625510440105, 0.068309473710537, 0.087945102194822, 0.106033592330923, - 0.123045226382564, 0.1393442, 0.155351600131351, 0.172491058371384, - 0.19101350900654, 0.211425349928599, 0.234936300692507, 0.264303292652126, - 0.299599722715327, 0.346282638921389, 0.423857010226352, 0.494689091614341, - 0.577833814673327), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0.00138033000000002, 0.030893965, 0.0479842, - 0.059815975, 0.07118759, 0.0815075, 0.0926819, 0.0992551, - 0.103199, 0.1071429, 0.1137161, 0.1248905, 0.13521041, 0.146582025, - 0.1584138, 0.175504035, 0.20501767, 0.25694586, 0.335051815, - 0.436709474), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0.0179658025100251, 0.0356060154111541, + 4L, 5L, 1L, 2L, 3L, 4L, 5L), .pred_distn = structure(list(c(0, + 0, 0.00812835000000001, 0.07297428, 0.0936219, 0.10421786, 0.1121285, + 0.1201118, 0.1273693, 0.1317238, 0.1360783, 0.1393442, 0.1426101, + 0.1469646, 0.1513191, 0.1585766, 0.1665599, 0.17447054, 0.1850665, + 0.20571412, 0.27056005, 0.313941744999999, 0.384931126999997), + c(0, 0, 0, 0.0250982954899548, 0.0576421230361804, 0.0776985410529105, + 0.0929731777892779, 0.104205115094451, 0.114209292598776, + 0.123365027741977, 0.131496226094211, 0.1393442, 0.147007648291083, + 0.154990950042, 0.16406284204392, 0.173835548288583, 0.185472494222942, + 0.200167568392984, 0.221760005190952, 0.260313716029161, + 0.318794320716957, 0.376941794597195, 0.461705276864399), + c(0, 0, 0, 0, 0.028693230499105, 0.055453963203632, 0.0755679534410344, + 0.0913921813275133, 0.104804902302573, 0.117142722458225, + 0.128444430213702, 0.1393442, 0.150479535783308, 0.161776522458225, + 0.173925041831968, 0.187540579925299, 0.204200618941439, + 0.225353161205212, 0.253695961466565, 0.294498109305393, + 0.358245879234942, 0.427563795224327, 0.501665748776186), + c(0, 0, 0, 0, 0.00587171510650109, 0.0364866623781238, 0.0602683002957529, + 0.0794861096145961, 0.0963414561651617, 0.111439230212802, + 0.125394639614746, 0.1393442, 0.153216527502025, 0.167801944181742, + 0.183359587288923, 0.200880434888349, 0.221656465706657, + 0.24743726609676, 0.279449270180852, 0.322415149384594, 0.395367499639696, + 0.464904880713406, 0.539558052669137), c(0, 0, 0, 0, 0, 0.019055042091221, + 0.0457625510440105, 0.068309473710537, 0.087945102194822, + 0.106033592330923, 0.123045226382564, 0.1393442, 0.155351600131351, + 0.172491058371384, 0.19101350900654, 0.211425349928599, 0.234936300692507, + 0.264303292652126, 0.299599722715327, 0.346282638921389, + 0.423857010226352, 0.494689091614341, 0.577833814673327), + c(0, 0, 0, 0.00138033000000002, 0.030893965, 0.0479842, 0.059815975, + 0.07118759, 0.0815075, 0.0926819, 0.0992551, 0.103199, 0.1071429, + 0.1137161, 0.1248905, 0.13521041, 0.146582025, 0.1584138, + 0.175504035, 0.20501767, 0.25694586, 0.335051815, 0.436709474 + ), c(0, 0, 0, 0, 0, 0.0179658025100251, 0.0356060154111541, 0.050834301692017, 0.0650050989327893, 0.0784417069434695, 0.0916422518458685, 0.103199, 0.115251501692017, 0.128398001692017, 0.142201701692017, 0.157319973859039, 0.174980914065641, 0.196101805086251, 0.223989860848608, 0.266334685464555, 0.354050965519204, 0.437948459272293, 0.520203978940639), - quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, - 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0, 0.0134241653129031, 0.0338447112456125, + c(0, 0, 0, 0, 0, 0, 0.0134241653129031, 0.0338447112456125, 0.052643303388484, 0.0699345638167383, 0.0866373614747148, 0.103199, 0.119627111136411, 0.137401026927169, 0.156056395793358, 0.175781901322513, 0.198564535163602, 0.226934571881819, 0.263862501322513, 0.317121769745397, 0.412419996940619, - 0.491470213131306, 0.580892509639735), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0, 0, - 0.0170903, 0.0403385023363734, 0.0616387632732329, 0.0827585779094291, - 0.103199, 0.123094939420544, 0.14464638301663, 0.1669589, 0.191770645535455, - 0.220735117412174, 0.254231042750228, 0.296807527848978, 0.357153759489695, - 0.45347931404539, 0.538725322834228, 0.636530647411066), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0, 0, 0, - 0.0026415954262542, 0.0297423239924899, 0.0555402340406406, 0.0792255827466275, - 0.103199, 0.127366925585556, 0.151700351432014, 0.177708522618176, - 0.206088123699737, 0.238712707453825, 0.277708313715037, 0.325132239647296, - 0.390468252727729, 0.490417296529864, 0.578557086846368, 0.688679948593326 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, - 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0, 0.0320461375000001, - 0.129384955, 0.18940881, 0.2200878, 0.2427634, 0.2587698, 0.2734423, - 0.2841133, 0.296118, 0.3041212, 0.3121244, 0.3201276, 0.3281308, - 0.3401355, 0.3508065, 0.365479, 0.3814854, 0.404161, 0.43483999, - 0.494863845, 0.592202662499998, 0.737413847999994), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0.0319186440152902, - 0.118606588418984, 0.166386434627046, 0.198884154069741, 0.224089313858389, - 0.245418255377554, 0.2641052, 0.281445422925429, 0.297451875378704, - 0.3121244, 0.327667648091081, 0.343487967727477, 0.360314881408664, - 0.379575527422374, 0.400991145952209, 0.426605204088841, 0.4588495, - 0.506128350755908, 0.604640728888889, 0.713520019350718, 0.848429920658984 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, - 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0, 0, - 0, 0.0628145244703447, 0.119951261697167, 0.161800708429584, - 0.194481529786298, 0.221976473503235, 0.246382528361484, 0.268661795456855, - 0.29099237601426, 0.3121244, 0.332687273503235, 0.354487379145491, - 0.376704773503235, 0.401222379758598, 0.428725473503235, 0.462071908680987, - 0.503745448659536, 0.564825512591627, 0.677307126205362, 0.788889302835928, - 0.92389000979736), quantile_levels = c(0.01, 0.025, 0.05, 0.1, - 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, - 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0.0154147362739629, 0.0815589624901754, - 0.130419447103471, 0.16933591200637, 0.202296191455315, 0.23230661698317, - 0.260103744489245, 0.28583424396924, 0.3121244, 0.337226511153312, - 0.3628113, 0.3894886, 0.419049975899859, 0.453339140405904, - 0.492830630339104, 0.542883079890499, 0.613577832767128, - 0.73571689900399, 0.853844909059791, 0.988010467319443), - quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, - 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0.0493531737111374, 0.104172112803728, - 0.147940700281253, 0.185518687303273, 0.220197034594646, - 0.2521005, 0.282477641919719, 0.3121244, 0.3414694, 0.371435390499905, - 0.402230766363414, 0.436173824348844, 0.474579164424894, - 0.519690345185252, 0.576673752066771, 0.655151246845668, - 0.78520792902029, 0.90968118047453, 1.05112182091783), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0.28439515, 0.33688581, - 0.369872555, 0.3863845, 0.3945111, 0.40189893, 0.4078092, 0.4137194, - 0.4174134, 0.4218461, 0.4262788, 0.4299728, 0.435883, 0.44179327, - 0.4491811, 0.4573077, 0.473819645, 0.50680639, 0.55929705, 0.9841905175, - 1.556671116), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, - 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, - 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0.003694, 0.268840486221162, 0.320208490155752, + 0.491470213131306, 0.580892509639735), c(0, 0, 0, 0, 0, 0, + 0, 0.0170903, 0.0403385023363734, 0.0616387632732329, 0.0827585779094291, + 0.103199, 0.123094939420544, 0.14464638301663, 0.1669589, + 0.191770645535455, 0.220735117412174, 0.254231042750228, + 0.296807527848978, 0.357153759489695, 0.45347931404539, 0.538725322834228, + 0.636530647411066), c(0, 0, 0, 0, 0, 0, 0, 0.0026415954262542, + 0.0297423239924899, 0.0555402340406406, 0.0792255827466275, + 0.103199, 0.127366925585556, 0.151700351432014, 0.177708522618176, + 0.206088123699737, 0.238712707453825, 0.277708313715037, + 0.325132239647296, 0.390468252727729, 0.490417296529864, + 0.578557086846368, 0.688679948593326), c(0, 0.0320461375000001, + 0.129384955, 0.18940881, 0.2200878, 0.2427634, 0.2587698, + 0.2734423, 0.2841133, 0.296118, 0.3041212, 0.3121244, 0.3201276, + 0.3281308, 0.3401355, 0.3508065, 0.365479, 0.3814854, 0.404161, + 0.43483999, 0.494863845, 0.592202662499998, 0.737413847999994 + ), c(0, 0, 0.0319186440152902, 0.118606588418984, 0.166386434627046, + 0.198884154069741, 0.224089313858389, 0.245418255377554, + 0.2641052, 0.281445422925429, 0.297451875378704, 0.3121244, + 0.327667648091081, 0.343487967727477, 0.360314881408664, + 0.379575527422374, 0.400991145952209, 0.426605204088841, + 0.4588495, 0.506128350755908, 0.604640728888889, 0.713520019350718, + 0.848429920658984), c(0, 0, 0, 0.0628145244703447, 0.119951261697167, + 0.161800708429584, 0.194481529786298, 0.221976473503235, + 0.246382528361484, 0.268661795456855, 0.29099237601426, 0.3121244, + 0.332687273503235, 0.354487379145491, 0.376704773503235, + 0.401222379758598, 0.428725473503235, 0.462071908680987, + 0.503745448659536, 0.564825512591627, 0.677307126205362, + 0.788889302835928, 0.92389000979736), c(0, 0, 0, 0.0154147362739629, + 0.0815589624901754, 0.130419447103471, 0.16933591200637, + 0.202296191455315, 0.23230661698317, 0.260103744489245, 0.28583424396924, + 0.3121244, 0.337226511153312, 0.3628113, 0.3894886, 0.419049975899859, + 0.453339140405904, 0.492830630339104, 0.542883079890499, + 0.613577832767128, 0.73571689900399, 0.853844909059791, 0.988010467319443 + ), c(0, 0, 0, 0, 0.0493531737111374, 0.104172112803728, 0.147940700281253, + 0.185518687303273, 0.220197034594646, 0.2521005, 0.282477641919719, + 0.3121244, 0.3414694, 0.371435390499905, 0.402230766363414, + 0.436173824348844, 0.474579164424894, 0.519690345185252, + 0.57667375206677, 0.655151246845668, 0.78520792902029, 0.90968118047453, + 1.05112182091783), c(0, 0, 0.28439515, 0.33688581, 0.369872555, + 0.3863845, 0.3945111, 0.40189893, 0.4078092, 0.4137194, 0.4174134, + 0.4218461, 0.4262788, 0.4299728, 0.435883, 0.44179327, 0.4491811, + 0.4573077, 0.473819645, 0.50680639, 0.55929705, 0.9841905175, + 1.556671116), c(0, 0, 0.003694, 0.268840486221162, 0.320208490155752, 0.34804029700677, 0.368653615349654, 0.3834292, 0.3945111, 0.4041153, 0.413171785132151, 0.4218461, 0.430424661802068, 0.4395769, 0.4491812, 0.4610017, 0.47590450199302, 0.497193409669697, 0.525275921931869, 0.57616046396334, 0.97179808113241, 1.42880557869041, - 2.00265362857685), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0.0925362072632727, 0.270427502912579, + 2.00265362857685), c(0, 0, 0, 0.0925362072632727, 0.270427502912579, 0.315212102423624, 0.343335698090731, 0.364285966419164, 0.381412585636556, 0.3959887, 0.4092868, 0.4218461, 0.4344055, 0.447738051828318, 0.4632179, 0.480948870517105, 0.502553166907419, 0.531676966454865, 0.576804782629326, 0.776643061384413, - 1.21840177544959, 1.666716830807, 2.19163048441111), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, - 0.99)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0.186887482630176, - 0.277238777881179, 0.317854348809488, 0.345779327332173, 0.367941987952029, - 0.38755201396574, 0.405055828677287, 0.4218461, 0.438666668060931, - 0.456611962704227, 0.476718028677287, 0.499751625882259, 0.528508989683397, - 0.569810205861059, 0.666081219804098, 0.934028445917159, 1.42658287124316, - 1.85311957889209, 2.30760254154095), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0, 0, 0.0845659921302213, - 0.228553649752897, 0.289236861333113, 0.326073140839108, 0.354785333802038, - 0.379166830409904, 0.401230227456875, 0.4218461, 0.442801275729157, - 0.465572618600986, 0.490133389090691, 0.520052318734487, 0.558588500497255, - 0.62065225601836, 0.788392143304334, 1.05428294678997, 1.55684044507063, - 2.01374350966068, 2.37954449328776), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.33818795, 0.4386877525, - 0.528816855, 0.61252005, 0.6626973, 0.6816954, 0.697340875, 0.7085162, - 0.7152214, 0.7208091, 0.72745833, 0.7319844, 0.73651047, 0.7431597, - 0.7487474, 0.7554526, 0.766627925, 0.7822734, 0.8012715, 0.85144875, - 0.935151945, 1.0252810475, 1.12578085), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.276821846502455, - 0.354318476867519, 0.440270225449805, 0.533132934163242, 0.5900576, - 0.631102729748298, 0.660462274661497, 0.680831108876989, 0.696223359635746, - 0.7096337, 0.7219265, 0.7319844, 0.7431597, 0.7543351, 0.7677455, - 0.783391, 0.804046832839828, 0.833541896886769, 0.873735298798638, - 0.929106903073231, 1.02188617627186, 1.10971107833641, 1.18626816850867 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, - 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, - 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0.202265200637946, - 0.298325094034965, 0.380907645938709, 0.481339524857949, 0.543219696138311, - 0.589507953775938, 0.6258186, 0.654874580912809, 0.6783427, 0.6984583, - 0.715655544727447, 0.7319844, 0.7487473, 0.7666278, 0.785715489951649, - 0.8090941, 0.83815, 0.873623567291473, 0.920206978680437, 0.98231174201862, - 1.08425930872329, 1.16639411427812, 1.25926838507547), quantile_levels = c(0.01, + 1.21840177544959, 1.666716830807, 2.19163048441111), c(0, + 0, 0, 0, 0.186887482630176, 0.277238777881179, 0.317854348809488, + 0.345779327332173, 0.367941987952029, 0.38755201396574, 0.405055828677287, + 0.4218461, 0.438666668060931, 0.456611962704227, 0.476718028677287, + 0.499751625882259, 0.528508989683397, 0.569810205861059, + 0.666081219804098, 0.934028445917159, 1.42658287124316, 1.85311957889209, + 2.30760254154095), c(0, 0, 0, 0, 0.0845659921302213, 0.228553649752897, + 0.289236861333113, 0.326073140839108, 0.354785333802038, + 0.379166830409904, 0.401230227456875, 0.4218461, 0.442801275729157, + 0.465572618600986, 0.490133389090691, 0.520052318734487, + 0.558588500497255, 0.62065225601836, 0.788392143304334, 1.05428294678997, + 1.55684044507063, 2.01374350966068, 2.37954449328776), c(0.33818795, + 0.4386877525, 0.528816855, 0.61252005, 0.6626973, 0.6816954, + 0.697340875, 0.7085162, 0.7152214, 0.7208091, 0.72745833, + 0.7319844, 0.73651047, 0.7431597, 0.7487474, 0.7554526, 0.766627925, + 0.7822734, 0.8012715, 0.85144875, 0.935151945, 1.0252810475, + 1.12578085), c(0.276821846502455, 0.354318476867519, 0.440270225449805, + 0.533132934163242, 0.5900576, 0.631102729748298, 0.660462274661497, + 0.680831108876989, 0.696223359635746, 0.7096337, 0.7219265, + 0.7319844, 0.7431597, 0.7543351, 0.7677455, 0.783391, 0.804046832839828, + 0.833541896886769, 0.873735298798638, 0.929106903073231, + 1.02188617627186, 1.10971107833641, 1.18626816850867), c(0.202265200637946, + 0.298325094034965, 0.380907645938709, 0.481339524857949, + 0.543219696138311, 0.589507953775938, 0.6258186, 0.654874580912809, + 0.6783427, 0.6984583, 0.715655544727447, 0.7319844, 0.7487473, + 0.7666278, 0.785715489951649, 0.8090941, 0.83815, 0.873623567291473, + 0.920206978680437, 0.98231174201862, 1.08425930872329, 1.16639411427812, + 1.25926838507547), c(0.129193504425124, 0.241744300793533, + 0.331949483165032, 0.43649858695157, 0.504472062268773, 0.556141464729147, + 0.597172505336053, 0.631406591640416, 0.660898437441874, + 0.686684727470375, 0.709633972330423, 0.7319844, 0.753217699696647, + 0.77608746100351, 0.8012715950276, 0.830327492252422, 0.86464477397774, + 0.906319686121761, 0.956815387818928, 1.02495125855129, 1.13129413647201, + 1.21644533535035, 1.32424172966634), c(0.0667682979050189, + 0.189580042212397, 0.290485041721667, 0.402951609190092, + 0.475328740486855, 0.530590906520765, 0.575504908587586, + 0.613421932920829, 0.647285177364573, 0.678099283398734, + 0.70593862799773, 0.7319844, 0.758701322488325, 0.786639532920829, + 0.816837200234752, 0.850627936753767, 0.888963924063491, + 0.933785069065791, 0.988913131611816, 1.06240172852619, 1.16959624730917, + 1.2662008825538, 1.38860505690239), c(0, 0, 0.0419413650000001, + 0.09882005, 0.1230992, 0.14226962, 0.1600776, 0.1722416, + 0.1800265, 0.1880061, 0.1936501, 0.1975426, 0.2014351, 0.2070791, + 0.2150587, 0.2228436, 0.2350076, 0.25281558, 0.271986, 0.29626515, + 0.353143835, 0.4353357125, 0.545314878), c(0, 0, 0, 0.0438463650372504, + 0.0808594787511875, 0.106995615813358, 0.127478232938079, + 0.145480846633466, 0.1610508, 0.17461199504795, 0.186668812203222, + 0.1975426, 0.208428571374764, 0.2204108, 0.233930283744537, + 0.249894552784127, 0.267362348440485, 0.288755575723157, + 0.316120297580926, 0.355450425419354, 0.443192503687136, + 0.536871211931719, 0.636344785545224), c(0, 0, 0, 0.00188932708477086, + 0.0470905919531195, 0.079226864399944, 0.105414109111591, + 0.127225815559956, 0.146699420891509, 0.164644114298843, + 0.18142942603581, 0.1975426, 0.213933119201142, 0.231001630488804, + 0.24941229702312, 0.269578845560456, 0.292362546530965, 0.319632071367214, + 0.354433951358713, 0.406915236639266, 0.506944745332152, + 0.596044605353528, 0.695533388807317), c(0, 0, 0, 0, 0.0156342454546545, + 0.0536811248488485, 0.084228833507335, 0.110407751354614, + 0.134410113872139, 0.156669167575476, 0.177701902429674, + 0.1975426, 0.217759024165492, 0.238897316673167, 0.261484572608426, + 0.286120039498095, 0.313065324705997, 0.345395334882349, + 0.386811116673167, 0.44780805303823, 0.550781846423163, 0.644984940689833, + 0.752937731654986), c(0, 0, 0, 0, 0, 0.0290260214229144, + 0.0653218111708617, 0.0966336637233373, 0.124670861123061, + 0.149775978614687, 0.174275935467055, 0.1975426, 0.221291415429954, + 0.246723385601356, 0.273144383515685, 0.30101566402084, 0.33204051788793, + 0.369730347126771, 0.416909038104281, 0.481925596660567, + 0.58989871202142, 0.688635568252056, 0.803906183401304)), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.129193504425124, - 0.241744300793533, 0.331949483165032, 0.43649858695157, 0.504472062268773, - 0.556141464729147, 0.597172505336053, 0.631406591640416, 0.660898437441874, - 0.686684727470375, 0.709633972330423, 0.7319844, 0.753217699696647, - 0.77608746100351, 0.8012715950276, 0.830327492252422, 0.86464477397774, - 0.906319686121761, 0.956815387818928, 1.02495125855129, 1.13129413647201, - 1.21644533535035, 1.32424172966634), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.0667682979050189, - 0.189580042212397, 0.290485041721667, 0.402951609190092, 0.475328740486855, - 0.530590906520765, 0.575504908587586, 0.613421932920829, 0.647285177364573, - 0.678099283398734, 0.70593862799773, 0.7319844, 0.758701322488325, - 0.786639532920829, 0.816837200234752, 0.850627936753767, 0.888963924063491, - 0.933785069065791, 0.988913131611816, 1.06240172852619, 1.16959624730917, - 1.2662008825538, 1.38860505690239), quantile_levels = c(0.01, - 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, - 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99 - )), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0, 0, 0.0419413650000001, - 0.09882005, 0.1230992, 0.14226962, 0.1600776, 0.1722416, 0.1800265, - 0.1880061, 0.1936501, 0.1975426, 0.2014351, 0.2070791, 0.2150587, - 0.2228436, 0.2350076, 0.25281558, 0.271986, 0.29626515, 0.353143835, - 0.4353357125, 0.545314878), quantile_levels = c(0.01, 0.025, - 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, - 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0.0438463650372504, 0.0808594787511875, - 0.106995615813358, 0.127478232938079, 0.145480846633466, - 0.1610508, 0.17461199504795, 0.186668812203222, 0.1975426, - 0.208428571374764, 0.2204108, 0.233930283744537, 0.249894552784127, - 0.267362348440485, 0.288755575723157, 0.316120297580926, - 0.355450425419354, 0.443192503687136, 0.536871211931719, - 0.636344785545224), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0.00188932708477086, 0.0470905919531195, - 0.079226864399944, 0.105414109111591, 0.127225815559956, - 0.146699420891509, 0.164644114298843, 0.18142942603581, 0.1975426, - 0.213933119201142, 0.231001630488804, 0.24941229702312, 0.269578845560456, - 0.292362546530965, 0.319632071367214, 0.354433951358713, - 0.406915236639266, 0.506944745332152, 0.596044605353528, - 0.695533388807317), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0.0156342454546545, 0.0536811248488485, - 0.084228833507335, 0.110407751354614, 0.134410113872139, - 0.156669167575476, 0.177701902429674, 0.1975426, 0.217759024165492, - 0.238897316673167, 0.261484572608426, 0.286120039498095, - 0.313065324705997, 0.345395334882349, 0.386811116673167, - 0.44780805303823, 0.550781846423163, 0.644984940689833, 0.752937731654986 - ), quantile_levels = c(0.01, 0.025, 0.05, 0.1, 0.15, 0.2, - 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, - 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0, 0, 0, 0, 0, 0.0290260214229144, 0.0653218111708617, - 0.0966336637233373, 0.124670861123061, 0.149775978614687, - 0.174275935467055, 0.1975426, 0.221291415429954, 0.246723385601356, - 0.273144383515685, 0.30101566402084, 0.33204051788793, 0.369730347126771, - 0.416909038104281, 0.481925596660567, 0.58989871202142, 0.688635568252056, - 0.803906183401304), quantile_levels = c(0.01, 0.025, 0.05, - 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, - 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.975, 0.99)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr"))), class = c("distribution", - "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, + ), class = c("quantile_pred", "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, 18992, - 18992), class = "Date"), target_date = structure(c(18997, 19002, - 19007, 19012, 19017, 18997, 19002, 19007, 19012, 19017, 18997, + 18992, 18992), class = "Date"), target_date = structure(c(18997, 19002, 19007, 19012, 19017, 18997, 19002, 19007, 19012, 19017, 18997, 19002, 19007, 19012, 19017, 18997, 19002, 19007, 19012, - 19017), class = "Date")), row.names = c(NA, -30L), class = c("tbl_df", + 19017, 18997, 19002, 19007, 19012, 19017, 18997, 19002, 19007, + 19012, 19017), class = "Date")), row.names = c(NA, -30L), class = c("tbl_df", "tbl", "data.frame")) # arx_forecaster snapshots @@ -1014,37 +610,23 @@ structure(list(geo_value = c("ca", "fl", "ga", "ny", "pa", "tx" ), .pred = c(0.353013358779435, 0.648525432444877, 0.667670289394328, 1.1418673907239, 0.830448695683587, 0.329799431948649), .pred_distn = structure(list( - structure(list(values = c(0.171022956902288, 0.244945899624723, - 0.308032696431071, 0.353013358779435, 0.397994021127798, - 0.461080817934147, 0.535003760656582), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.46653503056773, 0.540457973290166, 0.603544770096514, - 0.648525432444877, 0.693506094793241, 0.756592891599589, - 0.830515834322024), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0.485679887517181, + c(0.171022956902288, 0.244945899624723, 0.308032696431071, + 0.353013358779435, 0.397994021127798, 0.461080817934147, + 0.535003760656582), c(0.46653503056773, 0.540457973290166, + 0.603544770096514, 0.648525432444877, 0.693506094793241, + 0.756592891599589, 0.830515834322024), c(0.485679887517181, 0.559602830239616, 0.622689627045964, 0.667670289394328, 0.712650951742692, 0.77573774854904, 0.849660691271475), - quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, 0.9, - 0.95)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.959876988846753, - 1.03379993156919, 1.09688672837554, 1.1418673907239, 1.18684805307226, - 1.24993484987861, 1.32385779260105), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.64845829380644, 0.722381236528875, 0.785468033335223, - 0.830448695683587, 0.875429358031951, 0.938516154838299, - 1.01243909756073), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0.147809030071502, - 0.221731972793937, 0.284818769600285, 0.329799431948649, - 0.374780094297013, 0.437866891103361, 0.511789833825796), - quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, 0.9, - 0.95)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr"))), class = c("distribution", "vctrs_vctr", - "list")), forecast_date = structure(c(18992, 18992, 18992, 18992, - 18992, 18992), class = "Date"), target_date = structure(c(18999, + c(0.959876988846753, 1.03379993156919, 1.09688672837554, + 1.1418673907239, 1.18684805307226, 1.24993484987861, 1.32385779260105 + ), c(0.64845829380644, 0.722381236528875, 0.785468033335223, + 0.830448695683587, 0.875429358031951, 0.938516154838299, + 1.01243909756073), c(0.147809030071502, 0.221731972793937, + 0.284818769600285, 0.329799431948649, 0.374780094297013, + 0.437866891103361, 0.511789833825796)), quantile_levels = c(0.05, + 0.1, 0.25, 0.5, 0.75, 0.9, 0.95), class = c("quantile_pred", + "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, + 18992, 18992, 18992, 18992), class = "Date"), target_date = structure(c(18999, 18999, 18999, 18999, 18999, 18999), class = "Date")), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame")) @@ -1053,35 +635,21 @@ structure(list(geo_value = c("ca", "fl", "ga", "ny", "pa", "tx" ), .pred = c(0.149303403634373, 0.139764664505948, 0.333186321066645, 0.470345577837144, 0.725986105412008, 0.212686665274007), .pred_distn = structure(list( - structure(list(values = c(0.0961118191398634, 0.118312393281548, - 0.13840396557592, 0.149303403634373, 0.160202841692825, 0.180294413987198, - 0.202494988128882), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0.0865730800114383, - 0.108773654153123, 0.128865226447495, 0.139764664505948, - 0.1506641025644, 0.170755674858773, 0.192956249000457), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.279994736572136, 0.30219531071382, 0.322286883008193, - 0.333186321066645, 0.344085759125097, 0.36417733141947, - 0.386377905561154), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0.417153993342634, + c(0.0961118191398634, 0.118312393281548, 0.13840396557592, + 0.149303403634373, 0.160202841692825, 0.180294413987198, + 0.202494988128882), c(0.0865730800114383, 0.108773654153123, + 0.128865226447495, 0.139764664505948, 0.1506641025644, 0.170755674858773, + 0.192956249000457), c(0.279994736572136, 0.30219531071382, + 0.322286883008193, 0.333186321066645, 0.344085759125097, + 0.36417733141947, 0.386377905561154), c(0.417153993342634, 0.439354567484319, 0.459446139778691, 0.470345577837144, 0.481245015895596, 0.501336588189969, 0.523537162331653), - quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, 0.9, - 0.95)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.672794520917498, - 0.694995095059183, 0.715086667353556, 0.725986105412008, - 0.73688554347046, 0.756977115764833, 0.779177689906517), - quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, 0.9, - 0.95)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.159495080779498, - 0.181695654921182, 0.201787227215555, 0.212686665274007, - 0.223586103332459, 0.243677675626832, 0.265878249768516), - quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, 0.9, - 0.95)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr"))), class = c("distribution", "vctrs_vctr", + c(0.672794520917498, 0.694995095059183, 0.715086667353556, + 0.725986105412008, 0.73688554347046, 0.756977115764833, 0.779177689906517 + ), c(0.159495080779498, 0.181695654921182, 0.201787227215555, + 0.212686665274007, 0.223586103332459, 0.243677675626832, + 0.265878249768516)), quantile_levels = c(0.05, 0.1, 0.25, + 0.5, 0.75, 0.9, 0.95), class = c("quantile_pred", "vctrs_vctr", "list")), forecast_date = structure(c(18992, 18992, 18992, 18992, 18992, 18992), class = "Date"), target_date = structure(c(18993, 18993, 18993, 18993, 18993, 18993), class = "Date")), row.names = c(NA, @@ -1092,34 +660,20 @@ structure(list(geo_value = c("ca", "fl", "ga", "ny", "pa", "tx" ), .pred = c(0.303244704017742, 0.531332853311081, 0.58882794468598, 0.98869024921623, 0.79480199700164, 0.306895457225321), .pred_distn = structure(list( - structure(list(values = c(0.136509784083987, 0.202348949370703, - 0.263837900408968, 0.303244704017742, 0.342651507626517, - 0.404140458664782, 0.469979623951498), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.364597933377326, 0.430437098664042, 0.491926049702307, - 0.531332853311081, 0.570739656919856, 0.632228607958121, - 0.698067773244837), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0.422093024752224, + c(0.136509784083987, 0.202348949370703, 0.263837900408968, + 0.303244704017742, 0.342651507626517, 0.404140458664782, + 0.469979623951498), c(0.364597933377326, 0.430437098664042, + 0.491926049702307, 0.531332853311081, 0.570739656919856, + 0.632228607958121, 0.698067773244837), c(0.422093024752224, 0.48793219003894, 0.549421141077205, 0.58882794468598, 0.628234748294754, - 0.689723699333019, 0.755562864619735), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.821955329282475, 0.887794494569191, 0.949283445607456, - 0.98869024921623, 1.028097052825, 1.08958600386327, 1.15542516914999 - ), quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, 0.9, - 0.95)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.628067077067884, + 0.689723699333019, 0.755562864619735), c(0.821955329282475, + 0.887794494569191, 0.949283445607456, 0.98869024921623, 1.028097052825, + 1.08958600386327, 1.15542516914999), c(0.628067077067884, 0.693906242354601, 0.755395193392866, 0.79480199700164, 0.834208800610414, - 0.895697751648679, 0.961536916935395), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.140160537291566, 0.205999702578282, 0.267488653616547, - 0.306895457225321, 0.346302260834096, 0.407791211872361, - 0.473630377159077), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr"))), class = c("distribution", + 0.895697751648679, 0.961536916935395), c(0.140160537291566, + 0.205999702578282, 0.267488653616547, 0.306895457225321, + 0.346302260834096, 0.407791211872361, 0.473630377159077)), quantile_levels = c(0.05, + 0.1, 0.25, 0.5, 0.75, 0.9, 0.95), class = c("quantile_pred", "vctrs_vctr", "list")), forecast_date = structure(c(18997, 18997, 18997, 18997, 18997, 18997), class = "Date"), target_date = structure(c(18998, 18998, 18998, 18998, 18998, 18998), class = "Date")), row.names = c(NA, @@ -1130,34 +684,20 @@ structure(list(geo_value = c("ca", "fl", "ga", "ny", "pa", "tx" ), .pred = c(0.303244704017742, 0.531332853311081, 0.58882794468598, 0.98869024921623, 0.79480199700164, 0.306895457225321), .pred_distn = structure(list( - structure(list(values = c(0.136509784083987, 0.202348949370703, - 0.263837900408968, 0.303244704017742, 0.342651507626517, - 0.404140458664782, 0.469979623951498), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.364597933377326, 0.430437098664042, 0.491926049702307, - 0.531332853311081, 0.570739656919856, 0.632228607958121, - 0.698067773244837), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr")), structure(list(values = c(0.422093024752224, + c(0.136509784083987, 0.202348949370703, 0.263837900408968, + 0.303244704017742, 0.342651507626517, 0.404140458664782, + 0.469979623951498), c(0.364597933377326, 0.430437098664042, + 0.491926049702307, 0.531332853311081, 0.570739656919856, + 0.632228607958121, 0.698067773244837), c(0.422093024752224, 0.48793219003894, 0.549421141077205, 0.58882794468598, 0.628234748294754, - 0.689723699333019, 0.755562864619735), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.821955329282475, 0.887794494569191, 0.949283445607456, - 0.98869024921623, 1.028097052825, 1.08958600386327, 1.15542516914999 - ), quantile_levels = c(0.05, 0.1, 0.25, 0.5, 0.75, 0.9, - 0.95)), class = c("dist_quantiles", "dist_default", "vctrs_rcrd", - "vctrs_vctr")), structure(list(values = c(0.628067077067884, + 0.689723699333019, 0.755562864619735), c(0.821955329282475, + 0.887794494569191, 0.949283445607456, 0.98869024921623, 1.028097052825, + 1.08958600386327, 1.15542516914999), c(0.628067077067884, 0.693906242354601, 0.755395193392866, 0.79480199700164, 0.834208800610414, - 0.895697751648679, 0.961536916935395), quantile_levels = c(0.05, - 0.1, 0.25, 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", - "dist_default", "vctrs_rcrd", "vctrs_vctr")), structure(list( - values = c(0.140160537291566, 0.205999702578282, 0.267488653616547, - 0.306895457225321, 0.346302260834096, 0.407791211872361, - 0.473630377159077), quantile_levels = c(0.05, 0.1, 0.25, - 0.5, 0.75, 0.9, 0.95)), class = c("dist_quantiles", "dist_default", - "vctrs_rcrd", "vctrs_vctr"))), class = c("distribution", + 0.895697751648679, 0.961536916935395), c(0.140160537291566, + 0.205999702578282, 0.267488653616547, 0.306895457225321, + 0.346302260834096, 0.407791211872361, 0.473630377159077)), quantile_levels = c(0.05, + 0.1, 0.25, 0.5, 0.75, 0.9, 0.95), class = c("quantile_pred", "vctrs_vctr", "list")), forecast_date = structure(c(18997, 18997, 18997, 18997, 18997, 18997), class = "Date"), target_date = structure(c(18998, 18998, 18998, 18998, 18998, 18998), class = "Date")), row.names = c(NA, diff --git a/tests/testthat/_snaps/wis-dist-quantiles.md b/tests/testthat/_snaps/wis-dist-quantiles.md deleted file mode 100644 index fb9cfbdf6..000000000 --- a/tests/testthat/_snaps/wis-dist-quantiles.md +++ /dev/null @@ -1,17 +0,0 @@ -# wis dispatches and produces the correct values - - Code - weighted_interval_score(1:10, 10) - Condition - Error in `weighted_interval_score()`: - ! Weighted interval score can only be calculated if `x` - has class . - ---- - - Code - weighted_interval_score(dist_quantiles(list(1:4, 8:11), 1:4 / 5), 1:3) - Condition - Error in `weighted_interval_score()`: - ! Can't recycle `x` (size 2) to match `actual` (size 3). - diff --git a/tests/testthat/test-grf_quantiles.R b/tests/testthat/test-grf_quantiles.R index 5adbf6518..32f581d7a 100644 --- a/tests/testthat/test-grf_quantiles.R +++ b/tests/testthat/test-grf_quantiles.R @@ -78,7 +78,7 @@ test_that("quantile_rand_forest operates with arx_forecaster", { z <- arx_forecaster(df, "cases", "cases", spec2) expect_identical( - nested_quantiles(z$predictions$.pred_distn[1])[[1]]$quantile_levels, + hardhat::extract_quantile_levels(z$predictions$.pred_distn), c(.05, .1, 0.25, .5, 0.75, .9, .95) ) }) diff --git a/tests/testthat/test-pivot_quantiles.R b/tests/testthat/test-pivot_quantiles.R index a4362cffb..af6f82727 100644 --- a/tests/testthat/test-pivot_quantiles.R +++ b/tests/testthat/test-pivot_quantiles.R @@ -42,3 +42,12 @@ test_that("quantile pivotting longer behaves", { expect_identical(pivot_quantiles_longer(tib, d1)$d1_value, c(1:3, 2:4)) }) + +test_that("nested_quantiles is deprecated, but works where possible", { + expect_snapshot(d <- dist_quantiles(list(1:4, 2:5), 1:4 / 5)) + expect_snapshot(o <- nested_quantiles(d)) + res <- as_tibble(hardhat::quantile_pred( + matrix(c(1:4, 2:5), nrow = 2, byrow = TRUE), 1:4 / 5) + ) + expect_identical(o |> mutate(.row = dplyr::row_number()) |> unnest(data), res) +}) diff --git a/tests/testthat/test-population_scaling.R b/tests/testthat/test-population_scaling.R index 6e4cd5df2..f2efde3c0 100644 --- a/tests/testthat/test-population_scaling.R +++ b/tests/testthat/test-population_scaling.R @@ -340,7 +340,6 @@ test_that("test joining by default columns with less common keys/classes", { pivot_quantiles_wider(.pred), dat1 %>% select(!"y") %>% - as_tibble() %>% mutate(`0.5` = c(2 * 5, 2 * 11)) ) @@ -377,7 +376,6 @@ test_that("test joining by default columns with less common keys/classes", { pivot_quantiles_wider(.pred), dat1b %>% select(!"y") %>% - as_tibble() %>% # geo 1 scaling used for both: mutate(`0.5` = c(2 * 5, 2 * 5)) ), @@ -419,10 +417,10 @@ test_that("test joining by default columns with less common keys/classes", { expect_equal( # get_test_data doesn't work with non-`epi_df`s, so provide test data manually: predict(fit(ewf1b2, dat1b2), dat1b2) %>% - pivot_quantiles_wider(.pred), + pivot_quantiles_wider(.pred) %>% + as_tibble(), dat1b2 %>% select(!"y") %>% - as_tibble() %>% # geo 1 scaling used for both: mutate(`0.5` = c(2 * 5, 2 * 5)) %>% select(geo_value, age_group, time_value, `0.5`) @@ -485,7 +483,8 @@ test_that("test joining by default columns with less common keys/classes", { ) expect_equal( forecast(fit(ewf2, dat2)) %>% - pivot_quantiles_wider(.pred), + pivot_quantiles_wider(.pred) %>% + as_tibble(), dat2 %>% select(!"y") %>% as_tibble() %>% @@ -522,7 +521,6 @@ test_that("test joining by default columns with less common keys/classes", { pivot_quantiles_wider(.pred), dat2b %>% select(!"y") %>% - as_tibble() %>% mutate(`0.5` = c(2 * 5, 2 * 11)) ), class = "epipredict__step_population_scaling__default_by_missing_suggested_keys" @@ -559,8 +557,7 @@ test_that("test joining by default columns with less common keys/classes", { # slightly edited copy-pasta due to test time selection: dat3 %>% select(!"y") %>% - as_tibble() %>% - slice_max(by = geo_value, time_value) %>% + dplyr::slice_max(by = geo_value, time_value) %>% mutate(`0.5` = 2 * 11) ) diff --git a/tests/testthat/test-step_adjust_latency.R b/tests/testthat/test-step_adjust_latency.R index 7b1f320e4..e24cc870c 100644 --- a/tests/testthat/test-step_adjust_latency.R +++ b/tests/testthat/test-step_adjust_latency.R @@ -13,7 +13,6 @@ x <- tibble( ) %>% as_epi_df(as_of = as.POSIXct("2024-09-17")) max_time <- max(x$time_value) -class(attributes(x)$metadata$as_of) as_of <- attributes(x)$metadata$as_of ahead <- 7 latency <- 5 @@ -241,7 +240,12 @@ test_that("epi_adjust_latency extends multiple aheads", { # the as_of on x is today's date, which is >970 days in the future # also, there's no data >970 days in the past, so it gets an error trying to # fit on no data - expect_error(expect_warning(fit3 <- fit(epi_wf, data = x), class = "epipredict__prep.step_latency__very_large_latency"), class = "simpleError") + expect_error( + expect_warning( + fit3 <- fit(epi_wf, data = x), + class = "epipredict__prep.step_latency__very_large_latency"), + class = "simpleError" + ) # real date example fit3 <- fit(epi_wf, data = real_x) expect_equal( From 532b0d3a3cad5926fed9bfc8ec90659074d192ac Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Tue, 25 Feb 2025 12:00:47 -0800 Subject: [PATCH 23/25] pass local checks --- NAMESPACE | 1 - R/layer_threshold_preds.R | 3 +-- R/make_smooth_quantile_reg.R | 10 ++++------ R/weighted_interval_score.R | 6 +++--- man/smooth_quantile_reg.Rd | 10 ++++------ man/weighted_interval_score.Rd | 6 +++--- 6 files changed, 15 insertions(+), 21 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 9116bb71e..2f4149cd9 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -190,7 +190,6 @@ export(remove_frosting) export(remove_model) export(slather) export(smooth_quantile_reg) -export(snap) export(step_adjust_latency) export(step_epi_ahead) export(step_epi_lag) diff --git a/R/layer_threshold_preds.R b/R/layer_threshold_preds.R index ce02fe24a..40f912e44 100644 --- a/R/layer_threshold_preds.R +++ b/R/layer_threshold_preds.R @@ -59,8 +59,7 @@ layer_threshold_new <- layer("threshold", terms = terms, lower = lower, upper = upper, id = id) } -#' @export -#' @keywords internal + snap <- function(x, lower, upper, ...) { UseMethod("snap") } diff --git a/R/make_smooth_quantile_reg.R b/R/make_smooth_quantile_reg.R index b5081129f..3a390c582 100644 --- a/R/make_smooth_quantile_reg.R +++ b/R/make_smooth_quantile_reg.R @@ -43,13 +43,11 @@ #' ) #' pl <- pl %>% #' unnest(.pred) %>% -#' mutate(distn = nested_quantiles(distn)) %>% -#' unnest(distn) %>% +#' pivot_quantiles_wider(distn) %>% #' mutate( #' x = x[length(x) - 20] + ahead / 100 * 2 * pi, #' ahead = NULL -#' ) %>% -#' pivot_wider(names_from = distn_quantile_levels, values_from = distn_value) +#' ) #' plot(x, y, pch = 16, xlim = c(pi, 2 * pi), col = "lightgrey") #' curve(sin(x), add = TRUE) #' abline(v = fd, lty = 2) @@ -59,11 +57,11 @@ #' #' library(ggplot2) #' ggplot(data.frame(x = x, y = y), aes(x)) + -#' geom_ribbon(data = pl, aes(ymin = `0.2`, ymax = `0.8`), fill = "lightblue") + +#' geom_ribbon(data = pl, aes(ymin = `0.2`, ymax = `0.8`), fill = "cornflowerblue") + #' geom_point(aes(y = y), colour = "grey") + # observed data #' geom_function(fun = sin, colour = "black") + # truth #' geom_vline(xintercept = fd, linetype = "dashed") + # end of training data -#' geom_line(data = pl, aes(y = `0.5`), colour = "red") + # median prediction +#' geom_line(data = pl, aes(y = `0.5`), colour = "orange") + # median prediction #' theme_bw() + #' coord_cartesian(xlim = c(0, NA)) + #' ylab("y") diff --git a/R/weighted_interval_score.R b/R/weighted_interval_score.R index aa0c816a3..47187fe56 100644 --- a/R/weighted_interval_score.R +++ b/R/weighted_interval_score.R @@ -52,13 +52,13 @@ #' #' # Using some actual forecasts -------- #' library(dplyr) -#' jhu <- case_death_rate_subset %>% +#' training <- covid_case_death_rates %>% #' filter(time_value >= "2021-10-01", time_value <= "2021-12-01") #' preds <- flatline_forecaster( -#' jhu, "death_rate", +#' training, "death_rate", #' flatline_args_list(quantile_levels = c(.01, .025, 1:19 / 20, .975, .99)) #' )$predictions -#' actuals <- case_death_rate_subset %>% +#' actuals <- covid_case_death_rates %>% #' filter(time_value == as.Date("2021-12-01") + 7) %>% #' select(geo_value, time_value, actual = death_rate) #' preds <- left_join(preds, actuals, diff --git a/man/smooth_quantile_reg.Rd b/man/smooth_quantile_reg.Rd index 3ac83d62a..1ac93ae5e 100644 --- a/man/smooth_quantile_reg.Rd +++ b/man/smooth_quantile_reg.Rd @@ -62,13 +62,11 @@ pl <- predict( ) pl <- pl \%>\% unnest(.pred) \%>\% - mutate(distn = nested_quantiles(distn)) \%>\% - unnest(distn) \%>\% + pivot_quantiles_wider(distn) \%>\% mutate( x = x[length(x) - 20] + ahead / 100 * 2 * pi, ahead = NULL - ) \%>\% - pivot_wider(names_from = distn_quantile_levels, values_from = distn_value) + ) plot(x, y, pch = 16, xlim = c(pi, 2 * pi), col = "lightgrey") curve(sin(x), add = TRUE) abline(v = fd, lty = 2) @@ -78,11 +76,11 @@ lines(pl$x, pl$`0.5`, col = "red") library(ggplot2) ggplot(data.frame(x = x, y = y), aes(x)) + - geom_ribbon(data = pl, aes(ymin = `0.2`, ymax = `0.8`), fill = "lightblue") + + geom_ribbon(data = pl, aes(ymin = `0.2`, ymax = `0.8`), fill = "cornflowerblue") + geom_point(aes(y = y), colour = "grey") + # observed data geom_function(fun = sin, colour = "black") + # truth geom_vline(xintercept = fd, linetype = "dashed") + # end of training data - geom_line(data = pl, aes(y = `0.5`), colour = "red") + # median prediction + geom_line(data = pl, aes(y = `0.5`), colour = "orange") + # median prediction theme_bw() + coord_cartesian(xlim = c(0, NA)) + ylab("y") diff --git a/man/weighted_interval_score.Rd b/man/weighted_interval_score.Rd index 22a616b70..ef09d4da1 100644 --- a/man/weighted_interval_score.Rd +++ b/man/weighted_interval_score.Rd @@ -69,13 +69,13 @@ weighted_interval_score( # Using some actual forecasts -------- library(dplyr) -jhu <- case_death_rate_subset \%>\% +training <- covid_case_death_rates \%>\% filter(time_value >= "2021-10-01", time_value <= "2021-12-01") preds <- flatline_forecaster( - jhu, "death_rate", + training, "death_rate", flatline_args_list(quantile_levels = c(.01, .025, 1:19 / 20, .975, .99)) )$predictions -actuals <- case_death_rate_subset \%>\% +actuals <- covid_case_death_rates \%>\% filter(time_value == as.Date("2021-12-01") + 7) \%>\% select(geo_value, time_value, actual = death_rate) preds <- left_join(preds, actuals, From ee2c9f336e25fe293ecae2ed8994d776b19db75d Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Tue, 25 Feb 2025 12:05:03 -0800 Subject: [PATCH 24/25] bump news --- NEWS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.md b/NEWS.md index 28f5bb99e..ab16be45e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -14,6 +14,9 @@ Pre-1.0.0 numbering scheme: 0.x will indicate releases, while 0.0.x will indicat - Addresses upstream breaking changes from cmu-delphi/epiprocess#595 (`growth_rate()`). `step_growth_rate()` has lost its `additional_gr_args_list` argument and now has an `na_rm` argument. +- Removes dependence on the `distributional` package, replacing the quantiles + with `hardhat::quantile_pred()`. Some associated functions are deprecated with + `lifecycle` messages. ## Improvements @@ -23,6 +26,7 @@ Pre-1.0.0 numbering scheme: 0.x will indicate releases, while 0.0.x will indicat - Fix `quantile_reg()` producing error when asked to output just median-level predictions. - (temporary) ahead negative is allowed for `step_epi_ahead` until we have `step_epi_shift` - Add `reference_date` as an argument to `epi_recipe()` +- Replace `dist_quantiles()` with `hardhat::quantile_pred()` ## Bug fixes - Shifting no columns results in no error for either `step_epi_ahead` and `step_epi_lag` From 233c81dedaf0080999f9e6d6b2e552564242b347 Mon Sep 17 00:00:00 2001 From: "Daniel J. McDonald" Date: Tue, 25 Feb 2025 12:21:02 -0800 Subject: [PATCH 25/25] style: fu --- R/layer_residual_quantiles.R | 5 +++-- R/quantile_pred-methods.R | 25 +++++++++++++---------- tests/testthat/test-pivot_quantiles.R | 5 ++--- tests/testthat/test-quantile_pred.R | 2 -- tests/testthat/test-step_adjust_latency.R | 3 ++- tests/testthat/test-wis-quantile_pred.R | 3 ++- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/R/layer_residual_quantiles.R b/R/layer_residual_quantiles.R index 28076b69a..f13728a56 100644 --- a/R/layer_residual_quantiles.R +++ b/R/layer_residual_quantiles.R @@ -127,10 +127,11 @@ slather.layer_residual_quantiles <- r <- r %>% summarize(dstn = quantile_pred(matrix(quantile( - c(.resid, s * .resid), probs = object$quantile_levels, na.rm = TRUE + c(.resid, s * .resid), + probs = object$quantile_levels, na.rm = TRUE ), nrow = 1), quantile_levels = object$quantile_levels)) # Check for NA - if (anyNA(as.matrix(r$dstn))) { + if (anyNA(as.matrix(r$dstn))) { cli_abort(c( "Residual quantiles could not be calculated due to missing residuals.", i = "This may be due to `n_train` < `ahead` in your {.cls epi_recipe}." diff --git a/R/quantile_pred-methods.R b/R/quantile_pred-methods.R index 90313c9ef..010bba6fe 100644 --- a/R/quantile_pred-methods.R +++ b/R/quantile_pred-methods.R @@ -133,7 +133,7 @@ quantile_internal <- function(x, tau_out, middle) { # short circuit if we aren't actually extrapolating # matches to ~15 decimals if (all(tau_out %in% tau) && !anyNA(qvals)) { - return(qvals[ , match(tau_out, tau), drop = FALSE]) + return(qvals[, match(tau_out, tau), drop = FALSE]) } if (length(tau) < 2) { cli_abort(paste( @@ -152,7 +152,9 @@ quantile_internal <- function(x, tau_out, middle) { extrapolate_quantiles_single <- function(qvals, tau, tau_out, middle) { qvals_out <- rep(NA, length(tau_out)) good <- !is.na(qvals) - if (!any(good)) return(qvals_out) + if (!any(good)) { + return(qvals_out) + } qvals <- qvals[good] tau <- tau[good] @@ -169,21 +171,22 @@ extrapolate_quantiles_single <- function(qvals, tau, tau_out, middle) { if (middle == "cubic") { method <- "cubic" - result <- tryCatch({ - Q <- stats::splinefun(tau, qvals, method = "hyman") - quartiles <- Q(c(.25, .5, .75)) - }, - error = function(e) { - return(NA) - }) + result <- tryCatch( + { + Q <- stats::splinefun(tau, qvals, method = "hyman") + quartiles <- Q(c(.25, .5, .75)) + }, + error = function(e) { + return(NA) + } + ) } if (middle == "linear" || any(is.na(result))) { method <- "linear" quartiles <- stats::approx(tau, qvals, c(.25, .5, .75))$y } if (any(indm)) { - qvals_out[indm] <- switch( - method, + qvals_out[indm] <- switch(method, linear = stats::approx(tau, qvals, tau_out[indm])$y, cubic = Q(tau_out[indm]) ) diff --git a/tests/testthat/test-pivot_quantiles.R b/tests/testthat/test-pivot_quantiles.R index af6f82727..39db31b2f 100644 --- a/tests/testthat/test-pivot_quantiles.R +++ b/tests/testthat/test-pivot_quantiles.R @@ -40,14 +40,13 @@ test_that("quantile pivotting longer behaves", { expect_length(pivot_quantiles_longer(tib, d1), 4L) expect_identical(nrow(pivot_quantiles_longer(tib, d1)), 6L) expect_identical(pivot_quantiles_longer(tib, d1)$d1_value, c(1:3, 2:4)) - }) test_that("nested_quantiles is deprecated, but works where possible", { expect_snapshot(d <- dist_quantiles(list(1:4, 2:5), 1:4 / 5)) expect_snapshot(o <- nested_quantiles(d)) res <- as_tibble(hardhat::quantile_pred( - matrix(c(1:4, 2:5), nrow = 2, byrow = TRUE), 1:4 / 5) - ) + matrix(c(1:4, 2:5), nrow = 2, byrow = TRUE), 1:4 / 5 + )) expect_identical(o |> mutate(.row = dplyr::row_number()) |> unnest(data), res) }) diff --git a/tests/testthat/test-quantile_pred.R b/tests/testthat/test-quantile_pred.R index d7c7cc4cb..70d7c71a5 100644 --- a/tests/testthat/test-quantile_pred.R +++ b/tests/testthat/test-quantile_pred.R @@ -1,4 +1,3 @@ - test_that("single quantile_pred works, quantiles are accessible", { z <- hardhat::quantile_pred( values = matrix(1:5, nrow = 1), @@ -79,7 +78,6 @@ test_that("unary math works on quantiles", { 1:4 / 5 ) expect_identical(log(dstn), dstn2) - }) test_that("arithmetic works on quantiles", { diff --git a/tests/testthat/test-step_adjust_latency.R b/tests/testthat/test-step_adjust_latency.R index e24cc870c..df24013ec 100644 --- a/tests/testthat/test-step_adjust_latency.R +++ b/tests/testthat/test-step_adjust_latency.R @@ -243,7 +243,8 @@ test_that("epi_adjust_latency extends multiple aheads", { expect_error( expect_warning( fit3 <- fit(epi_wf, data = x), - class = "epipredict__prep.step_latency__very_large_latency"), + class = "epipredict__prep.step_latency__very_large_latency" + ), class = "simpleError" ) # real date example diff --git a/tests/testthat/test-wis-quantile_pred.R b/tests/testthat/test-wis-quantile_pred.R index 187344af9..a51a67352 100644 --- a/tests/testthat/test-wis-quantile_pred.R +++ b/tests/testthat/test-wis-quantile_pred.R @@ -51,7 +51,8 @@ test_that("wis dispatches and produces the correct values", { )) expect_true(is.na( weighted_interval_score( - quantile_pred(rbind(1:4), 1:4 / 5), 2.5, 1:9 / 10, na_handling = "fail" + quantile_pred(rbind(1:4), 1:4 / 5), 2.5, 1:9 / 10, + na_handling = "fail" ) )) })