From 8ff6f8b0b9541daefa664458e8a73cecd45b8dda Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Sun, 21 Jul 2024 21:57:32 +0200 Subject: [PATCH 1/8] first draft for as_forecast_point and as_forecast_quantile --- NAMESPACE | 5 +- NEWS.md | 2 +- R/forecast.R | 103 +++++++++++++++--- R/utils_data_handling.R | 49 +-------- .../R/00-standalone-Figure-replication.R | 2 +- inst/manuscript/R/toy-example-calibration.R | 2 +- man/as_forecast.Rd | 36 ++++-- man/sample_to_interval_long.Rd | 4 + man/sample_to_quantile.Rd | 33 ------ tests/testthat/test-utils_data_handling.R | 26 ++--- 10 files changed, 139 insertions(+), 123 deletions(-) delete mode 100644 man/sample_to_quantile.Rd diff --git a/NAMESPACE b/NAMESPACE index b41c40be..4c84f6f6 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,10 @@ # Generated by roxygen2: do not edit by hand S3method(`[`,scores) +S3method(as_forecast_point,default) +S3method(as_forecast_point,forecast_quantile) +S3method(as_forecast_quantile,default) +S3method(as_forecast_quantile,forecast_sample) S3method(assert_forecast,default) S3method(assert_forecast,forecast_binary) S3method(assert_forecast,forecast_point) @@ -66,7 +70,6 @@ export(plot_pit) export(plot_quantile_coverage) export(plot_wis) export(quantile_score) -export(sample_to_quantile) export(score) export(se_mean_sample) export(select_metrics) diff --git a/NEWS.md b/NEWS.md index 8a0ec7f2..e11ae9ed 100644 --- a/NEWS.md +++ b/NEWS.md @@ -281,7 +281,7 @@ the mean before returning an output. ### Bug fixes - Testing was expanded -- Minor bugs were fixed, for example a bug in the `sample_to_quantile()` function +- Minor bugs were fixed, for example a bug in the `as_forecast_quantile()` function (https://github.com/epiforecasts/scoringutils/pull/223) ### Package data updated diff --git a/R/forecast.R b/R/forecast.R index df6c2a79..1bd05820 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -102,45 +102,74 @@ as_forecast_generic <- function(data, #' @rdname as_forecast #' @export #' @importFrom cli cli_warn -as_forecast_point <- function(data, - forecast_unit = NULL, - observed = NULL, - predicted = NULL, - model = NULL) { +as_forecast_binary <- function(data, + forecast_unit = NULL, + observed = NULL, + predicted = NULL, + model = NULL) { data <- as_forecast_generic(data, forecast_unit, observed, predicted, model) - data <- new_forecast(data, "forecast_point") + data <- new_forecast(data, "forecast_binary") assert_forecast(data) return(data) } +#' @rdname as_forecast +#' @export +as_forecast_point <- function(data, ...) { + UseMethod("as_forecast_point") +} + #' @rdname as_forecast #' @export #' @importFrom cli cli_warn -as_forecast_binary <- function(data, - forecast_unit = NULL, - observed = NULL, - predicted = NULL, - model = NULL) { +as_forecast_point.default <- function(data, + forecast_unit = NULL, + observed = NULL, + predicted = NULL, + model = NULL, + ...) { data <- as_forecast_generic(data, forecast_unit, observed, predicted, model) - data <- new_forecast(data, "forecast_binary") + data <- new_forecast(data, "forecast_point") assert_forecast(data) return(data) } +#' @rdname as_forecast +#' @export +#' @keywords check-forecasts +as_forecast_point.forecast_quantile <- function(data, ...) { + assert_forecast(data, verbose = FALSE) + assert_subset(0.5, unique(data$quantile_level)) + + forecast <- data[quantile_level == 0.5] + forecast[, "quantile_level" := NULL] + + point_forecast <- new_forecast(forecast, "forecast_point") + return(point_forecast) +} + + +#' @rdname as_forecast +#' @export +as_forecast_quantile <- function(data, ...) { + UseMethod("as_forecast_quantile") +} + + #' @rdname as_forecast #' @param quantile_level (optional) Name of the column in `data` that contains #' the quantile level of the predicted values. This column will be renamed to #' "quantile_level". Only applicable to quantile-based forecasts. #' @export #' @importFrom cli cli_warn -as_forecast_quantile <- function(data, - forecast_unit = NULL, - observed = NULL, - predicted = NULL, - model = NULL, - quantile_level = NULL) { +as_forecast_quantile.default <- function(data, + forecast_unit = NULL, + observed = NULL, + predicted = NULL, + model = NULL, + quantile_level = NULL) { assert_character(quantile_level, len = 1, null.ok = TRUE) assert_subset(quantile_level, names(data), empty.ok = TRUE) if (!is.null(quantile_level)) { @@ -154,6 +183,44 @@ as_forecast_quantile <- function(data, } +#' @rdname as_forecast +#' @param quantile_level A numeric vector of quantile levels for which +#' quantiles will be computed. +#' @param type Type argument passed down to the quantile function. For more +#' information, see [quantile()]. +#' @importFrom stats quantile +#' @importFrom methods hasArg +#' @importFrom checkmate assert_numeric +#' @export +as_forecast_quantile.forecast_sample <- function( + data, + quantile_level = c(0.05, 0.25, 0.5, 0.75, 0.95), + type = 7, + ... +) { + forecast <- copy(data) + assert_forecast(forecast, verbose = FALSE) + assert_numeric(quantile_level, min.len = 1) + reserved_columns <- c("predicted", "sample_id") + by <- setdiff(colnames(forecast), reserved_columns) + + quantile_level <- unique( + round(c(quantile_level, 1 - quantile_level), digits = 10) + ) + + forecast <- + forecast[, .(quantile_level = quantile_level, + predicted = quantile(x = predicted, probs = ..quantile_level, + type = ..type, na.rm = TRUE)), + by = by] + + quantile_forecast <- new_forecast(forecast, "forecast_quantile") + assert_forecast(quantile_forecast) + + return(quantile_forecast) +} + + #' @rdname as_forecast #' @param sample_id (optional) Name of the column in `data` that contains the #' sample id. This column will be renamed to "sample_id". Only applicable to diff --git a/R/utils_data_handling.R b/R/utils_data_handling.R index a53698a4..0c169bf5 100644 --- a/R/utils_data_handling.R +++ b/R/utils_data_handling.R @@ -1,48 +1,3 @@ -#' @title Change data from a sample based format to a quantile format -#' -#' @description -#' Transform data from a format that is based on predictive samples to a format -#' based on plain quantiles. -#' -#' @param forecast A `forecast` object of class `forecast_sample` (a validated -#' data.table with predicted and observed values, see [as_forecast()]). -#' -#' @param quantile_level A numeric vector of quantile levels for which -#' quantiles will be computed. -#' @param type Type argument passed down to the quantile function. For more -#' information, see [quantile()]. -#' @return a data.table in a long interval range format -#' @importFrom data.table as.data.table -#' @importFrom stats quantile -#' @importFrom methods hasArg -#' @importFrom checkmate assert_numeric -#' @keywords data-handling -#' @export -#' @examples -#' sample_to_quantile(as_forecast_sample(example_sample_discrete)) -sample_to_quantile <- function(forecast, - quantile_level = c(0.05, 0.25, 0.5, 0.75, 0.95), - type = 7) { - forecast <- copy(forecast) - assert_forecast(forecast, forecast_type = "sample", verbose = FALSE) - assert_numeric(quantile_level, min.len = 1) - reserved_columns <- c("predicted", "sample_id") - by <- setdiff(colnames(forecast), reserved_columns) - - quantile_level <- unique( - round(c(quantile_level, 1 - quantile_level), digits = 10) - ) - - forecast <- - forecast[, .(quantile_level = quantile_level, - predicted = quantile(x = predicted, probs = ..quantile_level, - type = ..type, na.rm = TRUE)), - by = by] - - return(as_forecast_quantile(forecast)) -} - - # ==================== Functions internally used for scoring =================== # These functions would ideally be replaced in the future @@ -183,7 +138,7 @@ quantile_to_interval_numeric <- function(observed, #' Transform data from a format that is based on predictive samples to a format #' based on interval ranges. #' -#' @inheritParams sample_to_quantile +#' @inheritParams as_forecast_quantile #' @param keep_quantile_col keep quantile_level column, default is TRUE #' @return A data.table in a long interval interval range format #' @importFrom data.table as.data.table @@ -200,7 +155,7 @@ sample_to_interval_long <- function(data, upper_quantiles <- 1 - lower_quantiles quantile_levels <- sort(unique(c(lower_quantiles, upper_quantiles))) - data <- sample_to_quantile( + data <- as_forecast_quantile( data, quantile_level = quantile_levels, type = type diff --git a/inst/manuscript/R/00-standalone-Figure-replication.R b/inst/manuscript/R/00-standalone-Figure-replication.R index 7276e833..c4ffdc78 100644 --- a/inst/manuscript/R/00-standalone-Figure-replication.R +++ b/inst/manuscript/R/00-standalone-Figure-replication.R @@ -143,7 +143,7 @@ pit_plots <- plot_pit(stored$pit) + # create interval and quantile coverage plots ---------------------------------- # create coverage plots by transforming to quantile format first quantiles <- c(0.01, 0.025, seq(0.05, 0.95, 0.05), 0.975, 0.99) -df_quantile <- sample_to_quantile(df, +df_quantile <- as_forecast_quantile(df, quantiles = quantiles) res_quantile <- score(df_quantile) diff --git a/inst/manuscript/R/toy-example-calibration.R b/inst/manuscript/R/toy-example-calibration.R index 0f1db5df..0e3b6d22 100644 --- a/inst/manuscript/R/toy-example-calibration.R +++ b/inst/manuscript/R/toy-example-calibration.R @@ -72,7 +72,7 @@ pit_plots <- plot_pit(stored$pit) + # create interval and quantile coverage plots ---------------------------------- # create coverage plots by transforming to quantile format first quantiles <- c(0.01, 0.025, seq(0.05, 0.95, 0.05), 0.975, 0.99) -df_quantile <- sample_to_quantile(df, +df_quantile <- as_forecast_quantile(df, quantile_level = quantiles) res_quantile <- score(df_quantile) diff --git a/man/as_forecast.Rd b/man/as_forecast.Rd index 8fb2e061..e1afafe1 100644 --- a/man/as_forecast.Rd +++ b/man/as_forecast.Rd @@ -2,13 +2,17 @@ % Please edit documentation in R/forecast.R \name{as_forecast} \alias{as_forecast} -\alias{as_forecast_point} \alias{as_forecast_binary} +\alias{as_forecast_point} +\alias{as_forecast_point.default} +\alias{as_forecast_point.forecast_quantile} \alias{as_forecast_quantile} +\alias{as_forecast_quantile.default} +\alias{as_forecast_quantile.forecast_sample} \alias{as_forecast_sample} \title{Create a \code{forecast} object} \usage{ -as_forecast_point( +as_forecast_binary( data, forecast_unit = NULL, observed = NULL, @@ -16,15 +20,22 @@ as_forecast_point( model = NULL ) -as_forecast_binary( +as_forecast_point(data, ...) + +\method{as_forecast_point}{default}( data, forecast_unit = NULL, observed = NULL, predicted = NULL, - model = NULL + model = NULL, + ... ) -as_forecast_quantile( +\method{as_forecast_point}{forecast_quantile}(data, ...) + +as_forecast_quantile(data, ...) + +\method{as_forecast_quantile}{default}( data, forecast_unit = NULL, observed = NULL, @@ -33,6 +44,13 @@ as_forecast_quantile( quantile_level = NULL ) +\method{as_forecast_quantile}{forecast_sample}( + data, + quantile_level = c(0.05, 0.25, 0.5, 0.75, 0.95), + type = 7, + ... +) + as_forecast_sample( data, forecast_unit = NULL, @@ -64,9 +82,11 @@ predicted values. This column will be renamed to "predicted".} of the models/forecasters that generated the predicted values. This column will be renamed to "model".} -\item{quantile_level}{(optional) Name of the column in \code{data} that contains -the quantile level of the predicted values. This column will be renamed to -"quantile_level". Only applicable to quantile-based forecasts.} +\item{quantile_level}{A numeric vector of quantile levels for which +quantiles will be computed.} + +\item{type}{Type argument passed down to the quantile function. For more +information, see \code{\link[=quantile]{quantile()}}.} \item{sample_id}{(optional) Name of the column in \code{data} that contains the sample id. This column will be renamed to "sample_id". Only applicable to diff --git a/man/sample_to_interval_long.Rd b/man/sample_to_interval_long.Rd index 959d1a1b..c16254a0 100644 --- a/man/sample_to_interval_long.Rd +++ b/man/sample_to_interval_long.Rd @@ -12,6 +12,10 @@ sample_to_interval_long( ) } \arguments{ +\item{data}{A data.frame (or similar) with predicted and observed values. +See the details section of \code{\link[=as_forecast]{as_forecast()}} for additional information +on required input formats.} + \item{type}{Type argument passed down to the quantile function. For more information, see \code{\link[=quantile]{quantile()}}.} diff --git a/man/sample_to_quantile.Rd b/man/sample_to_quantile.Rd deleted file mode 100644 index 4c7f5b7c..00000000 --- a/man/sample_to_quantile.Rd +++ /dev/null @@ -1,33 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/utils_data_handling.R -\name{sample_to_quantile} -\alias{sample_to_quantile} -\title{Change data from a sample based format to a quantile format} -\usage{ -sample_to_quantile( - forecast, - quantile_level = c(0.05, 0.25, 0.5, 0.75, 0.95), - type = 7 -) -} -\arguments{ -\item{forecast}{A \code{forecast} object of class \code{forecast_sample} (a validated -data.table with predicted and observed values, see \code{\link[=as_forecast]{as_forecast()}}).} - -\item{quantile_level}{A numeric vector of quantile levels for which -quantiles will be computed.} - -\item{type}{Type argument passed down to the quantile function. For more -information, see \code{\link[=quantile]{quantile()}}.} -} -\value{ -a data.table in a long interval range format -} -\description{ -Transform data from a format that is based on predictive samples to a format -based on plain quantiles. -} -\examples{ -sample_to_quantile(as_forecast_sample(example_sample_discrete)) -} -\keyword{data-handling} diff --git a/tests/testthat/test-utils_data_handling.R b/tests/testthat/test-utils_data_handling.R index fd5e9355..6ece4d05 100644 --- a/tests/testthat/test-utils_data_handling.R +++ b/tests/testthat/test-utils_data_handling.R @@ -59,14 +59,15 @@ test_that("quantile_to_interval_dataframe() works", { }) -test_that("sample_to_quantiles works", { +test_that("as_forecast_quantiles works", { samples <- data.frame( date = as.Date("2020-01-01") + 1:10, model = "model1", observed = 1:10, predicted = c(rep(0, 10), 2:11, 3:12, 4:13, rep(100, 10)), sample_id = rep(1:5, each = 10) - ) + ) |> + as_forecast_sample() quantile <- data.frame( date = rep(as.Date("2020-01-01") + 1:10, each = 2), @@ -76,32 +77,31 @@ test_that("sample_to_quantiles works", { predicted = rep(2:11, each = 2) + c(0, 2) ) - expect_error( - sample_to_quantile(samples, quantile_level = c(0.25, 0.75)), - "The input needs to be a valid forecast object." + expect_no_condition( + as_forecast_quantile(samples, quantile_level = c(0.25, 0.75)) ) wrongclass <- as_forecast_sample(samples) class(wrongclass) <- c("forecast_point", "data.table", "data.frame") expect_error( - sample_to_quantile(wrongclass, quantile_level = c(0.25, 0.75)), - 'Desired forecast type: "sample"' + as_forecast_quantile(wrongclass, quantile_level = c(0.25, 0.75)), + "Assertion on 'quantile_level' failed: Must be of type" ) - quantile2 <- sample_to_quantile( + quantile2 <- as_forecast_quantile( as_forecast_sample(samples), quantile_level = c(0.25, 0.75) ) expect_equal(quantile, as.data.frame(quantile2)) - # Verify that `type` is correctly scoped in sample_to_quantile(), as it is + # Verify that `type` is correctly scoped in as_forecast_quantile(), as it is # also an argument. - # If it's not scoped well, the call to `sample_to_quantile()` will fail. + # If it's not scoped well, the call to `as_forecast_quantile()` will fail. samples$type <- "test" - quantile3 <- sample_to_quantile( + quantile3 <- as_forecast_quantile( as_forecast_sample(samples), quantile_level = c(0.25, 0.75) ) @@ -113,11 +113,11 @@ test_that("sample_to_quantiles works", { ) }) -test_that("sample_to_quantiles issue 557 fix", { +test_that("as_forecast_quantiles issue 557 fix", { out <- example_sample_discrete %>% as_forecast_sample() %>% - sample_to_quantile( + as_forecast_quantile( quantile_level = c(0.01, 0.025, seq(0.05, 0.95, 0.05), 0.975, 0.99) ) %>% score() From f743eeda1fab4ef4bba2fc5b7c5685e191cc41e5 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Sun, 28 Jul 2024 12:43:40 +0200 Subject: [PATCH 2/8] update docs and tests --- R/forecast.R | 57 ++++++++++----- R/utils_data_handling.R | 2 +- man/as_forecast.Rd | 85 ++++------------------- man/as_forecast_binary.Rd | 17 +++++ man/as_forecast_point.Rd | 52 ++++++++++++++ man/as_forecast_quantile.Rd | 46 ++++++++++++ man/as_forecast_sample.Rd | 27 +++++++ man/sample_to_interval_long.Rd | 4 -- tests/testthat/test-utils_data_handling.R | 8 +-- 9 files changed, 202 insertions(+), 96 deletions(-) create mode 100644 man/as_forecast_binary.Rd create mode 100644 man/as_forecast_point.Rd create mode 100644 man/as_forecast_quantile.Rd create mode 100644 man/as_forecast_sample.Rd diff --git a/R/forecast.R b/R/forecast.R index 1bd05820..d8a6a32b 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -5,18 +5,24 @@ #' and observations. If the input passes all input checks, it will be converted #' to a `forecast` object. A forecast object is a `data.table` with a #' class `forecast` and an additional class that depends on the forecast type. -#' Every forecast type has its own `as_forecast_()` function. +#' Every forecast type has its own `as_forecast_()` function. #' See the details section below for more information #' on the expected input formats. #' -#' The `as_forecast_()` functions give users some control over how their data -#' is parsed. +#' The `as_forecast_()` functions give users some control over how their +#' data is parsed. #' Using the arguments `observed`, `predicted`, `model`, etc. users can rename #' existing columns of their input data to match the required columns for a #' forecast object. Using the argument `forecast_unit`, users can specify the #' the columns that uniquely identify a single forecast (and remove the others, #' see [set_forecast_unit()] for details). #' +#' The following functions are available: +#' - [as_forecast_point()] +#' - [as_forecast_binary()] +#' - [as_forecast_sample()] +#' - [as_forecast_quantile()] +#' #' @param data A data.frame (or similar) with predicted and observed values. #' See the details section of [as_forecast()] for additional information #' on required input formats. @@ -43,6 +49,8 @@ #' - `forecast_sample` for sample-based forecasts #' - `forecast_quantile` for quantile-based forecasts #' @keywords check-forecasts +#' @seealso [as_forecast_point()], [as_forecast_binary()], +#' [as_forecast_sample()], [as_forecast_quantile()] #' @examples #' as_forecast_binary(example_binary) #' as_forecast_quantile( @@ -99,7 +107,7 @@ as_forecast_generic <- function(data, } -#' @rdname as_forecast +#' @title Create a `forecast` object for binary forecasts #' @export #' @importFrom cli cli_warn as_forecast_binary <- function(data, @@ -114,13 +122,20 @@ as_forecast_binary <- function(data, } -#' @rdname as_forecast +#' @title Create a `forecast` object for point forecasts +#' @description +#' Create a `forecast` object for point forecasts. See more information on +#' forecast types and expected input formats by calling `?`[as_forecast()]. +#' @inherit as_forecast params +#' @seealso [as_forecast()], [as_forecast_point()], [as_forecast_binary()], +#' [as_forecast_sample()], [as_forecast_quantile()] #' @export as_forecast_point <- function(data, ...) { UseMethod("as_forecast_point") } -#' @rdname as_forecast + +#' @rdname as_forecast_point #' @export #' @importFrom cli cli_warn as_forecast_point.default <- function(data, @@ -136,7 +151,7 @@ as_forecast_point.default <- function(data, } -#' @rdname as_forecast +#' @rdname as_forecast_point #' @export #' @keywords check-forecasts as_forecast_point.forecast_quantile <- function(data, ...) { @@ -151,14 +166,19 @@ as_forecast_point.forecast_quantile <- function(data, ...) { } -#' @rdname as_forecast +#' @title Create a `forecast` object for quantile-based forecasts +#' @description +#' Create a `forecast` object for quantile-based forecasts. See more information +#' on forecast types and expected input formats by calling `?`[as_forecast()]. +#' @seealso [as_forecast_point()], [as_forecast_binary()], +#' [as_forecast_sample()], [as_forecast_quantile()] #' @export as_forecast_quantile <- function(data, ...) { UseMethod("as_forecast_quantile") } -#' @rdname as_forecast +#' @rdname as_forecast_quantile #' @param quantile_level (optional) Name of the column in `data` that contains #' the quantile level of the predicted values. This column will be renamed to #' "quantile_level". Only applicable to quantile-based forecasts. @@ -183,9 +203,10 @@ as_forecast_quantile.default <- function(data, } -#' @rdname as_forecast -#' @param quantile_level A numeric vector of quantile levels for which -#' quantiles will be computed. +#' @rdname as_forecast_quantile +#' @param probs A numeric vector of quantile levels for which +#' quantiles will be computed. Corresponds to the `probs` argument in +#' [quantile()]. #' @param type Type argument passed down to the quantile function. For more #' information, see [quantile()]. #' @importFrom stats quantile @@ -194,23 +215,23 @@ as_forecast_quantile.default <- function(data, #' @export as_forecast_quantile.forecast_sample <- function( data, - quantile_level = c(0.05, 0.25, 0.5, 0.75, 0.95), + probs = c(0.05, 0.25, 0.5, 0.75, 0.95), type = 7, ... ) { forecast <- copy(data) assert_forecast(forecast, verbose = FALSE) - assert_numeric(quantile_level, min.len = 1) + assert_numeric(probs, min.len = 1) reserved_columns <- c("predicted", "sample_id") by <- setdiff(colnames(forecast), reserved_columns) quantile_level <- unique( - round(c(quantile_level, 1 - quantile_level), digits = 10) + round(c(probs, 1 - probs), digits = 10) ) forecast <- forecast[, .(quantile_level = quantile_level, - predicted = quantile(x = predicted, probs = ..quantile_level, + predicted = quantile(x = predicted, probs = ..probs, type = ..type, na.rm = TRUE)), by = by] @@ -221,11 +242,13 @@ as_forecast_quantile.forecast_sample <- function( } -#' @rdname as_forecast +#' @title Create a `forecast` object for sample-based forecasts #' @param sample_id (optional) Name of the column in `data` that contains the #' sample id. This column will be renamed to "sample_id". Only applicable to #' sample-based forecasts. #' @export +#' @seealso [as_forecast_point()], [as_forecast_binary()], +#' [as_forecast_sample()], [as_forecast_quantile()] #' @importFrom cli cli_warn as_forecast_sample <- function(data, forecast_unit = NULL, diff --git a/R/utils_data_handling.R b/R/utils_data_handling.R index 0c169bf5..1b8ea27d 100644 --- a/R/utils_data_handling.R +++ b/R/utils_data_handling.R @@ -157,7 +157,7 @@ sample_to_interval_long <- function(data, data <- as_forecast_quantile( data, - quantile_level = quantile_levels, + probs = quantile_levels, type = type ) diff --git a/man/as_forecast.Rd b/man/as_forecast.Rd index e1afafe1..3fda18ef 100644 --- a/man/as_forecast.Rd +++ b/man/as_forecast.Rd @@ -2,64 +2,7 @@ % Please edit documentation in R/forecast.R \name{as_forecast} \alias{as_forecast} -\alias{as_forecast_binary} -\alias{as_forecast_point} -\alias{as_forecast_point.default} -\alias{as_forecast_point.forecast_quantile} -\alias{as_forecast_quantile} -\alias{as_forecast_quantile.default} -\alias{as_forecast_quantile.forecast_sample} -\alias{as_forecast_sample} \title{Create a \code{forecast} object} -\usage{ -as_forecast_binary( - data, - forecast_unit = NULL, - observed = NULL, - predicted = NULL, - model = NULL -) - -as_forecast_point(data, ...) - -\method{as_forecast_point}{default}( - data, - forecast_unit = NULL, - observed = NULL, - predicted = NULL, - model = NULL, - ... -) - -\method{as_forecast_point}{forecast_quantile}(data, ...) - -as_forecast_quantile(data, ...) - -\method{as_forecast_quantile}{default}( - data, - forecast_unit = NULL, - observed = NULL, - predicted = NULL, - model = NULL, - quantile_level = NULL -) - -\method{as_forecast_quantile}{forecast_sample}( - data, - quantile_level = c(0.05, 0.25, 0.5, 0.75, 0.95), - type = 7, - ... -) - -as_forecast_sample( - data, - forecast_unit = NULL, - observed = NULL, - predicted = NULL, - model = NULL, - sample_id = NULL -) -} \arguments{ \item{data}{A data.frame (or similar) with predicted and observed values. See the details section of \code{\link[=as_forecast]{as_forecast()}} for additional information @@ -81,16 +24,6 @@ predicted values. This column will be renamed to "predicted".} \item{model}{(optional) Name of the column in \code{data} that contains the names of the models/forecasters that generated the predicted values. This column will be renamed to "model".} - -\item{quantile_level}{A numeric vector of quantile levels for which -quantiles will be computed.} - -\item{type}{Type argument passed down to the quantile function. For more -information, see \code{\link[=quantile]{quantile()}}.} - -\item{sample_id}{(optional) Name of the column in \code{data} that contains the -sample id. This column will be renamed to "sample_id". Only applicable to -sample-based forecasts.} } \value{ Depending on the forecast type, an object of the following class will be @@ -107,17 +40,25 @@ Process and validate a data.frame (or similar) or similar with forecasts and observations. If the input passes all input checks, it will be converted to a \code{forecast} object. A forecast object is a \code{data.table} with a class \code{forecast} and an additional class that depends on the forecast type. -Every forecast type has its own \code{as_forecast_()} function. +Every forecast type has its own \verb{as_forecast_()} function. See the details section below for more information on the expected input formats. -The \code{as_forecast_()} functions give users some control over how their data -is parsed. +The \verb{as_forecast_()} functions give users some control over how their +data is parsed. Using the arguments \code{observed}, \code{predicted}, \code{model}, etc. users can rename existing columns of their input data to match the required columns for a forecast object. Using the argument \code{forecast_unit}, users can specify the the columns that uniquely identify a single forecast (and remove the others, see \code{\link[=set_forecast_unit]{set_forecast_unit()}} for details). + +The following functions are available: +\itemize{ +\item \code{\link[=as_forecast_point]{as_forecast_point()}} +\item \code{\link[=as_forecast_binary]{as_forecast_binary()}} +\item \code{\link[=as_forecast_sample]{as_forecast_sample()}} +\item \code{\link[=as_forecast_quantile]{as_forecast_quantile()}} +} } \section{Forecast types and input formats}{ Various different forecast types / forecast formats are supported. At the @@ -200,4 +141,8 @@ as_forecast_quantile( "horizon", "location") ) } +\seealso{ +\code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, +\code{\link[=as_forecast_sample]{as_forecast_sample()}}, \code{\link[=as_forecast_quantile]{as_forecast_quantile()}} +} \keyword{check-forecasts} diff --git a/man/as_forecast_binary.Rd b/man/as_forecast_binary.Rd new file mode 100644 index 00000000..d6e2ce1a --- /dev/null +++ b/man/as_forecast_binary.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/forecast.R +\name{as_forecast_binary} +\alias{as_forecast_binary} +\title{Create a \code{forecast} object for binary forecasts} +\usage{ +as_forecast_binary( + data, + forecast_unit = NULL, + observed = NULL, + predicted = NULL, + model = NULL +) +} +\description{ +Create a \code{forecast} object for binary forecasts +} diff --git a/man/as_forecast_point.Rd b/man/as_forecast_point.Rd new file mode 100644 index 00000000..65634271 --- /dev/null +++ b/man/as_forecast_point.Rd @@ -0,0 +1,52 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/forecast.R +\name{as_forecast_point} +\alias{as_forecast_point} +\alias{as_forecast_point.default} +\alias{as_forecast_point.forecast_quantile} +\title{Create a \code{forecast} object for point forecasts} +\usage{ +as_forecast_point(data, ...) + +\method{as_forecast_point}{default}( + data, + forecast_unit = NULL, + observed = NULL, + predicted = NULL, + model = NULL, + ... +) + +\method{as_forecast_point}{forecast_quantile}(data, ...) +} +\arguments{ +\item{data}{A data.frame (or similar) with predicted and observed values. +See the details section of \code{\link[=as_forecast]{as_forecast()}} for additional information +on required input formats.} + +\item{forecast_unit}{(optional) Name of the columns in \code{data} (after +any renaming of columns) that denote the unit of a +single forecast. See \code{\link[=get_forecast_unit]{get_forecast_unit()}} for details. +If \code{NULL} (the default), all columns that are not required columns are +assumed to form the unit of a single forecast. If specified, all columns +that are not part of the forecast unit (or required columns) will be removed.} + +\item{observed}{(optional) Name of the column in \code{data} that contains the +observed values. This column will be renamed to "observed".} + +\item{predicted}{(optional) Name of the column in \code{data} that contains the +predicted values. This column will be renamed to "predicted".} + +\item{model}{(optional) Name of the column in \code{data} that contains the names +of the models/forecasters that generated the predicted values. +This column will be renamed to "model".} +} +\description{ +Create a \code{forecast} object for point forecasts. See more information on +forecast types and expected input formats by calling \verb{?}\code{\link[=as_forecast]{as_forecast()}}. +} +\seealso{ +\code{\link[=as_forecast]{as_forecast()}}, \code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, +\code{\link[=as_forecast_sample]{as_forecast_sample()}}, \code{\link[=as_forecast_quantile]{as_forecast_quantile()}} +} +\keyword{check-forecasts} diff --git a/man/as_forecast_quantile.Rd b/man/as_forecast_quantile.Rd new file mode 100644 index 00000000..b4a73787 --- /dev/null +++ b/man/as_forecast_quantile.Rd @@ -0,0 +1,46 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/forecast.R +\name{as_forecast_quantile} +\alias{as_forecast_quantile} +\alias{as_forecast_quantile.default} +\alias{as_forecast_quantile.forecast_sample} +\title{Create a \code{forecast} object for quantile-based forecasts} +\usage{ +as_forecast_quantile(data, ...) + +\method{as_forecast_quantile}{default}( + data, + forecast_unit = NULL, + observed = NULL, + predicted = NULL, + model = NULL, + quantile_level = NULL +) + +\method{as_forecast_quantile}{forecast_sample}( + data, + probs = c(0.05, 0.25, 0.5, 0.75, 0.95), + type = 7, + ... +) +} +\arguments{ +\item{quantile_level}{(optional) Name of the column in \code{data} that contains +the quantile level of the predicted values. This column will be renamed to +"quantile_level". Only applicable to quantile-based forecasts.} + +\item{probs}{A numeric vector of quantile levels for which +quantiles will be computed. Corresponds to the \code{probs} argument in +\code{\link[=quantile]{quantile()}}.} + +\item{type}{Type argument passed down to the quantile function. For more +information, see \code{\link[=quantile]{quantile()}}.} +} +\description{ +Create a \code{forecast} object for quantile-based forecasts. See more information +on forecast types and expected input formats by calling \verb{?}\code{\link[=as_forecast]{as_forecast()}}. +} +\seealso{ +\code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, +\code{\link[=as_forecast_sample]{as_forecast_sample()}}, \code{\link[=as_forecast_quantile]{as_forecast_quantile()}} +} diff --git a/man/as_forecast_sample.Rd b/man/as_forecast_sample.Rd new file mode 100644 index 00000000..204e0c94 --- /dev/null +++ b/man/as_forecast_sample.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/forecast.R +\name{as_forecast_sample} +\alias{as_forecast_sample} +\title{Create a \code{forecast} object for sample-based forecasts} +\usage{ +as_forecast_sample( + data, + forecast_unit = NULL, + observed = NULL, + predicted = NULL, + model = NULL, + sample_id = NULL +) +} +\arguments{ +\item{sample_id}{(optional) Name of the column in \code{data} that contains the +sample id. This column will be renamed to "sample_id". Only applicable to +sample-based forecasts.} +} +\description{ +Create a \code{forecast} object for sample-based forecasts +} +\seealso{ +\code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, +\code{\link[=as_forecast_sample]{as_forecast_sample()}}, \code{\link[=as_forecast_quantile]{as_forecast_quantile()}} +} diff --git a/man/sample_to_interval_long.Rd b/man/sample_to_interval_long.Rd index c16254a0..959d1a1b 100644 --- a/man/sample_to_interval_long.Rd +++ b/man/sample_to_interval_long.Rd @@ -12,10 +12,6 @@ sample_to_interval_long( ) } \arguments{ -\item{data}{A data.frame (or similar) with predicted and observed values. -See the details section of \code{\link[=as_forecast]{as_forecast()}} for additional information -on required input formats.} - \item{type}{Type argument passed down to the quantile function. For more information, see \code{\link[=quantile]{quantile()}}.} diff --git a/tests/testthat/test-utils_data_handling.R b/tests/testthat/test-utils_data_handling.R index 6ece4d05..0d6eaa63 100644 --- a/tests/testthat/test-utils_data_handling.R +++ b/tests/testthat/test-utils_data_handling.R @@ -78,7 +78,7 @@ test_that("as_forecast_quantiles works", { ) expect_no_condition( - as_forecast_quantile(samples, quantile_level = c(0.25, 0.75)) + as_forecast_quantile(samples, probs = c(0.25, 0.75)) ) wrongclass <- as_forecast_sample(samples) @@ -91,7 +91,7 @@ test_that("as_forecast_quantiles works", { quantile2 <- as_forecast_quantile( as_forecast_sample(samples), - quantile_level = c(0.25, 0.75) + probs = c(0.25, 0.75) ) expect_equal(quantile, as.data.frame(quantile2)) @@ -103,7 +103,7 @@ test_that("as_forecast_quantiles works", { quantile3 <- as_forecast_quantile( as_forecast_sample(samples), - quantile_level = c(0.25, 0.75) + probs = c(0.25, 0.75) ) quantile3$type <- NULL @@ -118,7 +118,7 @@ test_that("as_forecast_quantiles issue 557 fix", { out <- example_sample_discrete %>% as_forecast_sample() %>% as_forecast_quantile( - quantile_level = c(0.01, 0.025, seq(0.05, 0.95, 0.05), 0.975, 0.99) + probs = c(0.01, 0.025, seq(0.05, 0.95, 0.05), 0.975, 0.99) ) %>% score() From ebd6db6a45f7ce95cf73440fc0d33345ab0d5ae0 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Sun, 28 Jul 2024 13:04:36 +0200 Subject: [PATCH 3/8] Update docs --- R/forecast.R | 26 +++++++++++++++++++++++--- R/z_globalVariables.R | 2 +- man/as_forecast_binary.Rd | 29 ++++++++++++++++++++++++++++- man/as_forecast_point.Rd | 5 +++++ man/as_forecast_quantile.Rd | 34 ++++++++++++++++++++++++++++++++-- man/as_forecast_sample.Rd | 23 ++++++++++++++++++++++- man/sample_to_interval_long.Rd | 4 ++++ 7 files changed, 115 insertions(+), 8 deletions(-) diff --git a/R/forecast.R b/R/forecast.R index d8a6a32b..2cfa6cc8 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -108,7 +108,13 @@ as_forecast_generic <- function(data, #' @title Create a `forecast` object for binary forecasts +#' @description +#' Create a `forecast` object for binary forecasts. See more information on +#' forecast types and expected input formats by calling `?`[as_forecast()]. #' @export +#' @inheritParams as_forecast +#' @seealso [as_forecast()], [as_forecast_point()], [as_forecast_binary()], +#' [as_forecast_sample()], [as_forecast_quantile()] #' @importFrom cli cli_warn as_forecast_binary <- function(data, forecast_unit = NULL, @@ -127,6 +133,7 @@ as_forecast_binary <- function(data, #' Create a `forecast` object for point forecasts. See more information on #' forecast types and expected input formats by calling `?`[as_forecast()]. #' @inherit as_forecast params +#' @param ... Unused #' @seealso [as_forecast()], [as_forecast_point()], [as_forecast_binary()], #' [as_forecast_sample()], [as_forecast_quantile()] #' @export @@ -152,6 +159,9 @@ as_forecast_point.default <- function(data, #' @rdname as_forecast_point +#' @description +#' When converting a `forecast_quantile` object into a `forecast_point` object, +#' the 0.5 quantile is extracted and returned as the point forecast. #' @export #' @keywords check-forecasts as_forecast_point.forecast_quantile <- function(data, ...) { @@ -170,8 +180,10 @@ as_forecast_point.forecast_quantile <- function(data, ...) { #' @description #' Create a `forecast` object for quantile-based forecasts. See more information #' on forecast types and expected input formats by calling `?`[as_forecast()]. -#' @seealso [as_forecast_point()], [as_forecast_binary()], +#' @param ... Unused +#' @seealso [as_forecast()], [as_forecast_point()], [as_forecast_binary()], #' [as_forecast_sample()], [as_forecast_quantile()] +#' @inheritParams as_forecast #' @export as_forecast_quantile <- function(data, ...) { UseMethod("as_forecast_quantile") @@ -189,7 +201,8 @@ as_forecast_quantile.default <- function(data, observed = NULL, predicted = NULL, model = NULL, - quantile_level = NULL) { + quantile_level = NULL, + ...) { assert_character(quantile_level, len = 1, null.ok = TRUE) assert_subset(quantile_level, names(data), empty.ok = TRUE) if (!is.null(quantile_level)) { @@ -204,6 +217,12 @@ as_forecast_quantile.default <- function(data, #' @rdname as_forecast_quantile +#' @description +#' When creating a `forecast_quantile` object from a `forecast_sample` object, +#' the quantiles are estimated by computing empircal quantiles from the samples +#' via [quantile()]. Note that empirical quantiles are a biased estimator for +#' the true quantiles in particular in the tails of the distribution and +#' when the number of available samples is low. #' @param probs A numeric vector of quantile levels for which #' quantiles will be computed. Corresponds to the `probs` argument in #' [quantile()]. @@ -246,8 +265,9 @@ as_forecast_quantile.forecast_sample <- function( #' @param sample_id (optional) Name of the column in `data` that contains the #' sample id. This column will be renamed to "sample_id". Only applicable to #' sample-based forecasts. +#' @inheritParams as_forecast #' @export -#' @seealso [as_forecast_point()], [as_forecast_binary()], +#' @seealso [as_forecast()], [as_forecast_point()], [as_forecast_binary()], #' [as_forecast_sample()], [as_forecast_quantile()] #' @importFrom cli cli_warn as_forecast_sample <- function(data, diff --git a/R/z_globalVariables.R b/R/z_globalVariables.R index d2037617..37c463cc 100644 --- a/R/z_globalVariables.R +++ b/R/z_globalVariables.R @@ -1,6 +1,6 @@ globalVariables(c( "..index", - "..quantile_level", + "..probs", "..type", ".", ".SD", diff --git a/man/as_forecast_binary.Rd b/man/as_forecast_binary.Rd index d6e2ce1a..20386d19 100644 --- a/man/as_forecast_binary.Rd +++ b/man/as_forecast_binary.Rd @@ -12,6 +12,33 @@ as_forecast_binary( model = NULL ) } +\arguments{ +\item{data}{A data.frame (or similar) with predicted and observed values. +See the details section of \code{\link[=as_forecast]{as_forecast()}} for additional information +on required input formats.} + +\item{forecast_unit}{(optional) Name of the columns in \code{data} (after +any renaming of columns) that denote the unit of a +single forecast. See \code{\link[=get_forecast_unit]{get_forecast_unit()}} for details. +If \code{NULL} (the default), all columns that are not required columns are +assumed to form the unit of a single forecast. If specified, all columns +that are not part of the forecast unit (or required columns) will be removed.} + +\item{observed}{(optional) Name of the column in \code{data} that contains the +observed values. This column will be renamed to "observed".} + +\item{predicted}{(optional) Name of the column in \code{data} that contains the +predicted values. This column will be renamed to "predicted".} + +\item{model}{(optional) Name of the column in \code{data} that contains the names +of the models/forecasters that generated the predicted values. +This column will be renamed to "model".} +} \description{ -Create a \code{forecast} object for binary forecasts +Create a \code{forecast} object for binary forecasts. See more information on +forecast types and expected input formats by calling \verb{?}\code{\link[=as_forecast]{as_forecast()}}. +} +\seealso{ +\code{\link[=as_forecast]{as_forecast()}}, \code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, +\code{\link[=as_forecast_sample]{as_forecast_sample()}}, \code{\link[=as_forecast_quantile]{as_forecast_quantile()}} } diff --git a/man/as_forecast_point.Rd b/man/as_forecast_point.Rd index 65634271..25da6844 100644 --- a/man/as_forecast_point.Rd +++ b/man/as_forecast_point.Rd @@ -24,6 +24,8 @@ as_forecast_point(data, ...) See the details section of \code{\link[=as_forecast]{as_forecast()}} for additional information on required input formats.} +\item{...}{Unused} + \item{forecast_unit}{(optional) Name of the columns in \code{data} (after any renaming of columns) that denote the unit of a single forecast. See \code{\link[=get_forecast_unit]{get_forecast_unit()}} for details. @@ -44,6 +46,9 @@ This column will be renamed to "model".} \description{ Create a \code{forecast} object for point forecasts. See more information on forecast types and expected input formats by calling \verb{?}\code{\link[=as_forecast]{as_forecast()}}. + +When converting a \code{forecast_quantile} object into a \code{forecast_point} object, +the 0.5 quantile is extracted and returned as the point forecast. } \seealso{ \code{\link[=as_forecast]{as_forecast()}}, \code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, diff --git a/man/as_forecast_quantile.Rd b/man/as_forecast_quantile.Rd index b4a73787..7b1d77c5 100644 --- a/man/as_forecast_quantile.Rd +++ b/man/as_forecast_quantile.Rd @@ -14,7 +14,8 @@ as_forecast_quantile(data, ...) observed = NULL, predicted = NULL, model = NULL, - quantile_level = NULL + quantile_level = NULL, + ... ) \method{as_forecast_quantile}{forecast_sample}( @@ -25,6 +26,29 @@ as_forecast_quantile(data, ...) ) } \arguments{ +\item{data}{A data.frame (or similar) with predicted and observed values. +See the details section of \code{\link[=as_forecast]{as_forecast()}} for additional information +on required input formats.} + +\item{...}{Unused} + +\item{forecast_unit}{(optional) Name of the columns in \code{data} (after +any renaming of columns) that denote the unit of a +single forecast. See \code{\link[=get_forecast_unit]{get_forecast_unit()}} for details. +If \code{NULL} (the default), all columns that are not required columns are +assumed to form the unit of a single forecast. If specified, all columns +that are not part of the forecast unit (or required columns) will be removed.} + +\item{observed}{(optional) Name of the column in \code{data} that contains the +observed values. This column will be renamed to "observed".} + +\item{predicted}{(optional) Name of the column in \code{data} that contains the +predicted values. This column will be renamed to "predicted".} + +\item{model}{(optional) Name of the column in \code{data} that contains the names +of the models/forecasters that generated the predicted values. +This column will be renamed to "model".} + \item{quantile_level}{(optional) Name of the column in \code{data} that contains the quantile level of the predicted values. This column will be renamed to "quantile_level". Only applicable to quantile-based forecasts.} @@ -39,8 +63,14 @@ information, see \code{\link[=quantile]{quantile()}}.} \description{ Create a \code{forecast} object for quantile-based forecasts. See more information on forecast types and expected input formats by calling \verb{?}\code{\link[=as_forecast]{as_forecast()}}. + +When creating a \code{forecast_quantile} object from a \code{forecast_sample} object, +the quantiles are estimated by computing empircal quantiles from the samples +via \code{\link[=quantile]{quantile()}}. Note that empirical quantiles are a biased estimator for +the true quantiles in particular in the tails of the distribution and +when the number of available samples is low. } \seealso{ -\code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, +\code{\link[=as_forecast]{as_forecast()}}, \code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, \code{\link[=as_forecast_sample]{as_forecast_sample()}}, \code{\link[=as_forecast_quantile]{as_forecast_quantile()}} } diff --git a/man/as_forecast_sample.Rd b/man/as_forecast_sample.Rd index 204e0c94..10d22f5c 100644 --- a/man/as_forecast_sample.Rd +++ b/man/as_forecast_sample.Rd @@ -14,6 +14,27 @@ as_forecast_sample( ) } \arguments{ +\item{data}{A data.frame (or similar) with predicted and observed values. +See the details section of \code{\link[=as_forecast]{as_forecast()}} for additional information +on required input formats.} + +\item{forecast_unit}{(optional) Name of the columns in \code{data} (after +any renaming of columns) that denote the unit of a +single forecast. See \code{\link[=get_forecast_unit]{get_forecast_unit()}} for details. +If \code{NULL} (the default), all columns that are not required columns are +assumed to form the unit of a single forecast. If specified, all columns +that are not part of the forecast unit (or required columns) will be removed.} + +\item{observed}{(optional) Name of the column in \code{data} that contains the +observed values. This column will be renamed to "observed".} + +\item{predicted}{(optional) Name of the column in \code{data} that contains the +predicted values. This column will be renamed to "predicted".} + +\item{model}{(optional) Name of the column in \code{data} that contains the names +of the models/forecasters that generated the predicted values. +This column will be renamed to "model".} + \item{sample_id}{(optional) Name of the column in \code{data} that contains the sample id. This column will be renamed to "sample_id". Only applicable to sample-based forecasts.} @@ -22,6 +43,6 @@ sample-based forecasts.} Create a \code{forecast} object for sample-based forecasts } \seealso{ -\code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, +\code{\link[=as_forecast]{as_forecast()}}, \code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, \code{\link[=as_forecast_sample]{as_forecast_sample()}}, \code{\link[=as_forecast_quantile]{as_forecast_quantile()}} } diff --git a/man/sample_to_interval_long.Rd b/man/sample_to_interval_long.Rd index 959d1a1b..c16254a0 100644 --- a/man/sample_to_interval_long.Rd +++ b/man/sample_to_interval_long.Rd @@ -12,6 +12,10 @@ sample_to_interval_long( ) } \arguments{ +\item{data}{A data.frame (or similar) with predicted and observed values. +See the details section of \code{\link[=as_forecast]{as_forecast()}} for additional information +on required input formats.} + \item{type}{Type argument passed down to the quantile function. For more information, see \code{\link[=quantile]{quantile()}}.} From d3b0f7dc660b68693d59a940082d134cda9ab1dd Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Sun, 28 Jul 2024 13:10:31 +0200 Subject: [PATCH 4/8] Update News file --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index e11ae9ed..c4370202 100644 --- a/NEWS.md +++ b/NEWS.md @@ -23,6 +23,7 @@ of our [original](https://doi.org/10.48550/arXiv.2205.07090) `scoringutils` pape ### Creating a forecast object - The `as_forecast_()` functions create a forecast object and validates it. They also allow users to rename/specify required columns and specify the forecast unit in a single step, taking over the functionality of `set_forecast_unit()` in most cases. +- Some `as_forecast_()` functions like e.g. `as_forecast_point()` and `as_forecast_quantile()` have S3 methods for converting from another forecast type to the respective forecast type. For example, `as_forecast_quantile()` has a method for converting from a `forecast_sample` object to a `forecast_quantile` object by estimating quantiles from the samples. ### Updated workflows - An example workflow for scoring a forecast now looks like this: From 9b5d0eb85faa805847dce43565797ec138e63e81 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Sun, 28 Jul 2024 13:10:59 +0200 Subject: [PATCH 5/8] Update news file again --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index c4370202..ad7f22fc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -22,7 +22,7 @@ of our [original](https://doi.org/10.48550/arXiv.2205.07090) `scoringutils` pape - the CRPS is now reported as decomposition into dispersion, overprediction and underprediction. ### Creating a forecast object -- The `as_forecast_()` functions create a forecast object and validates it. They also allow users to rename/specify required columns and specify the forecast unit in a single step, taking over the functionality of `set_forecast_unit()` in most cases. +- The `as_forecast_()` functions create a forecast object and validates it. They also allow users to rename/specify required columns and specify the forecast unit in a single step, taking over the functionality of `set_forecast_unit()` in most cases. See `?as_forecast()` for more information. - Some `as_forecast_()` functions like e.g. `as_forecast_point()` and `as_forecast_quantile()` have S3 methods for converting from another forecast type to the respective forecast type. For example, `as_forecast_quantile()` has a method for converting from a `forecast_sample` object to a `forecast_quantile` object by estimating quantiles from the samples. ### Updated workflows From f9f35c0084809b1f71774833f240e95e88522bbb Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Sun, 28 Jul 2024 13:25:37 +0200 Subject: [PATCH 6/8] fix pkgdown and R4.0 issue with pipe --- R/forecast.R | 4 ++++ man/as_forecast_binary.Rd | 1 + man/as_forecast_quantile.Rd | 1 + man/as_forecast_sample.Rd | 1 + tests/testthat/test-utils_data_handling.R | 2 +- 5 files changed, 8 insertions(+), 1 deletion(-) diff --git a/R/forecast.R b/R/forecast.R index 2cfa6cc8..7ce02f38 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -116,6 +116,7 @@ as_forecast_generic <- function(data, #' @seealso [as_forecast()], [as_forecast_point()], [as_forecast_binary()], #' [as_forecast_sample()], [as_forecast_quantile()] #' @importFrom cli cli_warn +#' @keywords check-forecasts as_forecast_binary <- function(data, forecast_unit = NULL, observed = NULL, @@ -137,6 +138,7 @@ as_forecast_binary <- function(data, #' @seealso [as_forecast()], [as_forecast_point()], [as_forecast_binary()], #' [as_forecast_sample()], [as_forecast_quantile()] #' @export +#' @keywords check-forecasts as_forecast_point <- function(data, ...) { UseMethod("as_forecast_point") } @@ -185,6 +187,7 @@ as_forecast_point.forecast_quantile <- function(data, ...) { #' [as_forecast_sample()], [as_forecast_quantile()] #' @inheritParams as_forecast #' @export +#' @keywords check-forecasts as_forecast_quantile <- function(data, ...) { UseMethod("as_forecast_quantile") } @@ -270,6 +273,7 @@ as_forecast_quantile.forecast_sample <- function( #' @seealso [as_forecast()], [as_forecast_point()], [as_forecast_binary()], #' [as_forecast_sample()], [as_forecast_quantile()] #' @importFrom cli cli_warn +#' @keywords check-forecasts as_forecast_sample <- function(data, forecast_unit = NULL, observed = NULL, diff --git a/man/as_forecast_binary.Rd b/man/as_forecast_binary.Rd index 20386d19..c965d9a1 100644 --- a/man/as_forecast_binary.Rd +++ b/man/as_forecast_binary.Rd @@ -42,3 +42,4 @@ forecast types and expected input formats by calling \verb{?}\code{\link[=as_for \code{\link[=as_forecast]{as_forecast()}}, \code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, \code{\link[=as_forecast_sample]{as_forecast_sample()}}, \code{\link[=as_forecast_quantile]{as_forecast_quantile()}} } +\keyword{check-forecasts} diff --git a/man/as_forecast_quantile.Rd b/man/as_forecast_quantile.Rd index 7b1d77c5..edb5d5e5 100644 --- a/man/as_forecast_quantile.Rd +++ b/man/as_forecast_quantile.Rd @@ -74,3 +74,4 @@ when the number of available samples is low. \code{\link[=as_forecast]{as_forecast()}}, \code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, \code{\link[=as_forecast_sample]{as_forecast_sample()}}, \code{\link[=as_forecast_quantile]{as_forecast_quantile()}} } +\keyword{check-forecasts} diff --git a/man/as_forecast_sample.Rd b/man/as_forecast_sample.Rd index 10d22f5c..45e1ae98 100644 --- a/man/as_forecast_sample.Rd +++ b/man/as_forecast_sample.Rd @@ -46,3 +46,4 @@ Create a \code{forecast} object for sample-based forecasts \code{\link[=as_forecast]{as_forecast()}}, \code{\link[=as_forecast_point]{as_forecast_point()}}, \code{\link[=as_forecast_binary]{as_forecast_binary()}}, \code{\link[=as_forecast_sample]{as_forecast_sample()}}, \code{\link[=as_forecast_quantile]{as_forecast_quantile()}} } +\keyword{check-forecasts} diff --git a/tests/testthat/test-utils_data_handling.R b/tests/testthat/test-utils_data_handling.R index 0d6eaa63..2457d9e7 100644 --- a/tests/testthat/test-utils_data_handling.R +++ b/tests/testthat/test-utils_data_handling.R @@ -66,7 +66,7 @@ test_that("as_forecast_quantiles works", { observed = 1:10, predicted = c(rep(0, 10), 2:11, 3:12, 4:13, rep(100, 10)), sample_id = rep(1:5, each = 10) - ) |> + ) %>% as_forecast_sample() quantile <- data.frame( From 1904f5227be220dbb0c07c4def691b4b5e807637 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Tue, 30 Jul 2024 15:16:48 +0200 Subject: [PATCH 7/8] fix more merge conflict --- man/sample_to_quantile.Rd | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 man/sample_to_quantile.Rd diff --git a/man/sample_to_quantile.Rd b/man/sample_to_quantile.Rd deleted file mode 100644 index db885c66..00000000 --- a/man/sample_to_quantile.Rd +++ /dev/null @@ -1,36 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/utils_data_handling.R -\name{sample_to_quantile} -\alias{sample_to_quantile} -\title{Change data from a sample based format to a quantile format} -\usage{ -sample_to_quantile( - forecast, - quantile_level = c(0.05, 0.25, 0.5, 0.75, 0.95), - type = 7 -) -} -\arguments{ -\item{forecast}{A \code{forecast} object of class \code{forecast_sample} (a validated -data.table with predicted and observed values, see \code{\link[=as_forecast]{as_forecast()}}).} - -\item{quantile_level}{A numeric vector of quantile levels for which -quantiles will be computed.} - -\item{type}{Type argument passed down to the quantile function. For more -information, see \code{\link[=quantile]{quantile()}}.} -} -\value{ -a data.table in a long interval range format -} -\description{ -Transform data from a format that is based on predictive samples to a format -based on plain quantiles. -} -\examples{ -library(magrittr) # pipe operator -example_sample_discrete \%>\% - as_forecast_sample() \%>\% - sample_to_quantile() -} -\keyword{data-handling} From a1a787cecc0d87a82f2e470869908c5c15541321 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Tue, 30 Jul 2024 15:33:38 +0200 Subject: [PATCH 8/8] update tests --- tests/testthat/test-forecast.R | 6 +++++- tests/testthat/test-utils_data_handling.R | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-forecast.R b/tests/testthat/test-forecast.R index c6359cd5..7d31baf8 100644 --- a/tests/testthat/test-forecast.R +++ b/tests/testthat/test-forecast.R @@ -90,7 +90,11 @@ test_that("as_forecast() warns if there are different numbers of quantiles", { expect_no_condition(w) }) - +test_that("as_forecast_point() works", { + expect_no_condition( + as_forecast_point(as_forecast_quantile(na.omit(example_quantile))) + ) +}) test_that("check_columns_present() works", { expect_equal( diff --git a/tests/testthat/test-utils_data_handling.R b/tests/testthat/test-utils_data_handling.R index 2457d9e7..cbca2f9e 100644 --- a/tests/testthat/test-utils_data_handling.R +++ b/tests/testthat/test-utils_data_handling.R @@ -269,7 +269,13 @@ test_that("quantile_to_interval works - data.frame case", { colnames(ex_interval), c(colnames(ex), "boundary", "interval_range") ) + + expect_error( + quantile_to_interval(x = "not working"), + "Input must be either a data.frame or a numeric vector." + ) }) +