From 55320ca6e1f5eb9b10340d69043c9c12fcc441ba Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Thu, 16 Nov 2023 18:34:19 +0100 Subject: [PATCH 1/6] Fix an issue with `correlation()` and the test for `plot_correlation()` --- R/correlations.R | 2 -- tests/testthat/test-plot_correlation.R | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/R/correlations.R b/R/correlations.R index 75eda7583..0a553e8a7 100644 --- a/R/correlations.R +++ b/R/correlations.R @@ -21,8 +21,6 @@ correlation <- function(scores, metrics = NULL, digits = NULL) { - metrics <- check_metrics(metrics) - metrics <- get_metrics(scores) # if quantile column is present, throw a warning diff --git a/tests/testthat/test-plot_correlation.R b/tests/testthat/test-plot_correlation.R index be29faf3b..0b170b963 100644 --- a/tests/testthat/test-plot_correlation.R +++ b/tests/testthat/test-plot_correlation.R @@ -1,5 +1,5 @@ test_that("plot_correlation() works as expected", { - correlations <- correlation(summarise_scores(scores), digits = 2) + correlations <- correlation(summarise_scores(scores_quantile), digits = 2) p <- plot_correlation(correlations) expect_s3_class(p, "ggplot") skip_on_cran() From 995b90b6f3eef2017c44505e9d44eea0296955b4 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Thu, 16 Nov 2023 19:18:15 +0100 Subject: [PATCH 2/6] Add a new function to check for matching dimensions in point forecasts, update tests for point and binary forecasts --- NAMESPACE | 1 + R/check-inputs-scoring-functions.R | 70 +++++++++++++++++++++++------- man/assert_dims_ok_point.Rd | 40 +++++++++++++++++ man/assert_input_binary.Rd | 3 +- man/check_dims_ok_point.Rd | 40 +++++++++++++++++ man/check_input_binary.Rd | 3 +- 6 files changed, 139 insertions(+), 18 deletions(-) create mode 100644 man/assert_dims_ok_point.Rd create mode 100644 man/check_dims_ok_point.Rd diff --git a/NAMESPACE b/NAMESPACE index d3b6ffe22..bec4cdeef 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -85,6 +85,7 @@ importFrom(checkmate,assert_list) importFrom(checkmate,assert_logical) importFrom(checkmate,assert_number) importFrom(checkmate,assert_numeric) +importFrom(checkmate,assert_vector) importFrom(checkmate,check_atomic_vector) importFrom(checkmate,check_data_frame) importFrom(checkmate,check_function) diff --git a/R/check-inputs-scoring-functions.R b/R/check-inputs-scoring-functions.R index 0e4467e3c..e1067e99d 100644 --- a/R/check-inputs-scoring-functions.R +++ b/R/check-inputs-scoring-functions.R @@ -161,25 +161,21 @@ check_input_interval <- function(observed, lower, upper, range) { #' that `predicted` represents the probability that the observed value is equal #' to the highest factor level. #' @param predicted Input to be checked. `predicted` should be a vector of -#' length n, holding probabilities. Values represent the probability that +#' length n, holding probabilities. Alternatively, `predicted` can be a matrix +#' of size n x 1. Values represent the probability that #' the corresponding value in `observed` will be equal to the highest #' available factor level. #' @importFrom checkmate assert assert_factor #' @inherit document_assert_functions return #' @keywords check-inputs assert_input_binary <- function(observed, predicted) { - if (length(observed) != length(predicted)) { - stop("`observed` and `predicted` need to be ", - "of same length when scoring binary forecasts") - } - assert_factor(observed, n.levels = 2) - levels <- levels(observed) - assert( - check_numeric_vector(predicted, min.len = 1, lower = 0, upper = 1) - ) + assert_factor(observed, n.levels = 2, min.len = 1) + assert_numeric(predicted, lower = 0, upper = 1) + assert(check_dims_ok_point(observed, predicted)) return(invisible(NULL)) } + #' @title Check that inputs are correct for binary forecast #' @inherit assert_input_binary params description #' @inherit document_check_functions return @@ -200,12 +196,9 @@ check_input_binary <- function(observed, predicted) { #' @inherit document_assert_functions return #' @keywords check-inputs assert_input_point <- function(observed, predicted) { - assert(check_numeric_vector(observed, min.len = 1)) - assert(check_numeric_vector(predicted, min.len = 1)) - if (length(observed) != length(predicted)) { - stop("`observed` and `predicted` need to be ", - "of same length when scoring point forecasts") - } + assert(check_numeric(observed)) + assert(check_numeric(predicted)) + assert(check_dims_ok_point(observed, predicted)) return(invisible(NULL)) } @@ -217,3 +210,48 @@ check_input_point <- function(observed, predicted) { result <- check_try(assert_input_point(observed, predicted)) return(result) } + + +#' Assert Inputs Have Matching Dimensions +#' @description Function assesses whether input dimensions match. In the +#' following, n is the number of observations / forecasts. Scalar values may +#' be repeated to match the length of the other input. +#' Allowed options are therefore +#' - `observed` is vector of length 1 or length n +#' - `predicted` is +#' - a vector of of length 1 or length n +#' - a matrix with n rows and 1 column +#' @inherit assert_input_binary +#' @inherit document_assert_functions return +#' @importFrom checkmate assert_vector check_matrix check_vector assert +#' @keywords check-inputs +assert_dims_ok_point <- function(observed, predicted) { + assert_vector(observed, min.len = 1) + n_obs <- length(observed) + assert( + check_vector(predicted, min.len = 1), + check_matrix(predicted, ncols = 1, nrows = n_obs) + ) + dim_p <- dim(predicted) + if (!is.null(dim_p) && (length(dim_p) > 1) && (dim_p[2] > 1)) { + stop("`predicted` must be a vector or a matrix with one column. Found ", + dim(predicted)[2], " columns") + } + n_pred <- length(as.vector(predicted)) + # check that both are either of length 1 or of equal length + if (n_obs != 1 & n_pred != 1 & n_obs != n_pred) { + stop("`observed` and `predicted` must either be of length 1 or ", + "of equal length. Found ", n_obs, " and ", n_pred) + } + return(invisible(NULL)) +} + + +#' Assert Inputs For Binary And Point Forecasts Have Matching Dimensions +#' @inherit assert_dims_ok_point params description +#' @inherit document_check_functions return +#' @keywords check-inputs +check_dims_ok_point <- function(observed, predicted) { + result <- check_try(assert_dims_ok_point(observed, predicted)) + return(result) +} diff --git a/man/assert_dims_ok_point.Rd b/man/assert_dims_ok_point.Rd new file mode 100644 index 000000000..4f6bd3bd0 --- /dev/null +++ b/man/assert_dims_ok_point.Rd @@ -0,0 +1,40 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check-inputs-scoring-functions.R +\name{assert_dims_ok_point} +\alias{assert_dims_ok_point} +\title{Assert Inputs Have Matching Dimensions} +\usage{ +assert_dims_ok_point(observed, predicted) +} +\arguments{ +\item{observed}{Input to be checked. Should be a factor of length n with +exactly two levels, holding the observed values. +The highest factor level is assumed to be the reference level. This means +that \code{predicted} represents the probability that the observed value is equal +to the highest factor level.} + +\item{predicted}{Input to be checked. \code{predicted} should be a vector of +length n, holding probabilities. Alternatively, \code{predicted} can be a matrix +of size n x 1. Values represent the probability that +the corresponding value in \code{observed} will be equal to the highest +available factor level.} +} +\value{ +Returns NULL invisibly if the assertion was successful and throws an +error otherwise. +} +\description{ +Function assesses whether input dimensions match. In the +following, n is the number of observations / forecasts. Scalar values may +be repeated to match the length of the other input. +Allowed options are therefore +\itemize{ +\item \code{observed} is vector of length 1 or length n +\item \code{predicted} is +\itemize{ +\item a vector of of length 1 or length n +\item a matrix with n rows and 1 column +} +} +} +\keyword{check-inputs} diff --git a/man/assert_input_binary.Rd b/man/assert_input_binary.Rd index 4ca8f7883..5b4d8b2bf 100644 --- a/man/assert_input_binary.Rd +++ b/man/assert_input_binary.Rd @@ -14,7 +14,8 @@ that \code{predicted} represents the probability that the observed value is equa to the highest factor level.} \item{predicted}{Input to be checked. \code{predicted} should be a vector of -length n, holding probabilities. Values represent the probability that +length n, holding probabilities. Alternatively, \code{predicted} can be a matrix +of size n x 1. Values represent the probability that the corresponding value in \code{observed} will be equal to the highest available factor level.} } diff --git a/man/check_dims_ok_point.Rd b/man/check_dims_ok_point.Rd new file mode 100644 index 000000000..aac618d05 --- /dev/null +++ b/man/check_dims_ok_point.Rd @@ -0,0 +1,40 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check-inputs-scoring-functions.R +\name{check_dims_ok_point} +\alias{check_dims_ok_point} +\title{Assert Inputs For Binary And Point Forecasts Have Matching Dimensions} +\usage{ +check_dims_ok_point(observed, predicted) +} +\arguments{ +\item{observed}{Input to be checked. Should be a factor of length n with +exactly two levels, holding the observed values. +The highest factor level is assumed to be the reference level. This means +that \code{predicted} represents the probability that the observed value is equal +to the highest factor level.} + +\item{predicted}{Input to be checked. \code{predicted} should be a vector of +length n, holding probabilities. Alternatively, \code{predicted} can be a matrix +of size n x 1. Values represent the probability that +the corresponding value in \code{observed} will be equal to the highest +available factor level.} +} +\value{ +Returns TRUE if the check was successful and a string with an +error message otherwise +} +\description{ +Function assesses whether input dimensions match. In the +following, n is the number of observations / forecasts. Scalar values may +be repeated to match the length of the other input. +Allowed options are therefore +\itemize{ +\item \code{observed} is vector of length 1 or length n +\item \code{predicted} is +\itemize{ +\item a vector of of length 1 or length n +\item a matrix with n rows and 1 column +} +} +} +\keyword{check-inputs} diff --git a/man/check_input_binary.Rd b/man/check_input_binary.Rd index 5b206f35b..10d6c36ea 100644 --- a/man/check_input_binary.Rd +++ b/man/check_input_binary.Rd @@ -14,7 +14,8 @@ that \code{predicted} represents the probability that the observed value is equa to the highest factor level.} \item{predicted}{Input to be checked. \code{predicted} should be a vector of -length n, holding probabilities. Values represent the probability that +length n, holding probabilities. Alternatively, \code{predicted} can be a matrix +of size n x 1. Values represent the probability that the corresponding value in \code{observed} will be equal to the highest available factor level.} } From 7e7f1cda61b04a228e93d2ff83f8886f325bb783 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Thu, 16 Nov 2023 19:39:40 +0100 Subject: [PATCH 3/6] update and expand binary tests --- tests/testthat/test-metrics-binary.R | 128 +++++++++++++++------------ 1 file changed, 73 insertions(+), 55 deletions(-) diff --git a/tests/testthat/test-metrics-binary.R b/tests/testthat/test-metrics-binary.R index 9c49e7050..8917ea7db 100644 --- a/tests/testthat/test-metrics-binary.R +++ b/tests/testthat/test-metrics-binary.R @@ -7,14 +7,36 @@ df <- data.table( id = 1:10 ) -# test input handling -test_that("function throws an error when missing observed or predicted", { - observed <- sample(c(0, 1), size = 10, replace = TRUE) - predicted <- replicate( - 20, - sample(c(0, 1), size = 10, replace = TRUE) + +test_that("correct input works", { + expect_no_condition( + scoringutils:::assert_input_binary(observed, predicted) + ) + + # observed is a single number and does not have the same length as predicted + expect_no_condition( + scoringutils:::assert_input_binary(factor(1, levels = c(0, 1)), predicted) ) + # predicted is a single number and does not have the same length as observed + expect_no_condition( + scoringutils:::assert_input_binary(observed, predicted = 0.2) + ) + + # predicted is a matrix with one row + expect_no_condition( + scoringutils:::assert_input_binary(observed, predicted = matrix(0.2)) + ) + + # predicted is a matrix with 1 row - this is will throw a warning in the + # actual scoring rule function + expect_no_condition( + scoringutils:::assert_input_binary(observed, matrix(predicted)) + ) +}) + +# test input handling +test_that("function throws an error when missing observed or predicted", { expect_error( brier_score(predicted = predicted), 'argument "observed" is missing, with no default' @@ -27,56 +49,39 @@ test_that("function throws an error when missing observed or predicted", { }) - -test_that("function throws an error for wrong format of `observed`", { - observed <- factor(rpois(10, lambda = 1:10)) - predicted <- runif(10, min = 0, max = 1) - +test_that("function throws an error for wrong input formats", { expect_error( brier_score( - observed = observed, + observed = rnorm(10), predicted = predicted ), - "Assertion on 'observed' failed: Must have exactly 2 levels." + "Assertion on 'observed' failed: Must be of type 'factor', not 'double'." ) - observed <- rnorm(10) + # observed value not factor expect_error( - brier_score( - observed = observed, - predicted = predicted - ), - "Assertion on 'observed' failed: Must be of type 'factor', not 'double'." + scoringutils:::assert_input_binary(1:10, predicted), + "Assertion on 'observed' failed: Must be of type 'factor', not 'integer'." + ) + + # observed value has not 2 levels + expect_error( + scoringutils:::assert_input_binary(factor(1:10), predicted), + "Assertion on 'observed' failed: Must have exactly 2 levels." ) -}) -test_that("function throws an error for wrong format of predictions", { predicted <- runif(10, min = 0, max = 1) expect_error( - brier_score( - observed = observed, - predicted = as.list(predicted) - ), + brier_score(observed = observed, predicted = as.list(predicted)), "Assertion on 'predicted' failed: Must be of type 'numeric', not 'list'." ) - predicted <- runif(15, min = 0, max = 1) + # wrong length expect_error( - brier_score( - observed = observed, - predicted = predicted - ), - "`observed` and `predicted` need to be of same length when scoring binary forecasts", - # "Arguments to the following function call: 'brier_score(observed = observed, predicted = predicted)' should have the same length (or length one). Actual lengths: 10, 15", + brier_score(observed = observed, predicted = runif(15, min = 0, max = 1)), + "Assertion on 'observed' failed: `observed` and `predicted` must either be of length 1 or of equal length. Found 10 and 15.", fixed = TRUE ) -}) - -test_that("Input checking for binary forecasts works", { - # everything correct - expect_no_condition( - scoringutils:::assert_input_binary(observed, predicted) - ) # predicted > 1 expect_error( @@ -90,38 +95,51 @@ test_that("Input checking for binary forecasts works", { "Assertion on 'predicted' failed: Element 1 is not >= 0." ) - # observed value not factor + # predicted is a matrix with 2 rows expect_error( - scoringutils:::assert_input_binary(1:10, predicted), - "Assertion on 'observed' failed: Must be of type 'factor', not 'integer'." + scoringutils:::assert_input_binary(observed, matrix(rep(predicted, 2), ncol = 2)), + "Assertion on 'observed' failed: `predicted` must be a vector or a matrix with one column. Found 2 columns." ) +}) - # observed value has not 2 levels - expect_error( - scoringutils:::assert_input_binary(factor(1:10), predicted), - "Assertion on 'observed' failed: Must have exactly 2 levels." - ) +test_that("Brier score works with different inputs", { # observed is a single number and does not have the same length as predicted - expect_error( - scoringutils:::assert_input_binary(factor(1), predicted), - "`observed` and `predicted` need to be of same length when scoring binary forecasts", - fixed = TRUE + expect_equal( + brier_score(factor(1, levels = c(0, 1)), predicted), + (1 - predicted)^2 ) - # predicted is a matrix - expect_error( - scoringutils:::assert_input_binary(observed, matrix(predicted)), - "Assertion on 'predicted' failed: Must be of type 'atomic vector', not 'matrix'." + # predicted is a single number and does not have the same length as observed + expect_equal( + brier_score(observed, predicted = 0.2), + ifelse(observed == 1, (1 - 0.2)^2, (0.2)^2) + ) + + # predicted is a matrix with 1 row + expect_warning( + brier_score(observed, predicted = matrix(0.2)), + "Recycling array of length 1 in vector-array arithmetic is deprecated. + Use c() or as.vector() instead.", + fixed = TRUE + ) + + expect_warning( + brier_score(observed, predicted = array(0.2)), + "Recycling array of length 1 in vector-array arithmetic is deprecated. + Use c() or as.vector() instead.", + fixed = TRUE ) }) + test_that("Binary metrics work within and outside of `score()`", { result <- score(df) expect_equal( brier_score(observed, predicted), result$brier_score ) + expect_equal( logs_binary(observed, predicted), result$log_score From 26d4bbbfe48be8086129a0b4dbc7068f0773b29e Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Thu, 16 Nov 2023 19:52:12 +0100 Subject: [PATCH 4/6] Add point input checks where they are very similar to binary input checks --- tests/testthat/test-metrics-binary.R | 98 ++++++++++++++++------------ 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/tests/testthat/test-metrics-binary.R b/tests/testthat/test-metrics-binary.R index 8917ea7db..a19319814 100644 --- a/tests/testthat/test-metrics-binary.R +++ b/tests/testthat/test-metrics-binary.R @@ -7,102 +7,116 @@ df <- data.table( id = 1:10 ) +observed_point <- rnorm(10) +predicted_point <- rnorm(10) +# ============================================================================== +# Test Input Checks - this also checks point inputs where functions are similar +# ============================================================================== test_that("correct input works", { - expect_no_condition( - scoringutils:::assert_input_binary(observed, predicted) - ) + expect_no_condition(assert_input_binary(observed, predicted)) + expect_no_condition(assert_input_point(observed_point, predicted_point)) # observed is a single number and does not have the same length as predicted expect_no_condition( - scoringutils:::assert_input_binary(factor(1, levels = c(0, 1)), predicted) + assert_input_binary(factor(1, levels = c(0, 1)), predicted) ) - - # predicted is a single number and does not have the same length as observed expect_no_condition( - scoringutils:::assert_input_binary(observed, predicted = 0.2) + assert_input_point(1, predicted_point) ) + # predicted is a single number and does not have the same length as observed + expect_no_condition(assert_input_binary(observed, predicted = 0.2)) + expect_no_condition(assert_input_point(observed_point, predicted = 0.2)) + # predicted is a matrix with one row - expect_no_condition( - scoringutils:::assert_input_binary(observed, predicted = matrix(0.2)) - ) + expect_no_condition(assert_input_binary(observed, predicted = matrix(0.2))) + expect_no_condition(assert_input_point(observed_point, matrix(0.2))) # predicted is a matrix with 1 row - this is will throw a warning in the # actual scoring rule function - expect_no_condition( - scoringutils:::assert_input_binary(observed, matrix(predicted)) - ) + expect_no_condition(assert_input_binary(observed, matrix(predicted))) + expect_no_condition(assert_input_point(observed_point, matrix(predicted_point))) }) # test input handling -test_that("function throws an error when missing observed or predicted", { +test_that("function throws an error for wrong input formats", { + # observed value not as expected expect_error( - brier_score(predicted = predicted), - 'argument "observed" is missing, with no default' + assert_input_binary(observed = rnorm(10), predicted = predicted), + "Assertion on 'observed' failed: Must be of type 'factor', not 'double'." ) - expect_error( - brier_score(observed = observed), - 'argument "predicted" is missing, with no default' + assert_input_binary(1:10, predicted), + "Assertion on 'observed' failed: Must be of type 'factor', not 'integer'." ) -}) - - -test_that("function throws an error for wrong input formats", { expect_error( - brier_score( - observed = rnorm(10), - predicted = predicted - ), - "Assertion on 'observed' failed: Must be of type 'factor', not 'double'." + assert_input_binary(observed = observed, predicted = as.list(predicted)), + "Assertion on 'predicted' failed: Must be of type 'numeric', not 'list'." ) - - # observed value not factor expect_error( - scoringutils:::assert_input_binary(1:10, predicted), - "Assertion on 'observed' failed: Must be of type 'factor', not 'integer'." + assert_input_point(observed = factor(rnorm(10)), predicted = predicted), + "Assertion on 'observed' failed: Must be of type 'numeric', not 'factor'." + ) + expect_error( + assert_input_point(observed = observed_point, list(predicted_point)), + "Assertion on 'predicted' failed: Must be of type 'numeric', not 'list'." ) # observed value has not 2 levels expect_error( - scoringutils:::assert_input_binary(factor(1:10), predicted), + assert_input_binary(factor(1:10), predicted), "Assertion on 'observed' failed: Must have exactly 2 levels." ) - predicted <- runif(10, min = 0, max = 1) + # wrong length expect_error( - brier_score(observed = observed, predicted = as.list(predicted)), - "Assertion on 'predicted' failed: Must be of type 'numeric', not 'list'." + assert_input_binary(observed = observed, predicted = runif(15, min = 0, max = 1)), + "Assertion on 'observed' failed: `observed` and `predicted` must either be of length 1 or of equal length. Found 10 and 15.", + fixed = TRUE ) - - # wrong length expect_error( - brier_score(observed = observed, predicted = runif(15, min = 0, max = 1)), + assert_input_point(observed_point, runif(15, min = 0, max = 1)), "Assertion on 'observed' failed: `observed` and `predicted` must either be of length 1 or of equal length. Found 10 and 15.", fixed = TRUE ) # predicted > 1 expect_error( - scoringutils:::assert_input_binary(observed, predicted + 1), + assert_input_binary(observed, predicted + 1), "Assertion on 'predicted' failed: Element 1 is not <= 1." ) # predicted < 0 expect_error( - scoringutils:::assert_input_binary(observed, predicted - 1), + assert_input_binary(observed, predicted - 1), "Assertion on 'predicted' failed: Element 1 is not >= 0." ) # predicted is a matrix with 2 rows expect_error( - scoringutils:::assert_input_binary(observed, matrix(rep(predicted, 2), ncol = 2)), + assert_input_binary(observed, matrix(rep(predicted, 2), ncol = 2)), "Assertion on 'observed' failed: `predicted` must be a vector or a matrix with one column. Found 2 columns." ) }) +# ============================================================================== +# Test Binary Metrics +# ============================================================================== + +test_that("function throws an error when missing observed or predicted", { + expect_error( + brier_score(predicted = predicted), + 'argument "observed" is missing, with no default' + ) + + expect_error( + brier_score(observed = observed), + 'argument "predicted" is missing, with no default' + ) +}) + test_that("Brier score works with different inputs", { # observed is a single number and does not have the same length as predicted expect_equal( From c33212ecf9d7cd1b47b9d161d03e2e4acb67b566 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Fri, 17 Nov 2023 09:44:33 +0100 Subject: [PATCH 5/6] Fix small typos in the check functions, update tests --- R/check-inputs-scoring-functions.R | 6 ++--- tests/testthat/test-metrics-binary.R | 37 ++++++++++++++++------------ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/R/check-inputs-scoring-functions.R b/R/check-inputs-scoring-functions.R index e1067e99d..70cfd60cc 100644 --- a/R/check-inputs-scoring-functions.R +++ b/R/check-inputs-scoring-functions.R @@ -171,7 +171,7 @@ check_input_interval <- function(observed, lower, upper, range) { assert_input_binary <- function(observed, predicted) { assert_factor(observed, n.levels = 2, min.len = 1) assert_numeric(predicted, lower = 0, upper = 1) - assert(check_dims_ok_point(observed, predicted)) + assert_dims_ok_point(observed, predicted) return(invisible(NULL)) } @@ -229,7 +229,7 @@ assert_dims_ok_point <- function(observed, predicted) { assert_vector(observed, min.len = 1) n_obs <- length(observed) assert( - check_vector(predicted, min.len = 1), + check_vector(predicted, min.len = 1, strict = TRUE), check_matrix(predicted, ncols = 1, nrows = n_obs) ) dim_p <- dim(predicted) @@ -239,7 +239,7 @@ assert_dims_ok_point <- function(observed, predicted) { } n_pred <- length(as.vector(predicted)) # check that both are either of length 1 or of equal length - if (n_obs != 1 & n_pred != 1 & n_obs != n_pred) { + if ((n_obs != 1) && (n_pred != 1) && (n_obs != n_pred)) { stop("`observed` and `predicted` must either be of length 1 or ", "of equal length. Found ", n_obs, " and ", n_pred) } diff --git a/tests/testthat/test-metrics-binary.R b/tests/testthat/test-metrics-binary.R index a19319814..79f56c535 100644 --- a/tests/testthat/test-metrics-binary.R +++ b/tests/testthat/test-metrics-binary.R @@ -29,12 +29,7 @@ test_that("correct input works", { expect_no_condition(assert_input_binary(observed, predicted = 0.2)) expect_no_condition(assert_input_point(observed_point, predicted = 0.2)) - # predicted is a matrix with one row - expect_no_condition(assert_input_binary(observed, predicted = matrix(0.2))) - expect_no_condition(assert_input_point(observed_point, matrix(0.2))) - - # predicted is a matrix with 1 row - this is will throw a warning in the - # actual scoring rule function + # predicted is a matrix with nrow equal to observed expect_no_condition(assert_input_binary(observed, matrix(predicted))) expect_no_condition(assert_input_point(observed_point, matrix(predicted_point))) }) @@ -72,7 +67,7 @@ test_that("function throws an error for wrong input formats", { # wrong length expect_error( assert_input_binary(observed = observed, predicted = runif(15, min = 0, max = 1)), - "Assertion on 'observed' failed: `observed` and `predicted` must either be of length 1 or of equal length. Found 10 and 15.", + "`observed` and `predicted` must either be of length 1 or of equal length. Found 10 and 15", fixed = TRUE ) expect_error( @@ -93,10 +88,21 @@ test_that("function throws an error for wrong input formats", { "Assertion on 'predicted' failed: Element 1 is not >= 0." ) + # predicted is a matrix with one row + expect_error( + assert_input_binary(observed, predicted = matrix(0.2)), + "Assertion failed. One of the following must apply:\n * check_vector(predicted): Must be of type 'vector', not 'matrix'\n * check_matrix(predicted): Must have exactly 10 rows, but has 1 rows", + fixed = TRUE) + expect_error( + assert_input_point(observed_point, predicted = matrix(0.2)), + "Assertion failed. One of the following must apply:\n * check_vector(predicted): Must be of type 'vector', not 'matrix'\n * check_matrix(predicted): Must have exactly 10 rows, but has 1 rows", + fixed = TRUE) + # predicted is a matrix with 2 rows expect_error( assert_input_binary(observed, matrix(rep(predicted, 2), ncol = 2)), - "Assertion on 'observed' failed: `predicted` must be a vector or a matrix with one column. Found 2 columns." + "Assertion failed. One of the following must apply:\n * check_vector(predicted): Must be of type 'vector', not 'matrix'\n * check_matrix(predicted): Must have exactly 1 cols, but has 2 cols", + fixed = TRUE ) }) @@ -131,18 +137,17 @@ test_that("Brier score works with different inputs", { ) # predicted is a matrix with 1 row - expect_warning( + expect_error( brier_score(observed, predicted = matrix(0.2)), - "Recycling array of length 1 in vector-array arithmetic is deprecated. - Use c() or as.vector() instead.", - fixed = TRUE + "Assertion failed. One of the following must apply:\n * check_vector(predicted): Must be of type 'vector', not 'matrix'\n * check_matrix(predicted): Must have exactly 10 rows, but has 1 rows", + fixed = TRUE ) - expect_warning( + # predicted is an array + expect_error( brier_score(observed, predicted = array(0.2)), - "Recycling array of length 1 in vector-array arithmetic is deprecated. - Use c() or as.vector() instead.", - fixed = TRUE + "Assertion failed. One of the following must apply:\n * check_vector(predicted): Must be of type 'vector', not 'array'\n * check_matrix(predicted): Must be of type 'matrix', not 'array'", + fixed = TRUE ) }) From 67768c57cdebed457b258a20ba5e261e11fa1f1c Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Mon, 20 Nov 2023 13:05:25 +0100 Subject: [PATCH 6/6] Update docs to make them more consistent --- R/check-inputs-scoring-functions.R | 4 ++-- man/check_dims_ok_point.Rd | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/R/check-inputs-scoring-functions.R b/R/check-inputs-scoring-functions.R index 70cfd60cc..2c36071ad 100644 --- a/R/check-inputs-scoring-functions.R +++ b/R/check-inputs-scoring-functions.R @@ -212,7 +212,7 @@ check_input_point <- function(observed, predicted) { } -#' Assert Inputs Have Matching Dimensions +#' @title Assert Inputs Have Matching Dimensions #' @description Function assesses whether input dimensions match. In the #' following, n is the number of observations / forecasts. Scalar values may #' be repeated to match the length of the other input. @@ -247,7 +247,7 @@ assert_dims_ok_point <- function(observed, predicted) { } -#' Assert Inputs For Binary And Point Forecasts Have Matching Dimensions +#' @title Check Inputs Have Matching Dimensions #' @inherit assert_dims_ok_point params description #' @inherit document_check_functions return #' @keywords check-inputs diff --git a/man/check_dims_ok_point.Rd b/man/check_dims_ok_point.Rd index aac618d05..1269a6725 100644 --- a/man/check_dims_ok_point.Rd +++ b/man/check_dims_ok_point.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/check-inputs-scoring-functions.R \name{check_dims_ok_point} \alias{check_dims_ok_point} -\title{Assert Inputs For Binary And Point Forecasts Have Matching Dimensions} +\title{Check Inputs Have Matching Dimensions} \usage{ check_dims_ok_point(observed, predicted) }