diff --git a/R/score.R b/R/score.R index 6c1298d90..5ca049fa7 100644 --- a/R/score.R +++ b/R/score.R @@ -81,7 +81,7 @@ score.forecast_binary <- function(data, metrics = metrics_binary, ...) { data <- remove_na_observed_predicted(data) metrics <- validate_metrics(metrics) - data <- apply_metrics( + data <- apply_rules( data, metrics, data$observed, data$predicted, ... ) @@ -101,7 +101,7 @@ score.forecast_point <- function(data, metrics = metrics_point, ...) { data <- remove_na_observed_predicted(data) metrics <- validate_metrics(metrics) - data <- apply_metrics( + data <- apply_rules( data, metrics, data$observed, data$predicted, ... ) @@ -135,7 +135,7 @@ score.forecast_sample <- function(data, metrics = metrics_sample, ...) { predicted <- do.call(rbind, data$predicted) data[, c("observed", "predicted", "scoringutils_N") := NULL] - data <- apply_metrics( + data <- apply_rules( data, metrics, observed, predicted, ... ) @@ -180,7 +180,7 @@ score.forecast_quantile <- function(data, metrics = metrics_quantile, ...) { "observed", "predicted", "quantile", "scoringutils_quantile" ) := NULL] - data <- apply_metrics( + data <- apply_rules( data, metrics, observed, predicted, quantile, ... ) @@ -193,7 +193,18 @@ score.forecast_quantile <- function(data, metrics = metrics_quantile, ...) { return(data[]) } -apply_metrics <- function(data, metrics, ...) { + +#' @title Apply A List Of Functions To A Data Table Of Forecasts +#' @description This helper function applies scoring rules (stored as a list of +#' functions) to a data table of forecasts. `apply_rules` is used within +#' `score()` to apply all scoring rules to the data. +#' Scoring rules are wrapped in [run_safely()] to catch errors and to make +#' sure that only arguments are passed to the scoring rule that are actually +#' accepted by it. +#' @inheritParams score +#' @return A data table with the forecasts and the calculated metrics +#' @keywords internal +apply_rules <- function(data, metrics, ...) { expr <- expression( data[, (metric_name) := do.call(run_safely, list(..., fun = fun))] ) diff --git a/man/apply_rules.Rd b/man/apply_rules.Rd new file mode 100644 index 000000000..f64ba562f --- /dev/null +++ b/man/apply_rules.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/score.R +\name{apply_rules} +\alias{apply_rules} +\title{Apply A List Of Functions To A Data Table Of Forecasts} +\usage{ +apply_rules(data, metrics, ...) +} +\arguments{ +\item{data}{A data.frame or data.table with predicted and observed values.} + +\item{metrics}{A named list of scoring functions. Names will be used as +column names in the output. See \code{\link[=metrics_point]{metrics_point()}}, \code{\link[=metrics_binary]{metrics_binary()}}, +\code{metrics_quantile()}, and \code{\link[=metrics_sample]{metrics_sample()}} for more information on the +default metrics used.} + +\item{...}{additional arguments} +} +\value{ +A data table with the forecasts and the calculated metrics +} +\description{ +This helper function applies scoring rules (stored as a list of +functions) to a data table of forecasts. \code{apply_rules} is used within +\code{score()} to apply all scoring rules to the data. +Scoring rules are wrapped in \code{\link[=run_safely]{run_safely()}} to catch errors and to make +sure that only arguments are passed to the scoring rule that are actually +accepted by it. +} +\keyword{internal} diff --git a/tests/testthat/test-score.R b/tests/testthat/test-score.R index 29132de21..ac6249528 100644 --- a/tests/testthat/test-score.R +++ b/tests/testthat/test-score.R @@ -277,16 +277,31 @@ test_that("function throws an error if data is missing", { expect_error(suppressMessages(score(data = NULL))) }) -# test_that( -# "score() can support a sample column when a quantile forecast is used", { -# ex <- example_quantile[!is.na(quantile)][1:200, ] -# ex <- rbind( -# data.table::copy(ex)[, sample_id := 1], -# ex[, sample_id := 2] -# ) -# scores <- suppressWarnings(score(ex)) -# expect_snapshot(summarise_scores( -# summarise_scores(scores, by = "model"), by = "model", -# fun = signif, digits = 2 -# )) -# }) +# ============================================================================= +# `apply_rules()` +# ============================================================================= + +test_that("apply_rules() works", { + + dt <- data.table::data.table(x = 1:10) + scoringutils:::apply_rules( + data = dt, metrics = list("test" = function(x) x + 1), + dt$x + ) + expect_equal(dt$test, 2:11) + + # additional named argument works + expect_no_condition( + scoringutils:::apply_rules( + data = dt, metrics = list("test" = function(x) x + 1), + dt$x, y = dt$test) + ) + + # additional unnamed argument does not work + + expect_warning( + scoringutils:::apply_rules( + data = dt, metrics = list("test" = function(x) x + 1), + dt$x, dt$test) + ) +})