diff --git a/R/AbsBiasSS.R b/R/AbsBiasSS.R index 0ceb009c7b4dc33b6f9788dc6cb8459f0e25767b..8cb1bcee6edabb662aace1ba9e1aaa8da5e3ba82 100644 --- a/R/AbsBiasSS.R +++ b/R/AbsBiasSS.R @@ -267,7 +267,7 @@ AbsBiasSS <- function(exp, obs, ref = NULL, time_dim = 'sdate', memb_dim = NULL, bias_ref <- .Bias(exp = ref_data, obs = obs_data, na.rm = na.rm, absolute = TRUE, time_mean = FALSE) ## Skill score and significance biasSS[i, j] <- 1 - mean(bias_exp) / mean(bias_ref) - sign[i, j] <- .RandomWalkTest(skill_A = bias_exp, skill_B = bias_ref)$signif + sign[i, j] <- .RandomWalkTest(skill_A = bias_exp, skill_B = bias_ref, sign = T, pval = F)$sign } } diff --git a/R/CRPSS.R b/R/CRPSS.R index a6b4a1405a80156149cf16cad5c955b9135428c2..6b063edea4795ac7309b478300ff5abaf6d5c35e 100644 --- a/R/CRPSS.R +++ b/R/CRPSS.R @@ -276,14 +276,14 @@ CRPSS <- function(exp, obs, ref = NULL, time_dim = 'sdate', memb_dim = 'member', for (i in 1:nexp) { for (j in 1:nobs) { crpss[i, j] <- 1 - crps_exp_mean[i, j] / crps_ref_mean[j] - sign[i, j] <- .RandomWalkTest(skill_A = crps_exp_mean[i, j], skill_B = crps_ref_mean[j])$signif + sign[i, j] <- .RandomWalkTest(skill_A = crps_exp_mean[i, j], skill_B = crps_ref_mean[j], sign = T, pval = F)$sign } } } else { for (i in 1:nexp) { for (j in 1:nobs) { crpss[i, j] <- 1 - crps_exp_mean[i, j] / crps_ref_mean[i, j] - sign[i, j] <- .RandomWalkTest(skill_A = crps_exp_mean[i, j], skill_B = crps_ref_mean[i, j])$signif + sign[i, j] <- .RandomWalkTest(skill_A = crps_exp_mean[i, j], skill_B = crps_ref_mean[i, j], sign = T, pval = F)$sign } } } @@ -291,7 +291,7 @@ CRPSS <- function(exp, obs, ref = NULL, time_dim = 'sdate', memb_dim = 'member', } else { crpss <- 1 - mean(crps_exp) / mean(crps_ref) # Significance - sign <- .RandomWalkTest(skill_A = crps_exp, skill_B = crps_ref)$signif + sign <- .RandomWalkTest(skill_A = crps_exp, skill_B = crps_ref, sign = T, pval = F)$sign } return(list(crpss = crpss, sign = sign)) diff --git a/R/RPSS.R b/R/RPSS.R index 3d50d2bc554317949a4f2bba8c25d928502eddef..c1b1bf95e7e76e3e0821a672fa685e2acb23b93d 100644 --- a/R/RPSS.R +++ b/R/RPSS.R @@ -399,21 +399,21 @@ RPSS <- function(exp, obs, ref = NULL, time_dim = 'sdate', memb_dim = 'member', for (i in 1:nexp) { for (j in 1:nobs) { rpss[i, j] <- 1 - rps_exp_mean[i, j] / rps_ref_mean[j] - sign[i, j] <- .RandomWalkTest(skill_A = rps_exp_mean[i, j], skill_B = rps_ref_mean[j])$signif + sign[i, j] <- .RandomWalkTest(skill_A = rps_exp_mean[i, j], skill_B = rps_ref_mean[j], sign = T, pval = F)$sign } } } else { for (i in 1:nexp) { for (j in 1:nobs) { rpss[i, j] <- 1 - rps_exp_mean[i, j] / rps_ref_mean[i, j] - sign[i, j] <- .RandomWalkTest(skill_A = rps_exp_mean[i, j], skill_B = rps_ref_mean[i, j])$signif + sign[i, j] <- .RandomWalkTest(skill_A = rps_exp_mean[i, j], skill_B = rps_ref_mean[i, j], sign = T, pval = F)$sign } } } } else { rpss <- 1 - mean(rps_exp) / mean(rps_ref) # Significance - sign <- .RandomWalkTest(skill_A = rps_exp, skill_B = rps_ref)$signif + sign <- .RandomWalkTest(skill_A = rps_exp, skill_B = rps_ref, sign = T, pval = F)$sign } return(list(rpss = rpss, sign = sign)) diff --git a/R/RandomWalkTest.R b/R/RandomWalkTest.R index adeadc1ec94b62920c885640938f966c91e75ddc..7a222cd33fc64c5d0ca5461608b5629a5f9511b5 100644 --- a/R/RandomWalkTest.R +++ b/R/RandomWalkTest.R @@ -1,82 +1,214 @@ -#'Random walk test for skill differences +#'Random Walk test for skill differences #' #'Forecast comparison of the skill obtained with 2 forecasts (with respect to a -#'common reference) based on Random Walks, with significance estimate at the 95% -#'confidence level, as in DelSole and Tippett (2016). +#'common observational reference) based on Random Walks (DelSole and Tippett, +#'2016). #' -#'@param skill_A A numerical array of the time series of the skill with the -#' forecaster A's. -#'@param skill_B A numerical array of the time series of the skill with the -#' forecaster B's. The dimensions should be identical as parameter 'skill_A'. +#'@param skill_A A numerical array of the time series of the scores obtained +#' with the forecaster A. +#'@param skill_B A numerical array of the time series of the scores obtained +#' with the forecaster B. The dimensions should be identical as parameter +#' 'skill_A'. #'@param time_dim A character string indicating the name of the dimension along #' which the tests are computed. The default value is 'sdate'. +#'@param N.eff Effective sample size to be used in the statistical significance +#' test. It can be NA (to use the length of the "time_dim" dimension) or an +#' array with the same dimensions as "skill_A" except "time_dim" (for a +#' particular N.eff to be used for each case). The default value is NA. +#'@param test.type A character string indicating the type of significance test. +#' It can be "two.sided.approx" (to assess whether forecaster A and forecaster +#' B are significantly different in terms of skill with a two-sided test using +#' the approximation of DelSole and Tippett, 2016), "two.sided" (to assess +#' whether forecaster A and forecaster B are significantly different in terms +#' of skill with an exact two-sided test), "greater" (to assess whether +#' forecaster A shows significantly better skill than forecaster B with a +#' one-sided test for negatively oriented scores), or "less" (to assess whether +#' forecaster A shows significantly better skill than forecaster B with a +#' one-sided test for positively oriented scores). The default value is +#' "two.sided.approx". +#'@param alpha A numeric of the significance level to be used in the statistical +#' significance test (output "sign"). The default value is 0.05. +#'@param pval A logical value indicating whether to return the p-value of the +#' significance test. The default value is TRUE. +#'@param sign A logical value indicating whether to return the statistical +#' significance of the test based on 'alpha'. The default value is FALSE. #'@param ncores An integer indicating the number of cores to use for parallel #' computation. The default value is NULL. #' -#'@return A list of 2: +#'@return A list with: #'\item{$score}{ #' A numerical array with the same dimensions as the input arrays except #' 'time_dim'. The number of times that forecaster A has been better than #' forecaster B minus the number of times that forecaster B has been better -#' than forecaster A (for skill positively oriented). If $score is positive -#' forecaster A is better than forecaster B, and if $score is negative -#' forecaster B is better than forecaster B. +#' than forecaster A (for skill negatively oriented, i.e., the lower the +#' better). If $score is positive, forecaster A has been better more times +#' than forecaster B. If $score is negative, forecaster B has been better more +#' times than forecaster A. #'} -#'\item{$signif}{ -#' A logical array with the same dimensions as the input arrays except -#' 'time_dim'. Whether the difference is significant or not at the 5% -#' significance level. +#'\item{$sign}{ +#' A logical array of the statistical significance with the same dimensions +#' as the input arrays except "time_dim". Returned only if "sign" is TRUE. #'} +#'\item{$p.val}{ +#' A numeric array of the p-values with the same dimensions as the input arrays +#' except "time_dim". Returned only if "pval" is TRUE. +#'} +#' +#'@details +#' Null and alternative hypothesis for "two-sided" test (regardless of the +#' orientation of the scores):\cr +#' H0: forecaster A and forecaster B are not different in terms of skill\cr +#' H1: forecaster A and forecaster B are different in terms of skill +#' +#' Null and alternative hypothesis for one-sided "greater" (for negatively +#' oriented scores, i.e., the lower the better) and "less" (for positively +#' oriented scores, i.e., the higher the better) tests:\cr +#' H0: forecaster A is not better than forecaster B\cr +#' H1: forecaster A is better than forecaster B +#' +#' Examples of negatively oriented scores are the RPS, RMSE and the Error, while +#' the ROC score is a positively oriented score. +#' +#' DelSole and Tippett (2016) approximation for two-sided test at 95% confidence +#' level: significant if the difference between the number of times that +#' forecaster A has been better than forecaster B and forecaster B has been +#' better than forecaster A is above 2sqrt(N) or below -2sqrt(N). +#' +#'@references +#'DelSole and Tippett (2016): https://doi.org/10.1175/MWR-D-15-0218.1 #' #'@examples -#' fcst_A <- array(c(11:50), dim = c(sdate = 10, lat = 2, lon = 2)) -#' fcst_B <- array(c(21:60), dim = c(sdate = 10, lat = 2, lon = 2)) -#' reference <- array(1:40, dim = c(sdate = 10, lat = 2, lon = 2)) -#' skill_A <- abs(fcst_A - reference) -#' skill_B <- abs(fcst_B - reference) -#' RandomWalkTest(skill_A = skill_A, skill_B = skill_B, time_dim = 'sdate', ncores = 1) +#' fcst_A <- array(data = 11:50, dim = c(sdate = 10, lat = 2, lon = 2)) +#' fcst_B <- array(data = 21:60, dim = c(sdate = 10, lat = 2, lon = 2)) +#' reference <- array(data = 1:40, dim = c(sdate = 10, lat = 2, lon = 2)) +#' scores_A <- abs(fcst_A - reference) +#' scores_B <- abs(fcst_B - reference) +#' res1 <- RandomWalkTest(skill_A = scores_A, skill_B = scores_B, pval = FALSE, sign = TRUE) +#' res2 <- RandomWalkTest(skill_A = scores_A, skill_B = scores_B, test.type = 'greater') #' #'@import multiApply +#'@importFrom ClimProjDiags Subset #'@export -RandomWalkTest <- function(skill_A, skill_B, time_dim = 'sdate', ncores = NULL){ +RandomWalkTest <- function(skill_A, skill_B, time_dim = 'sdate', N.eff = NA, + test.type = 'two.sided.approx', alpha = 0.05, pval = TRUE, + sign = FALSE, ncores = NULL) { - ## Check inputs - if (is.null(skill_A) | is.null(skill_B)){ + # Check inputs + ## skill_A and skill_B + if (is.null(skill_A) | is.null(skill_B)) { stop("Parameters 'skill_A' and 'skill_B' cannot be NULL.") } - if(!is.numeric(skill_A) | !is.numeric(skill_B)){ + if(!is.numeric(skill_A) | !is.numeric(skill_B)) { stop("Parameters 'skill_A' and 'skill_B' must be a numerical array.") } - if (!identical(dim(skill_A),dim(skill_B))){ + if (!identical(dim(skill_A), dim(skill_B))) { stop("Parameters 'skill_A' and 'skill_B' must have the same dimensions.") } - if(!is.character(time_dim)){ + ## time_dim + if (!is.character(time_dim) | length(time_dim) != 1) { stop("Parameter 'time_dim' must be a character string.") } - if(!time_dim %in% names(dim(skill_A)) | !time_dim %in% names(dim(skill_B))){ + if (!time_dim %in% names(dim(skill_A)) | !time_dim %in% names(dim(skill_B))) { stop("Parameter 'time_dim' is not found in 'skill_A' or 'skill_B' dimensions.") } - if (!is.null(ncores)){ - if (!is.numeric(ncores) | ncores %% 1 != 0 | ncores <= 0 | length(ncores) > 1){ + ## N.eff + if (is.array(N.eff)) { + if (!is.numeric(N.eff)) stop("Parameter 'N.eff' must be a numeric array or NA.") + if (!identical(dim(N.eff), dim(skill_A)[-which(names(dim(skill_A)) == time_dim)])) { + stop("If parameter 'N.eff' is provided with an array, it must ", + "have the same dimensions as 'skill_A' except 'time_dim'.") + } + } else if (!identical(N.eff, NA)) { + stop("Parameter 'N.eff' must be NA or an array with ", + "the same dimensions as 'skill_A' except 'time_dim'.") + } + ## alpha + if (any(!is.numeric(alpha) | alpha <= 0 | alpha >= 1 | length(alpha) > 1)) { + stop("Parameter 'alpha' must be a number between 0 and 1.") + } + ## test.type + if (!test.type %in% c('two.sided.approx','two.sided','greater','less')) { + stop("Parameter 'test.type' must be 'two.sided.approx', 'two.sided', 'greater', or 'less'.") + } + if (test.type == 'two.sided.approx') { + if (alpha != 0.05) { + .warning("DelSole and Tippett (2016) aproximation is valid for alpha ", + "= 0.05 only. Returning the significance at the 0.05 significance level.") + } + if (pval) { + .warning("p-value cannot be returned with the DelSole and Tippett (2016) ", + "aproximation. Returning the significance at the 0.05 significance level.") + } + sign <- TRUE + } + ## ncores + if (!is.null(ncores)) { + if (!is.numeric(ncores) | ncores %% 1 != 0 | ncores <= 0 | length(ncores) > 1) { stop("Parameter 'ncores' must be a positive integer.") } } ## Compute the Random Walk Test - res <- multiApply::Apply(data = list(skill_A, skill_B), - target_dims = time_dim, - fun = .RandomWalkTest, - ncores = ncores) + if (is.array(N.eff)) { + res <- Apply(data = list(skill_A = skill_A, + skill_B = skill_B, + N.eff = N.eff), + target_dims = list(skill_A = time_dim, + skill_B = time_dim, + N.eff = NULL), + fun = .RandomWalkTest, + test.type = test.type, + alpha = alpha, pval = pval, sign = sign, + ncores = ncores) + } else { + res <- Apply(data = list(skill_A = skill_A, + skill_B = skill_B), + target_dims = list(skill_A = time_dim, + skill_B = time_dim), + fun = .RandomWalkTest, + N.eff = N.eff, + test.type = test.type, + alpha = alpha, pval = pval, sign = sign, + ncores = ncores) + } + return(res) } -.RandomWalkTest <- function(skill_A, skill_B){ +.RandomWalkTest <- function(skill_A, skill_B, N.eff = NA, test.type = 'two.sided.approx', + alpha = 0.05, pval = TRUE, sign = FALSE) { + + if (is.na(N.eff)) { + N.eff <- length(skill_A) + } + + A_better <- sum(skill_B > skill_A) + B_better <- sum(skill_B < skill_A) + + output <- NULL + output$score <- A_better - B_better + + if (test.type == 'two.sided.approx') { + output$sign <- ifelse(test = abs(output$score) > (2 * sqrt(N.eff)), yes = TRUE, no = FALSE) + + } else { + + if (!is.na(output$score)) { + p.val <- binom.test(x = A_better, n = floor(N.eff), p = 0.5, conf.level = 1 - alpha, + alternative = test.type)$p.value + + } else { + p.val <- NA + } + + if (pval) { + output$p.val <- p.val + } + if (sign) { + output$sign <- ifelse(!is.na(p.val) & p.val <= alpha, TRUE, FALSE) + } + + } - score <- cumsum(skill_A > skill_B) - cumsum(skill_A < skill_B) - - ## TRUE if significant (if last value is above or below 2*sqrt(N)) - signif<- ifelse(test = (score[length(skill_A)] < (-2)*sqrt(length(skill_A))) | (score[length(skill_A)] > 2*sqrt(length(skill_A))), - yes = TRUE, no = FALSE) - - return(list("score"=score[length(skill_A)],"signif"=signif)) + return(output) } diff --git a/man/RandomWalkTest.Rd b/man/RandomWalkTest.Rd index bd1460a74fc8c9cbe69f810ec6ef6c23497dcbd6..cd02b4fc5791640527858bf2a7a14062f547da27 100644 --- a/man/RandomWalkTest.Rd +++ b/man/RandomWalkTest.Rd @@ -2,50 +2,115 @@ % Please edit documentation in R/RandomWalkTest.R \name{RandomWalkTest} \alias{RandomWalkTest} -\title{Random walk test for skill differences} +\title{Random Walk test for skill differences} \usage{ -RandomWalkTest(skill_A, skill_B, time_dim = "sdate", ncores = NULL) +RandomWalkTest( + skill_A, + skill_B, + time_dim = "sdate", + N.eff = NA, + test.type = "two.sided.approx", + alpha = 0.05, + pval = TRUE, + sign = FALSE, + ncores = NULL +) } \arguments{ -\item{skill_A}{A numerical array of the time series of the skill with the -forecaster A's.} +\item{skill_A}{A numerical array of the time series of the scores obtained +with the forecaster A.} -\item{skill_B}{A numerical array of the time series of the skill with the -forecaster B's. The dimensions should be identical as parameter 'skill_A'.} +\item{skill_B}{A numerical array of the time series of the scores obtained +with the forecaster B. The dimensions should be identical as parameter +'skill_A'.} \item{time_dim}{A character string indicating the name of the dimension along which the tests are computed. The default value is 'sdate'.} +\item{N.eff}{Effective sample size to be used in the statistical significance +test. It can be NA (to use the length of the "time_dim" dimension) or an +array with the same dimensions as "skill_A" except "time_dim" (for a +particular N.eff to be used for each case). The default value is NA.} + +\item{test.type}{A character string indicating the type of significance test. +It can be "two.sided.approx" (to assess whether forecaster A and forecaster +B are significantly different in terms of skill with a two-sided test using +the approximation of DelSole and Tippett, 2016), "two.sided" (to assess +whether forecaster A and forecaster B are significantly different in terms +of skill with an exact two-sided test), "greater" (to assess whether +forecaster A shows significantly better skill than forecaster B with a +one-sided test for negatively oriented scores), or "less" (to assess whether +forecaster A shows significantly better skill than forecaster B with a +one-sided test for positively oriented scores). The default value is +"two.sided.approx".} + +\item{alpha}{A numeric of the significance level to be used in the statistical +significance test (output "sign"). The default value is 0.05.} + +\item{pval}{A logical value indicating whether to return the p-value of the +significance test. The default value is TRUE.} + +\item{sign}{A logical value indicating whether to return the statistical +significance of the test based on 'alpha'. The default value is FALSE.} + \item{ncores}{An integer indicating the number of cores to use for parallel computation. The default value is NULL.} } \value{ -A list of 2: +A list with: \item{$score}{ A numerical array with the same dimensions as the input arrays except 'time_dim'. The number of times that forecaster A has been better than forecaster B minus the number of times that forecaster B has been better - than forecaster A (for skill positively oriented). If $score is positive - forecaster A is better than forecaster B, and if $score is negative - forecaster B is better than forecaster B. + than forecaster A (for skill negatively oriented, i.e., the lower the + better). If $score is positive, forecaster A has been better more times + than forecaster B. If $score is negative, forecaster B has been better more + times than forecaster A. +} +\item{$sign}{ + A logical array of the statistical significance with the same dimensions + as the input arrays except "time_dim". Returned only if "sign" is TRUE. } -\item{$signif}{ - A logical array with the same dimensions as the input arrays except - 'time_dim'. Whether the difference is significant or not at the 5% - significance level. +\item{$p.val}{ + A numeric array of the p-values with the same dimensions as the input arrays + except "time_dim". Returned only if "pval" is TRUE. } } \description{ Forecast comparison of the skill obtained with 2 forecasts (with respect to a -common reference) based on Random Walks, with significance estimate at the 95% -confidence level, as in DelSole and Tippett (2016). +common observational reference) based on Random Walks (DelSole and Tippett, +2016). +} +\details{ +Null and alternative hypothesis for "two-sided" test (regardless of the +orientation of the scores):\cr +H0: forecaster A and forecaster B are not different in terms of skill\cr +H1: forecaster A and forecaster B are different in terms of skill + +Null and alternative hypothesis for one-sided "greater" (for negatively +oriented scores, i.e., the lower the better) and "less" (for positively +oriented scores, i.e., the higher the better) tests:\cr +H0: forecaster A is not better than forecaster B\cr +H1: forecaster A is better than forecaster B + +Examples of negatively oriented scores are the RPS, RMSE and the Error, while +the ROC score is a positively oriented score. + +DelSole and Tippett (2016) approximation for two-sided test at 95% confidence +level: significant if the difference between the number of times that +forecaster A has been better than forecaster B and forecaster B has been +better than forecaster A is above 2sqrt(N) or below -2sqrt(N). } \examples{ -fcst_A <- array(c(11:50), dim = c(sdate = 10, lat = 2, lon = 2)) -fcst_B <- array(c(21:60), dim = c(sdate = 10, lat = 2, lon = 2)) -reference <- array(1:40, dim = c(sdate = 10, lat = 2, lon = 2)) -skill_A <- abs(fcst_A - reference) -skill_B <- abs(fcst_B - reference) -RandomWalkTest(skill_A = skill_A, skill_B = skill_B, time_dim = 'sdate', ncores = 1) +fcst_A <- array(data = 11:50, dim = c(sdate = 10, lat = 2, lon = 2)) +fcst_B <- array(data = 21:60, dim = c(sdate = 10, lat = 2, lon = 2)) +reference <- array(data = 1:40, dim = c(sdate = 10, lat = 2, lon = 2)) +scores_A <- abs(fcst_A - reference) +scores_B <- abs(fcst_B - reference) +res1 <- RandomWalkTest(skill_A = scores_A, skill_B = scores_B, pval = FALSE, sign = TRUE) +res2 <- RandomWalkTest(skill_A = scores_A, skill_B = scores_B, test.type = 'greater') } +\references{ +DelSole and Tippett (2016): https://doi.org/10.1175/MWR-D-15-0218.1 +} diff --git a/tests/testthat/test-RandomWalkTest.R b/tests/testthat/test-RandomWalkTest.R index d50b9ce9118910e7f7558dae1687b2f6467c0439..1af1d19db750967656c2daff7925c24b2b8b4303 100644 --- a/tests/testthat/test-RandomWalkTest.R +++ b/tests/testthat/test-RandomWalkTest.R @@ -1,11 +1,17 @@ context("s2dv::RandomWalkTest tests") ############################################## + #dat1 set.seed(1) dat1_A <- array(rnorm(64), dim = c(sdate = 4, ftime = 4, lat = 2, lon = 2)) set.seed(2) dat1_B <- array(rnorm(64), dim = c(sdate = 4, ftime = 4, lat = 2, lon = 2)) - + #dat2 + set.seed(1) + dat2_A <- array(rnorm(8), dim = c(sdate = 4, ftime = 2)) + set.seed(2) + dat2_B <- array(rnorm(8), dim = c(sdate = 4, ftime = 2)) + N.eff2 <- array(3:4, dim = c(ftime = 2)) ############################################## test_that("1. Input checks", { @@ -31,7 +37,27 @@ test_that("1. Input checks", { "Parameter 'time_dim' is not found in 'skill_A' or 'skill_B' dimension." ) expect_error( - RandomWalkTest(dat1_A, dat1_B, ncores = T), + RandomWalkTest(dat1_A, dat1_B, N.eff = as.array(T)), + "Parameter 'N.eff' must be a numeric array or NA." + ) + expect_error( + RandomWalkTest(dat1_A, dat1_B, N.eff = array(1:4, dim = c(ftime = 4))), + "If parameter 'N.eff' is provided with an array, it must have the same dimensions as 'skill_A' except 'time_dim'." + ) + expect_error( + RandomWalkTest(dat1_A, dat1_B, N.eff = 1), + "Parameter 'N.eff' must be NA or an array with the same dimensions as 'skill_A' except 'time_dim'." + ) + expect_error( + RandomWalkTest(dat1_A, dat1_B, alpha = 1), + "Parameter 'alpha' must be a number between 0 and 1." + ) + expect_error( + RandomWalkTest(dat1_A, dat1_B, test.type = 1), + "Parameter 'test.type' must be 'two.sided.approx', 'two.sided', 'greater', or 'less'." + ) + expect_error( + RandomWalkTest(dat1_A, dat1_B, ncores = T, sign = T, pval = F), "Parameter 'ncores' must be a positive integer." ) @@ -39,7 +65,7 @@ test_that("1. Input checks", { ############################################## test_that("2. Output checks: dat1", { - res <- RandomWalkTest(dat1_A, dat1_B) + res <- RandomWalkTest(dat1_A, dat1_B, sign = T, pval = F) expect_equal( length(res), @@ -47,14 +73,14 @@ test_that("2. Output checks: dat1", { ) expect_equal( names(res), - c("score", "signif") + c("score", "sign") ) expect_equal( dim(res$score), c(ftime = 4, lat = 2, lon = 2) ) expect_equal( - dim(res$signif), + dim(res$sign), c(ftime = 4, lat = 2, lon = 2) ) expect_equal( @@ -62,7 +88,7 @@ test_that("2. Output checks: dat1", { TRUE ) expect_equal( - is.logical(res$signif), + is.logical(res$sign), TRUE ) expect_equal( @@ -71,11 +97,107 @@ test_that("2. Output checks: dat1", { ) expect_equal( res$score[, 1, 1], - c(0, 0, -2, -2) + c(0, 0, 2, 2) ) expect_equal( res$score[, 1, 2], - c(0, 4, 2, 0) + c(0, -4, -2, 0) ) }) + +############################################## +test_that("3. Output checks: dat2", { + + res1 <- RandomWalkTest(dat2_A, dat2_B, sign = T, pval = T, test.type = "two.sided", alpha = 0.1) + + expect_equal( + names(res1), + c("score", "p.val", "sign") + ) + expect_equal( + dim(res1$score), + c(ftime = 2) + ) + expect_equal( + dim(res1$p.val), + c(ftime = 2) + ) + expect_equal( + dim(res1$sign), + c(ftime = 2) + ) + expect_equal( + as.vector(res1$score), + c(0, 0) + ) + expect_equal( + as.vector(res1$p), + c(1, 1) + ) + expect_equal( + as.vector(res1$sign), + c(F, F) + ) + +#------------------------------ + res2 <- RandomWalkTest(dat2_A + 1, dat2_B + 2, sign = T, pval = T, test.type = "greater", alpha = 0.1) + + expect_equal( + as.vector(res2$score), + c(2, 4) + ) + expect_equal( + as.vector(res2$p), + c(0.3125, 0.0625) + ) + expect_equal( + as.vector(res2$sign), + c(F, T) + ) + +#------------------------------ + res3 <- RandomWalkTest(dat2_A, dat2_B - 2, sign = T, pval = T, test.type = "less", alpha = 0.1) + expect_equal( + as.vector(res3$score), + c(-2, -4) + ) + expect_equal( + as.vector(res3$p), + c(0.3125, 0.0625) + ) + expect_equal( + as.vector(res3$sign), + c(F, T) + ) + +#------------------------------- + res4 <- RandomWalkTest(dat2_A, dat2_B - 2, sign = T, test.type = "less", alpha = 0.1, N.eff = N.eff2) + expect_equal( + dim(res4$score), + c(ftime = 2) + ) + expect_equal( + dim(res4$sign), + c(ftime = 2) + ) + expect_equal( + dim(res4$p.val), + c(ftime = 2) + ) + expect_equal( + as.vector(res4$score), + c(-2, -4) + ) + expect_equal( + as.vector(res4$p), + c(0.5000, 0.0625) + ) + expect_equal( + as.vector(res4$sign), + c(F, T) + ) + +}) + +