diff --git a/NEWS.md b/NEWS.md index 9f20054b9199276760eacdf58106a2ce0c520e12..2dd1570b127f4cf597633b8adbf810e47e82d485 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,6 @@ # s2dv 0.0.2 (Release date: 2020-) +- Change Regression() parameter 'time_dim' to 'reg_dim', and enable the inputs to be vectors. +- Change Trend() parameter 'time_dim' default value from 'sdate' to 'ftime'. - Change the default of Season() parameter 'time_dim' from 'sdate' to 'ftime'. - Add p-value by ANOVA in Trend(). - Change MeanDims() na.rm default to FALSE to be in line with mean() diff --git a/R/Clim.R b/R/Clim.R index 95701191a5741c36104a4e98491520ba0b24ddf2..d879fc4f4fdba572efeb4308ded28ea1ce41b799 100644 --- a/R/Clim.R +++ b/R/Clim.R @@ -335,10 +335,10 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), tmp <- Subset(obs, ftime_dim, 1, drop = 'selected') ini_obs <- InsertDim(tmp, pos_ftime, dim_ftime) #only first ftime #ini_: [sdate, dat_dim, ftime] - tmp_exp <- Regression(datay = exp, datax = ini_exp, time_dim = time_dim, + tmp_exp <- Regression(datay = exp, datax = ini_exp, reg_dim = time_dim, na.action = na.omit, pval = FALSE, conf = FALSE)$regression - tmp_obs <- Regression(datay = obs, datax = ini_obs, time_dim = time_dim, + tmp_obs <- Regression(datay = obs, datax = ini_obs, reg_dim = time_dim, na.action = na.omit, pval = FALSE, conf = FALSE)$regression #tmp_: [stats = 2, dat_dim, ftime] diff --git a/R/Regression.R b/R/Regression.R index 1e0c79b24c1e34f7d2875bcae03daa170c73d272..8b2bd9c3c73d4b90122f0f6623957882ddd1c410 100644 --- a/R/Regression.R +++ b/R/Regression.R @@ -1,7 +1,7 @@ #'Compute the regression of an array on another along one dimension. #' #'Compute the regression of the array 'datay' on the array 'datax' along the -#''time_dim' dimension by least square fitting (default) or self-defined model. +#''reg_dim' dimension by least square fitting (default) or self-defined model. #'The function provides the slope of the regression, the intercept, and the #'associated p-value and confidence interval. The filtered datay from the #'regression onto datax is also provided.\cr @@ -12,8 +12,8 @@ #' which the regression is computed. #'@param datax An numeric array as predictor. The dimension should be identical #' as parameter 'datay'. -#'@param time_dim A character string indicating the dimension along which to -#' compute the regression. +#'@param reg_dim A character string indicating the dimension along which to +#' compute the regression. The default value is 'sdate'. #'@param formula An object of class "formula" (see function \code{link[stats]{lm}}). #'@param pval A logical value indicating whether to retrieve the p-value #' or not. The default value is TRUE. @@ -35,14 +35,14 @@ #'A list containing: #'\item{$regression}{ #' A numeric array with same dimensions as parameter 'datay' and 'datax' except -#' the 'time_dim' dimension, which is replaced by a 'stats' dimension containing +#' the 'reg_dim' dimension, which is replaced by a 'stats' dimension containing #' the regression coefficients from the lowest order (i.e., intercept) to #' the highest degree. The length of the 'stats' dimension should be #' \code{polydeg + 1}. #'} #'\item{$conf.lower}{ #' A numeric array with same dimensions as parameter 'daty' and 'datax' except -#' the 'time_dim' dimension, which is replaced by a 'stats' dimension containing +#' the 'reg_dim' dimension, which is replaced by a 'stats' dimension containing #' the lower value of the \code{siglev}\% confidence interval for all #' the regression coefficients with the same order as $regression. The length #' of 'stats' dimension should be \code{polydeg + 1}. Only present if @@ -50,7 +50,7 @@ #'} #'\item{$conf.upper}{ #' A numeric array with same dimensions as parameter 'daty' and 'datax' except -#' the 'time_dim' dimension, which is replaced by a 'stats' dimension containing +#' the 'reg_dim' dimension, which is replaced by a 'stats' dimension containing #' the upper value of the \code{siglev}\% confidence interval for all #' the regression coefficients with the same order as $regression. The length #' of 'stats' dimension should be \code{polydeg + 1}. Only present if @@ -58,11 +58,11 @@ #'} #'\item{$p.val}{ #' A numeric array with same dimensions as parameter 'daty' and 'datax' except -#' the 'time_dim' dimension, The array contains the p-value. +#' the 'reg_dim' dimension, The array contains the p-value. #'} #'\item{$filtered}{ #' A numeric array with the same dimension as paramter 'datay' and 'datax', -#' the filtered datay from the regression onto datax along the 'time_dim' +#' the filtered datay from the regression onto datax along the 'reg_dim' #' dimension. #'} #' @@ -79,7 +79,7 @@ #'@importFrom stats lm na.omit confint #'@import multiApply #'@export -Regression <- function(datay, datax, time_dim = 'sdate', formula = y ~ x, +Regression <- function(datay, datax, reg_dim = 'sdate', formula = y ~ x, pval = TRUE, conf = TRUE, conf.lev = 0.95, na.action = na.omit, ncores = NULL) { @@ -91,8 +91,16 @@ Regression <- function(datay, datax, time_dim = 'sdate', formula = y ~ x, if (!is.numeric(datay) | !is.numeric(datax)) { stop("Parameter 'datay' and 'datax' must be a numeric array.") } - if (is.null(dim(datay)) | is.null(dim(datax))) { - stop("Parameter 'datay' and 'datax' must be at least one dimension 'time_dim'.") +# if (is.null(dim(datay)) | is.null(dim(datax))) { +# stop("Parameter 'datay' and 'datax' must be at least one dimension 'reg_dim'.") +# } + if (is.null(dim(datay))) { #is vector + dim(datay) <- c(length(datay)) + names(dim(datay)) <- reg_dim + } + if (is.null(dim(datax))) { #is vector + dim(datax) <- c(length(datax)) + names(dim(datax)) <- reg_dim } if(any(is.null(names(dim(datay))))| any(nchar(names(dim(datay))) == 0) | any(is.null(names(dim(datax))))| any(nchar(names(dim(datax))) == 0)) { @@ -107,12 +115,12 @@ Regression <- function(datay, datax, time_dim = 'sdate', formula = y ~ x, if(!all(dim(datay)[name_datay] == dim(datax)[name_datax])) { stop("Parameter 'datay' and 'datax' must have same length of all dimensions.") } - ## time_dim - if (!is.character(time_dim) | length(time_dim) > 1) { - stop("Parameter 'time_dim' must be a character string.") + ## reg_dim + if (!is.character(reg_dim) | length(reg_dim) > 1) { + stop("Parameter 'reg_dim' must be a character string.") } - if (!time_dim %in% names(dim(datay)) | !time_dim %in% names(dim(datax))) { - stop("Parameter 'time_dim' is not found in 'datay' or 'datax' dimension.") + if (!reg_dim %in% names(dim(datay)) | !reg_dim %in% names(dim(datax))) { + stop("Parameter 'reg_dim' is not found in 'datay' or 'datax' dimension.") } ## formula if (class(formula) != 'formula') { @@ -163,19 +171,19 @@ Regression <- function(datay, datax, time_dim = 'sdate', formula = y ~ x, # Calculate Regression if (conf & pval) { output_dims <- list(regression = 'stats', conf.lower = 'stats', - conf.upper = 'stats', p.val = NULL, filtered = time_dim) + conf.upper = 'stats', p.val = NULL, filtered = reg_dim) } else if (conf & !pval) { output_dims <- list(regression = 'stats', conf.lower = 'stats', - conf.upper = 'stats', filtered = time_dim) + conf.upper = 'stats', filtered = reg_dim) } else if (!conf & pval) { output_dims <- list(regression = 'stats', - p.val = NULL, filtered = time_dim) + p.val = NULL, filtered = reg_dim) } else if (!conf & !pval) { - output_dims <- list(regression = 'stats', filtered = time_dim) + output_dims <- list(regression = 'stats', filtered = reg_dim) } res <- Apply(list(datay, datax), - target_dims = time_dim, + target_dims = reg_dim, output_dims = output_dims, fun = .Regression, formula = formula, pval = pval, conf = conf, diff --git a/R/Trend.R b/R/Trend.R index 0f20efc0cb07ffd5dec036b77835b19c2c81a7d3..2914fb2e980468d1a0b00a2cd126bacf40447f3b 100644 --- a/R/Trend.R +++ b/R/Trend.R @@ -10,7 +10,7 @@ #'@param data An numeric array including the dimension along which the trend #' is computed. #'@param time_dim A character string indicating the dimension along which to -#' compute the trend. The default value is 'sdate'. +#' compute the trend. The default value is 'ftime'. #'@param interval A positive numeric indicating the unit length between two #' points along 'time_dim' dimension. The default value is 1. #'@param polydeg A positive integer indicating the degree of polynomial @@ -66,7 +66,7 @@ #'@rdname Trend #'@import multiApply #'@export -Trend <- function(data, time_dim = 'sdate', interval = 1, polydeg = 1, +Trend <- function(data, time_dim = 'ftime', interval = 1, polydeg = 1, conf = TRUE, conf.lev = 0.95, pval = TRUE, ncores = NULL) { # Check inputs @@ -149,7 +149,7 @@ Trend <- function(data, time_dim = 'sdate', interval = 1, polydeg = 1, return(output) } -.Trend <- function(x, time_dim = 'sdate', interval = 1, polydeg = 1, +.Trend <- function(x, time_dim = 'ftime', interval = 1, polydeg = 1, conf = TRUE, conf.lev = 0.95, pval = TRUE) { mon <- seq(x) * interval diff --git a/man/Regression.Rd b/man/Regression.Rd index cbb28759448945db58750f6d3044745e14cb8cde..4faafc1d83c57ab08f6d6fbf523e18593d89a131 100644 --- a/man/Regression.Rd +++ b/man/Regression.Rd @@ -4,7 +4,7 @@ \alias{Regression} \title{Compute the regression of an array on another along one dimension.} \usage{ -Regression(datay, datax, time_dim = "sdate", formula = y ~ x, pval = TRUE, +Regression(datay, datax, reg_dim = "sdate", formula = y ~ x, pval = TRUE, conf = TRUE, conf.lev = 0.95, na.action = na.omit, ncores = NULL) } \arguments{ @@ -14,8 +14,8 @@ which the regression is computed.} \item{datax}{An numeric array as predictor. The dimension should be identical as parameter 'datay'.} -\item{time_dim}{A character string indicating the dimension along which to -compute the regression.} +\item{reg_dim}{A character string indicating the dimension along which to +compute the regression. The default value is 'sdate'.} \item{formula}{An object of class "formula" (see function \code{link[stats]{lm}}).} @@ -41,14 +41,14 @@ computation. Default value is NULL.} A list containing: \item{$regression}{ A numeric array with same dimensions as parameter 'datay' and 'datax' except - the 'time_dim' dimension, which is replaced by a 'stats' dimension containing + the 'reg_dim' dimension, which is replaced by a 'stats' dimension containing the regression coefficients from the lowest order (i.e., intercept) to the highest degree. The length of the 'stats' dimension should be \code{polydeg + 1}. } \item{$conf.lower}{ A numeric array with same dimensions as parameter 'daty' and 'datax' except - the 'time_dim' dimension, which is replaced by a 'stats' dimension containing + the 'reg_dim' dimension, which is replaced by a 'stats' dimension containing the lower value of the \code{siglev}\% confidence interval for all the regression coefficients with the same order as $regression. The length of 'stats' dimension should be \code{polydeg + 1}. Only present if @@ -56,7 +56,7 @@ A list containing: } \item{$conf.upper}{ A numeric array with same dimensions as parameter 'daty' and 'datax' except - the 'time_dim' dimension, which is replaced by a 'stats' dimension containing + the 'reg_dim' dimension, which is replaced by a 'stats' dimension containing the upper value of the \code{siglev}\% confidence interval for all the regression coefficients with the same order as $regression. The length of 'stats' dimension should be \code{polydeg + 1}. Only present if @@ -64,17 +64,17 @@ A list containing: } \item{$p.val}{ A numeric array with same dimensions as parameter 'daty' and 'datax' except - the 'time_dim' dimension, The array contains the p-value. + the 'reg_dim' dimension, The array contains the p-value. } \item{$filtered}{ A numeric array with the same dimension as paramter 'datay' and 'datax', - the filtered datay from the regression onto datax along the 'time_dim' + the filtered datay from the regression onto datax along the 'reg_dim' dimension. } } \description{ Compute the regression of the array 'datay' on the array 'datax' along the -'time_dim' dimension by least square fitting (default) or self-defined model. +'reg_dim' dimension by least square fitting (default) or self-defined model. The function provides the slope of the regression, the intercept, and the associated p-value and confidence interval. The filtered datay from the regression onto datax is also provided.\cr diff --git a/man/Trend.Rd b/man/Trend.Rd index 17076c6e690e8063bb85b0bbf17550b24c9342f4..a641041cd451628b948ccb0545970322e0cf1f81 100644 --- a/man/Trend.Rd +++ b/man/Trend.Rd @@ -4,7 +4,7 @@ \alias{Trend} \title{Compute the trend} \usage{ -Trend(data, time_dim = "sdate", interval = 1, polydeg = 1, conf = TRUE, +Trend(data, time_dim = "ftime", interval = 1, polydeg = 1, conf = TRUE, conf.lev = 0.95, pval = TRUE, ncores = NULL) } \arguments{ @@ -12,7 +12,7 @@ Trend(data, time_dim = "sdate", interval = 1, polydeg = 1, conf = TRUE, is computed.} \item{time_dim}{A character string indicating the dimension along which to -compute the trend. The default value is 'sdate'.} +compute the trend. The default value is 'ftime'.} \item{interval}{A positive numeric indicating the unit length between two points along 'time_dim' dimension. The default value is 1.} diff --git a/tests/testthat/test-Regression.R b/tests/testthat/test-Regression.R index 69c4f9edd5eafa7561c565f9df80f3ce50079dc5..85e57822d74f1c861dea5c0952268501ebe8e8f9 100644 --- a/tests/testthat/test-Regression.R +++ b/tests/testthat/test-Regression.R @@ -39,10 +39,6 @@ test_that("1. Input checks", { "Parameter 'datay' and 'datax' must be a numeric array." ) expect_error( - Regression(c(1:10), c(2:4)), - "Parameter 'datay' and 'datax' must be at least one dimension 'time_dim'." - ) - expect_error( Regression(array(1:10, dim = c(2, 5)), array(1:4, dim = c(2, 2))), "Parameter 'datay' and 'datax' must have dimension names." ) @@ -55,12 +51,12 @@ test_that("1. Input checks", { "Parameter 'datay' and 'datax' must have same length of all dimensions." ) expect_error( - Regression(datay1, datax1, time_dim = 1), - "Parameter 'time_dim' must be a character string." + Regression(datay1, datax1, reg_dim = 1), + "Parameter 'reg_dim' must be a character string." ) expect_error( - Regression(datay1, datax1, time_dim = 'asd'), - "Parameter 'time_dim' is not found in 'datay' or 'datax' dimension." + Regression(datay1, datax1, reg_dim = 'asd'), + "Parameter 'reg_dim' is not found in 'datay' or 'datax' dimension." ) expect_error( Regression(datay1, datax1, na.action = TRUE), @@ -180,15 +176,15 @@ test_that("3. Output checks: dat2", { test_that("4. Output checks: dat3", { expect_equal( - dim(Regression(datay3, datax3, time_dim = 'date')$regression), + dim(Regression(datay3, datax3, reg_dim = 'date')$regression), c(stats = 2, ftime = 2, lon = 2, lat = 4) ) expect_equal( - dim(Regression(datay3, datax3, time_dim = 'date')$conf.lower), + dim(Regression(datay3, datax3, reg_dim = 'date')$conf.lower), c(stats = 2, ftime = 2, lon = 2, lat = 4) ) expect_equal( - dim(Regression(datay3, datax3, time_dim = 'date')$p.val), + dim(Regression(datay3, datax3, reg_dim = 'date')$p.val), c(ftime = 2, lon = 2, lat = 4) ) diff --git a/tests/testthat/test-Trend.R b/tests/testthat/test-Trend.R index 89052a0b119d09c02682f8a0b822caa3f3e722f8..79049b526b5c0b77c86239b9d64da96503aa2209 100644 --- a/tests/testthat/test-Trend.R +++ b/tests/testthat/test-Trend.R @@ -3,7 +3,7 @@ context("s2dv::Trend tests") ############################################## # dat1 dat1 <- array(c(-5, -7, -10:10, 12, 11, 7, 16), - dim = c(dat = 1, sdate = 13, ftime = 2)) + dim = c(dat = 1, ftime = 13, sdate = 2)) # dat2 set.seed(10) @@ -12,7 +12,7 @@ context("s2dv::Trend tests") # dat3 set.seed(1) dat3 <- array(c(1:60) + rnorm(60), - dim = c(sdate = 5, lat = 2, lon = 3, lev = 2)) + dim = c(ftime = 5, lat = 2, lon = 3, lev = 2)) set.seed(1) na <- floor(runif(5, min = 1, max = 60)) dat3[na] <- NA @@ -42,7 +42,7 @@ test_that("1. Input checks", { "Parameter 'time_dim' is not found in 'data' dimension." ) expect_error( - Trend(array(c(1:25), dim = c(dat = 1, date = 5, ftime = 5))), + Trend(array(c(1:25), dim = c(dat = 1, date = 5, sdate = 5))), "Parameter 'time_dim' is not found in 'data' dimension." ) expect_error( @@ -89,19 +89,19 @@ test_that("2. Output checks: dat1", { expect_equal( Trend(dat1)$trend, array(c(-9.7692308, 0.6593407, 0.9615385, 0.7967033), - dim = c(stats = 2, dat = 1, ftime = 2)), + dim = c(stats = 2, dat = 1, sdate = 2)), tolerance = 0.0001 ) expect_equal( Trend(dat1)$conf.upper, array(c(-7.4735367, 0.9485709, 3.0167860, 1.0556402), - dim = c(stats = 2, dat = 1, ftime = 2)), + dim = c(stats = 2, dat = 1, sdate = 2)), tolerance = 0.0001 ) expect_equal( Trend(dat1)$p.val, array(c(0.0003916111, 3.065828e-05), - dim = c(stats = 1, dat = 1, ftime = 2)), + dim = c(stats = 1, dat = 1, sdate = 2)), tolerance = 0.0001 ) expect_equal( @@ -122,7 +122,7 @@ test_that("3. Output checks: dat2", { conf.upper = array(c(0.953, 1.127), dim = c(stats = 2)), p.val = array(2.277774e-06, dim = c(stats = 1)), detrended = array(c(0.257, 0.110, -1.021, -0.193, 0.757, 0.909, - -0.633, 0.267, -0.939, 0.487), dim = c(sdate = 10))), + -0.633, 0.267, -0.939, 0.487), dim = c(ftime = 10))), tolerance = 0.001 ) expect_equal( @@ -132,7 +132,7 @@ test_that("3. Output checks: dat2", { conf.upper = array(c(0.953, 0.563), dim = c(stats = 2)), p.val = array(2.277774e-06, dim = c(stats = 1)), detrended = array(c(0.257, 0.110, -1.021, -0.193, 0.757, 0.909, - -0.633, 0.267, -0.939, 0.487), dim = c(sdate = 10))), + -0.633, 0.267, -0.939, 0.487), dim = c(ftime = 10))), tolerance = 0.001 ) expect_equal(