diff --git a/R/Clim.R b/R/Clim.R index 59f8bc99f6fa4202c76c68c8d7c93a377d5797dd..d4773d5f1783e9b0ce633e910a19201a07a73e60 100644 --- a/R/Clim.R +++ b/R/Clim.R @@ -15,23 +15,26 @@ #'is the initial condition bias correction method. The two methods both do the #'per-pair correction beforehand. #' -#'@param exp A named numeric array of experimental data, with at least two -#' dimensions 'time_dim' and 'dat_dim'. -#'@param obs A named numeric array of observational data, same dimensions as -#' parameter 'exp' except along 'dat_dim'. +#'@param exp A named numeric array of experimental data with at least dimension +#' 'time_dim'. +#'@param obs A named numeric array of observational data that has the same +#' dimension as 'exp' except 'dat_dim'. #'@param time_dim A character string indicating the name of dimension along #' which the climatologies are computed. The default value is 'sdate'. #'@param dat_dim A character vector indicating the name of the dataset and #' member dimensions. If data at one startdate (i.e., 'time_dim') are not #' complete along 'dat_dim', this startdate along 'dat_dim' will be discarded. -#' The default value is "c('dataset', 'member')". -#'@param method A character string indicating the method to be used. The +#' If there is no dataset dimension, it can be NULL, however, it will be more +#' efficient to simply use mean() to do the calculation. The default value is +#' "c('dataset', 'member')". +#'@param method A character string indicating the method to be used. The #' options include 'clim' (per-pair method), 'kharin' (Kharin method), and #' 'NDV' (Fuckar method). The default value is 'clim'. #'@param ftime_dim A character string indicating the name of forecast time #' dimension. Only used when method = 'NDV'. The default value is 'ftime'. #'@param memb A logical value indicating whether to remain 'memb_dim' dimension -#' (TRUE) or do ensemble mean over 'memb_dim' (FALSE). The default value is TRUE. +#' (TRUE) or do ensemble mean over 'memb_dim' (FALSE). The default value is +#' TRUE. #'@param memb_dim A character string indicating the name of the member #' dimension. Only used when parameter 'memb' is FALSE. It must be one element #' in 'dat_dim'. The default value is 'member'. @@ -50,7 +53,7 @@ #' dimension 'memb_dim' is also removed. #'} #'\item{$clim_obs}{ -#' A numeric array with the same dimensions as parameter 'exp' +#' A numeric array with the same dimensions as parameter 'obs' #' except dimension 'time_dim' is removed. If parameter 'memb' is FALSE, #' dimension 'memb_dim' is also removed. #'} @@ -86,14 +89,10 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), stop(paste0("Parameter 'exp' and 'obs' must be at least two dimensions ", "containing time_dim and dat_dim.")) } - if(any(is.null(names(dim(exp))))| any(nchar(names(dim(exp))) == 0) | - any(is.null(names(dim(obs))))| any(nchar(names(dim(obs))) == 0)) { + if (any(is.null(names(dim(exp))))| any(nchar(names(dim(exp))) == 0) | + any(is.null(names(dim(obs))))| any(nchar(names(dim(obs))) == 0)) { stop("Parameter 'exp' and 'obs' must have dimension names.") } - if(!all(names(dim(exp)) %in% names(dim(obs))) | - !all(names(dim(obs)) %in% names(dim(exp)))) { - stop("Parameter 'exp' and 'obs' must have same dimension name") - } ## time_dim if (!is.character(time_dim) | length(time_dim) > 1) { stop("Parameter 'time_dim' must be a character string.") @@ -102,12 +101,26 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), stop("Parameter 'time_dim' is not found in 'exp' or 'obs' dimension.") } ## dat_dim - if (!is.character(dat_dim)) { - stop("Parameter 'dat_dim' must be a character vector.") - } - if (!all(dat_dim %in% names(dim(exp))) | !all(dat_dim %in% names(dim(obs)))) { - stop("Parameter 'dat_dim' is not found in 'exp' or 'obs' dimension.") - } + if (!is.null(dat_dim)) { + if (!is.character(dat_dim)) { + stop("Parameter 'dat_dim' must be a character vector.") + } + # Check if dat_dim is in exp + if (!all(dat_dim %in% names(dim(exp)))) { + stop("Parameter 'dat_dim' is not found in 'exp' dimensions.") + } + # If dat_dim is not in obs, add it in + if (any(!dat_dim %in% names(dim(obs)))) { + reset_obs_dim <- TRUE + ori_obs_dim <- dim(obs) + dim(obs) <- c(dim(obs), rep(1, length(dat_dim[which(!dat_dim %in% names(dim(obs)))]))) + names(dim(obs)) <- c(names(ori_obs_dim), dat_dim[which(!dat_dim %in% names(dim(obs)))]) + } else { + reset_obs_dim <- FALSE + } + } else { + reset_obs_dim <- FALSE + } ## method if (!(method %in% c("clim", "kharin", "NDV"))) { stop("Parameter 'method' must be one of 'clim', 'kharin' or 'NDV'.") @@ -126,13 +139,17 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), stop("Parameter 'memb' must be one logical value.") } ## memb_dim - if (!memb) { + if (!is.null(memb_dim) & !memb) { if (!is.character(memb_dim) | length(memb_dim) > 1) { stop("Parameter 'memb_dim' must be a character string.") } if (!memb_dim %in% names(dim(exp)) | !memb_dim %in% names(dim(obs))) { - stop("Parameter 'memb_dim' is not found in 'exp' or 'obs' dimension.") + stop("Parameter 'memb_dim' is not found in 'exp' dimension.") } + if (!memb_dim %in% dat_dim) + stop("Parameter 'memb_dim' must be one element in parameter 'dat_dim'.") + } else if (is.null(memb_dim) & !memb) { + memb <- TRUE } ## na.rm if (!is.logical(na.rm) | length(na.rm) > 1) { @@ -148,13 +165,15 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), ## exp and obs (2) name_exp <- sort(names(dim(exp))) name_obs <- sort(names(dim(obs))) - for (i in 1:length(dat_dim)) { - name_exp <- name_exp[-which(name_exp == dat_dim[i])] - name_obs <- name_obs[-which(name_obs == dat_dim[i])] + if (!is.null(dat_dim)) { + for (i in 1:length(dat_dim)) { + name_exp <- name_exp[-which(name_exp == dat_dim[i])] + name_obs <- name_obs[-which(name_obs == dat_dim[i])] + } } if(!all(dim(exp)[name_exp] == dim(obs)[name_obs])) { - stop(paste0("Parameter 'exp' and 'obs' must have same length of ", - "all dimension expect 'dat_dim'.")) + stop(paste0("Parameter 'exp' and 'obs' must have the same dimensions ", + "expect 'dat_dim'.")) } ############################### @@ -169,24 +188,29 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), # Calculate Clim #---------------------------------- - # Remove all sdate if not complete along dat_dim - - pos <- rep(0, length(dat_dim)) - for (i in 1:length(dat_dim)) { #[dat, sdate] - ## dat_dim: [dataset, member] - pos[i] <- which(names(dim(obs)) == dat_dim[i]) + # Per-pair: Remove all sdate if not complete along dat_dim + if (!is.null(dat_dim)) { + pos <- which(names(dim(obs)) %in% dat_dim) + + na_array <- array(0, dim = dim(exp)[-pos]) + dat_dim_comb <- plyr::alply(expand.grid(lapply(dim(exp)[dat_dim], seq, 1)), 1) + for (i_dat in 1:length(dat_dim_comb)) { + na_array <- na_array + is.na(Subset(exp, dat_dim, dat_dim_comb[[i_dat]], drop = 'selected')) + } + dat_dim_comb <- plyr::alply(expand.grid(lapply(dim(obs)[dat_dim], seq, 1)), 1) + for (i_dat in 1:length(dat_dim_comb)) { + na_array <- na_array + is.na(Subset(obs, dat_dim, dat_dim_comb[[i_dat]], drop = 'selected')) } - outrows_exp <- MeanDims(exp, pos, na.rm = FALSE) + - MeanDims(obs, pos, na.rm = FALSE) - outrows_obs <- outrows_exp + na_array_2 <- na_array for (i in 1:length(pos)) { - outrows_exp <- InsertDim(outrows_exp, pos[i], dim(exp)[pos[i]]) - outrows_obs <- InsertDim(outrows_obs, pos[i], dim(obs)[pos[i]]) + na_array <- InsertDim(na_array, pos[i], dim(exp)[pos[i]]) + na_array_2 <- InsertDim(na_array_2, pos[i], dim(obs)[pos[i]]) } - exp[which(is.na(outrows_exp))] <- NA - obs[which(is.na(outrows_obs))] <- NA + exp[which(na_array != 0)] <- NA + obs[which(na_array_2 != 0)] <- NA + } #----------------------------------- if (method == 'clim') { @@ -197,13 +221,6 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), dat_dim = dat_dim, memb_dim = memb_dim, memb = memb, na.rm = na.rm, ncores_input = ncores, ncores = ncores) - # Add member dimension name back - if (memb) { - if(is.null(names(dim(clim$clim_exp))[1])) { - names(dim(clim$clim_exp))[1] <- memb_dim - names(dim(clim$clim_obs))[1] <- memb_dim - } - } } else if (method == 'kharin') { clim <- Apply(list(exp, obs), @@ -222,6 +239,19 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), dat_dim = dat_dim, ftime_dim = ftime_dim, memb_dim = memb_dim, memb = memb, na.rm = na.rm, ncores_input = ncores, ncores = ncores) + } + + # Remove dat_dim in obs if obs doesn't have at first place + if (reset_obs_dim) { + clim_obs_dim <- ori_obs_dim[-which(names(ori_obs_dim) == time_dim)] + if (!memb & memb_dim %in% names(clim_obs_dim)) { + clim_obs_dim <- clim_obs_dim[-which(names(clim_obs_dim) == memb_dim)] + } + if (is.integer(clim_obs_dim) & length(clim_obs_dim) == 0) { + clim$clim_obs <- as.vector(clim$clim_obs) + } else { + clim$clim_obs <- array(clim$clim_obs, dim = clim_obs_dim) + } } return(clim) @@ -234,32 +264,43 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), na.rm = TRUE, ncores_input = NULL) { if (method == 'clim') { - # exp: [sdate, dat_dim_exp] - # obs: [sdate, dat_dim_obs] - - clim_exp <- apply(exp, which(names(dim(exp)) != time_dim), - mean, na.rm = na.rm) #average out time_dim - clim_obs <- apply(obs, which(names(dim(obs)) != time_dim), - mean, na.rm = na.rm) #[dat_dim] - - ## member mean - if (!memb) { - if (length(dim(clim_exp)) == 1) { #dim: [member] - clim_exp <- mean(clim_exp, na.rm = TRUE) - clim_obs <- mean(clim_obs, na.rm = TRUE) - } else { - pos <- which(names(dim(clim_exp)) == memb_dim) - pos <- c(1:length(dim(clim_exp)))[-pos] - dim_name <- names(dim(clim_exp)) - clim_exp <- apply(clim_exp, pos, mean, na.rm = TRUE) - clim_obs <- apply(clim_obs, pos, mean, na.rm = TRUE) - if (is.null(names(dim(as.array(clim_exp))))) { - clim_exp <- as.array(clim_exp) - clim_obs <- as.array(clim_obs) - names(dim(clim_exp)) <- dim_name[pos] - names(dim(clim_obs)) <- dim_name[pos] + if (!is.null(dat_dim)) { + # exp: [sdate, dat_dim_exp] + # obs: [sdate, dat_dim_obs] + + clim_exp <- apply(exp, which(names(dim(exp)) != time_dim), + mean, na.rm = na.rm) #average out time_dim + clim_obs <- apply(obs, which(names(dim(obs)) != time_dim), + mean, na.rm = na.rm) #[dat_dim] + + if (is.null(dim(clim_exp))) { + dim(clim_exp) <- length(clim_exp) + names(dim(clim_exp)) <- dat_dim + dim(clim_obs) <- length(clim_obs) + names(dim(clim_obs)) <- dat_dim + } + + ## ensemble mean + if (!memb) { + if (length(dim(clim_exp)) == 1) { #dim: [member] + clim_exp <- mean(clim_exp, na.rm = TRUE) + clim_obs <- mean(clim_obs, na.rm = TRUE) + } else { + dim_name <- names(dim(clim_exp)) + pos <- c(1:length(dim(clim_exp)))[-which(dim_name == memb_dim)] + clim_exp <- apply(clim_exp, pos, mean, na.rm = TRUE) + clim_obs <- apply(clim_obs, pos, mean, na.rm = TRUE) + if (is.null(dim(clim_exp))) { + dim(clim_exp) <- length(clim_exp) + dim(clim_obs) <- length(clim_obs) + names(dim(clim_exp)) <- dim_name[pos] + names(dim(clim_obs)) <- dim_name[pos] + } } } + } else { #dat_dim = NULL + clim_exp <- mean(exp) + clim_obs <- mean(obs) } } else if (method == 'kharin') { @@ -267,27 +308,39 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), # obs: [sdate, dat_dim_obs] # obs clim - clim_obs <- apply(obs, which(names(dim(obs)) != time_dim), - mean, na.rm = na.rm) #[dat_dim] + if (!is.null(dat_dim)) { + clim_obs <- apply(obs, which(names(dim(obs)) != time_dim), + mean, na.rm = na.rm) #[dat_dim] + if (is.null(dim(clim_obs))) { + dim(clim_obs) <- length(clim_obs) + names(dim(clim_obs)) <- dat_dim + } + } else { + clim_obs <- mean(obs) + } # exp clim ##--- NEW trend ---## - tmp_obs <- Trend(data = obs, time_dim = time_dim, interval = 1, - polydeg = 1, conf = FALSE, ncores = ncores_input)$trend + tmp_obs <- Trend(data = obs, time_dim = time_dim, interval = 1, + polydeg = 1, conf = FALSE, ncores = ncores_input)$trend tmp_exp <- Trend(data = exp, time_dim = time_dim, interval = 1, polydeg = 1, conf = FALSE, ncores = ncores_input)$trend - # tmp_exp: [stats, dat_dim)] - + # tmp_exp: [stats, dat_dim] tmp_obs_mean <- apply(tmp_obs, 1, mean) #average out dat_dim (dat and member) #tmp_obs_mean: [stats = 2] - - intercept_exp <- Subset(tmp_exp, 1, 1, drop = 'selected') #[dat_dim] - slope_exp <- Subset(tmp_exp, 1, 2, drop = 'selected') #[dat_dim] - intercept_obs <- array(tmp_obs_mean[1], dim = dim(exp)[-1]) #[dat_dim] - slope_obs <- array(tmp_obs_mean[2], dim = dim(exp)[-1]) #[dat_dim] + if (!is.null(dat_dim)) { + intercept_exp <- Subset(tmp_exp, 1, 1, drop = 'selected') #[dat_dim] + slope_exp <- Subset(tmp_exp, 1, 2, drop = 'selected') #[dat_dim] + intercept_obs <- array(tmp_obs_mean[1], dim = dim(exp)[-1]) #[dat_dim] + slope_obs <- array(tmp_obs_mean[2], dim = dim(exp)[-1]) #[dat_dim] + } else { + intercept_exp <- tmp_exp[1] + slope_exp <- tmp_exp[2] + intercept_obs <- tmp_obs_mean[1] + slope_obs <- tmp_obs_mean[2] + } trend_exp <- list() trend_obs <- list() - for (jdate in 1:dim(exp)[time_dim]) { trend_exp[[jdate]] <- intercept_exp + jdate * slope_exp trend_obs[[jdate]] <- intercept_obs + jdate * slope_obs @@ -295,26 +348,40 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), # turn list into array trend_exp <- array(unlist(trend_exp), dim = c(dim(exp)[-1], dim(exp)[1])) trend_obs <- array(unlist(trend_obs), dim = c(dim(exp)[-1], dim(exp)[1])) - len <- length(dim(exp)) - trend_exp <- Reorder(trend_exp, c(len, 1:(len - 1))) - trend_obs <- Reorder(trend_obs, c(len, 1:(len - 1))) + if (!is.null(dat_dim)) { + len <- length(dim(exp)) + trend_exp <- Reorder(trend_exp, c(len, 1:(len - 1))) + trend_obs <- Reorder(trend_obs, c(len, 1:(len - 1))) + } - clim_obs_mean <- mean(apply(clim_obs, 1, mean)) #average out dat_dim, get a number + # average out dat_dim, get a number + if (is.null(dim(clim_obs))) { + clim_obs_mean <- mean(clim_obs) + } else { + clim_obs_mean <- mean(apply(clim_obs, 1, mean)) + } clim_obs_mean <- array(clim_obs_mean, dim = dim(exp)) #enlarge it for the next line clim_exp <- trend_exp - trend_obs + clim_obs_mean - - ## member mean + + ## member mean if (!memb) { - pos <- which(names(dim(clim_exp)) == memb_dim) - pos <- c(1:length(dim(clim_exp)))[-pos] - dim_name <- names(dim(clim_exp)) - clim_exp <- apply(clim_exp, pos, mean, na.rm = TRUE) - clim_obs <- apply(clim_obs, pos, mean, na.rm = TRUE) - if (is.null(names(dim(as.array(clim_exp))))) { + pos_exp <- c(1:length(dim(clim_exp)))[-which(names(dim(clim_exp)) == memb_dim)] + pos_obs <- c(1:length(dim(clim_obs)))[-which(names(dim(clim_obs)) == memb_dim)] + tmp_dim_exp <- dim(clim_exp) + tmp_dim_obs <- dim(clim_obs) + clim_exp <- apply(clim_exp, pos_exp, mean, na.rm = TRUE) + if (is.integer(pos_obs) & length(pos_obs) == 0) { + clim_obs <- mean(clim_obs) + } else { + clim_obs <- apply(clim_obs, pos_obs, mean, na.rm = TRUE) + } + if (is.null(dim(clim_exp))) { clim_exp <- as.array(clim_exp) + dim(clim_exp) <- tmp_dim_exp[pos_exp] + } + if (is.null(dim(clim_obs)) & !(is.integer(pos_obs) & length(pos_obs) == 0)) { clim_obs <- as.array(clim_obs) - names(dim(clim_exp)) <- dim_name[pos] - names(dim(clim_obs)) <- dim_name[pos] + dim(clim_obs) <- tmp_dim_obs[pos_obs] } } @@ -323,15 +390,24 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), # exp: [sdate, dat_dim, ftime] # obs: [sdate, dat_dim, ftime] - # obs clim + # obs clim clim_obs <- apply(obs, which(names(dim(obs)) != time_dim), - mean, na.rm = na.rm) #[dat_dim, ftime] + mean, na.rm = na.rm) #[(dat_dim), ftime] - # exp clim + if (is.null(dim(clim_obs))) { + dim(clim_obs) <- length(clim_obs) + names(dim(clim_obs)) <- c(dat_dim, ftime_dim) + } + + # exp clim pos_ftime <- length(dim(exp)) #a number dim_ftime <- dim(exp)[pos_ftime] #c(ftime = 4) - pos_dat <- 2:(length(dim(exp)) - 1) #1 is sdate, last is ftime - dim_dat <- dim(exp)[pos_dat] #c(dataset = 1, member = 3) + if (!is.null(dat_dim)) { + pos_dat <- 2:(length(dim(exp)) - 1) #1 is sdate, last is ftime + dim_dat <- dim(exp)[pos_dat] #c(dataset = 1, member = 3) + } else { + dim_dat <- NULL + } # Create initial data set (i.e., only first ftime) tmp <- Subset(exp, ftime_dim, 1, drop = 'selected') @@ -354,14 +430,14 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), # Find intercept and slope intercept_exp <- Subset(tmp_exp, 1, 1, drop = 'selected') #[dat_dim, ftime] slope_exp <- Subset(tmp_exp, 1, 2, drop = 'selected') #[dat_dim, ftime] - intercept_obs <- array(tmp_obs_mean[1, ], dim = c(dim_ftime, dim_dat)) - #[ftime, dat_dim] exp - intercept_obs <- Reorder(intercept_obs, c(2:length(dim(intercept_obs)), 1)) - #[dat_dim, ftime] exp - slope_obs <- array(tmp_obs_mean[2, ], dim = c(dim_ftime, dim_dat)) - #[ftime, dat_dim] exp - slope_obs <- Reorder(slope_obs, c(2:length(dim(slope_obs)), 1)) - #[dat_dim, ftime] exp + intercept_obs <- array(tmp_obs_mean[1, ], dim = c(dim_ftime, dim_dat)) #[ftime, dat_dim] exp + if (!is.null(dat_dim)) { + intercept_obs <- Reorder(intercept_obs, c(2:length(dim(intercept_obs)), 1)) #[dat_dim, ftime] exp + } + slope_obs <- array(tmp_obs_mean[2, ], dim = c(dim_ftime, dim_dat)) #[ftime, dat_dim] exp + if (!is.null(dat_dim)) { + slope_obs <- Reorder(slope_obs, c(2:length(dim(slope_obs)), 1)) #[dat_dim, ftime] exp + } trend_exp <- list() trend_obs <- list() @@ -370,7 +446,9 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), trend_exp[[jdate]] <- intercept_exp + tmp * slope_exp #[dat_dim, ftime] tmp <- array(ini_obs_mean[jdate, ], dim = c(dim_ftime, dim_dat)) #[ftime, dat_dim] - tmp <- Reorder(tmp, c(2:length(dim(tmp)), 1)) #[dat_dim, ftime] + if (!is.null(dat_dim)) { + tmp <- Reorder(tmp, c(2:length(dim(tmp)), 1)) #[dat_dim, ftime] + } trend_obs[[jdate]] <- intercept_obs + tmp * slope_obs } # turn list into array @@ -381,8 +459,11 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), trend_exp <- Reorder(trend_exp, c(len, 1:(len - 1))) trend_obs <- Reorder(trend_obs, c(len, 1:(len - 1))) #trend_: [sdate, dat_dim, ftime] - + if (is.null(dim(clim_obs))) { + clim_obs_mean <- clim_obs #[ftime] + } else { clim_obs_mean <- apply(clim_obs, length(dim(clim_obs)), mean) #average out dat_dim, [ftime] + } clim_obs_mean <- array(clim_obs_mean, dim = c(dim_ftime, dim(exp)[1], dim_dat)) #[ftime, sdate, dat_dim] len <- length(dim(clim_obs_mean)) @@ -391,18 +472,26 @@ Clim <- function(exp, obs, time_dim = 'sdate', dat_dim = c('dataset', 'member'), clim_exp <- trend_exp - trend_obs + clim_obs_mean - ## member mean + ## member mean if (!memb) { - pos <- which(names(dim(clim_exp)) == memb_dim) - pos <- c(1:length(dim(clim_exp)))[-pos] - dim_name <- names(dim(clim_exp)) - clim_exp <- apply(clim_exp, pos, mean, na.rm = TRUE) - clim_obs <- apply(clim_obs, pos, mean, na.rm = TRUE) - if (is.null(names(dim(as.array(clim_exp))))) { + pos_exp <- c(1:length(dim(clim_exp)))[-which(names(dim(clim_exp)) == memb_dim)] + pos_obs <- c(1:length(dim(clim_obs)))[-which(names(dim(clim_obs)) == memb_dim)] + + tmp_dim_exp <- dim(clim_exp) + tmp_dim_obs <- dim(clim_obs) + clim_exp <- apply(clim_exp, pos_exp, mean, na.rm = TRUE) + if (is.integer(pos_obs) & length(pos_obs) == 0) { + clim_obs <- mean(clim_obs) + } else { + clim_obs <- apply(clim_obs, pos_obs, mean, na.rm = TRUE) + } + if (is.null(dim(clim_exp))) { clim_exp <- as.array(clim_exp) + dim(clim_exp) <- tmp_dim_exp[pos_exp] + } + if (is.null(dim(clim_obs)) & !(is.integer(pos_obs) & length(pos_obs) == 0)) { clim_obs <- as.array(clim_obs) - names(dim(clim_exp)) <- dim_name[pos] - names(dim(clim_obs)) <- dim_name[pos] + dim(clim_obs) <- tmp_dim_obs[pos_obs] } } diff --git a/man/Clim.Rd b/man/Clim.Rd index cf5852590a0f4d76984f195450e3a131d253f84b..a5a6f19608a1aef12c82bced943418d74bc9eee3 100644 --- a/man/Clim.Rd +++ b/man/Clim.Rd @@ -18,11 +18,11 @@ Clim( ) } \arguments{ -\item{exp}{A named numeric array of experimental data, with at least two -dimensions 'time_dim' and 'dat_dim'.} +\item{exp}{A named numeric array of experimental data with at least dimension +'time_dim'.} -\item{obs}{A named numeric array of observational data, same dimensions as -parameter 'exp' except along 'dat_dim'.} +\item{obs}{A named numeric array of observational data that has the same +dimension as 'exp' except 'dat_dim'.} \item{time_dim}{A character string indicating the name of dimension along which the climatologies are computed. The default value is 'sdate'.} @@ -30,7 +30,9 @@ which the climatologies are computed. The default value is 'sdate'.} \item{dat_dim}{A character vector indicating the name of the dataset and member dimensions. If data at one startdate (i.e., 'time_dim') are not complete along 'dat_dim', this startdate along 'dat_dim' will be discarded. -The default value is "c('dataset', 'member')".} +If there is no dataset dimension, it can be NULL, however, it will be more +efficient to simply use mean() to do the calculation. The default value is +"c('dataset', 'member')".} \item{method}{A character string indicating the method to be used. The options include 'clim' (per-pair method), 'kharin' (Kharin method), and @@ -40,7 +42,8 @@ options include 'clim' (per-pair method), 'kharin' (Kharin method), and dimension. Only used when method = 'NDV'. The default value is 'ftime'.} \item{memb}{A logical value indicating whether to remain 'memb_dim' dimension -(TRUE) or do ensemble mean over 'memb_dim' (FALSE). The default value is TRUE.} +(TRUE) or do ensemble mean over 'memb_dim' (FALSE). The default value is +TRUE.} \item{memb_dim}{A character string indicating the name of the member dimension. Only used when parameter 'memb' is FALSE. It must be one element @@ -62,7 +65,7 @@ A list of 2: dimension 'memb_dim' is also removed. } \item{$clim_obs}{ - A numeric array with the same dimensions as parameter 'exp' + A numeric array with the same dimensions as parameter 'obs' except dimension 'time_dim' is removed. If parameter 'memb' is FALSE, dimension 'memb_dim' is also removed. } diff --git a/man/ResidualCorr.Rd b/man/ResidualCorr.Rd index 1e0adad151ea2d1abb86b6237c506ecfe1ff9ab5..e98ea7a439d56191eeca8b2d135924c401c23ad9 100644 --- a/man/ResidualCorr.Rd +++ b/man/ResidualCorr.Rd @@ -67,9 +67,9 @@ A list with: the input arrays except "time_dim" (and "memb_dim" if provided). } \item{$sign}{ - A logical array of the statistical significance of the residual correlation - with the same dimensions as the input arrays except "time_dim" (and - "memb_dim" if provided). Returned only if "alpha" is a numeric. + A logical array indicating whether the residual correlation is statistically + significant or not with the same dimensions as the input arrays except "time_dim" + (and "memb_dim" if provided). Returned only if "alpha" is a numeric. } \item{$p.val}{ A numeric array of the p-values with the same dimensions as the input arrays diff --git a/tests/testthat/test-Clim.R b/tests/testthat/test-Clim.R index 1d2ff3e6b013cdefd1cd3375a34193d2bbc0545d..7751afb405c23c4e42cc5587eefa7f670182d14e 100644 --- a/tests/testthat/test-Clim.R +++ b/tests/testthat/test-Clim.R @@ -7,7 +7,7 @@ context("s2dv::Clim tests") ftime = 3, lon = 2, lat = 4)) set.seed(2) obs1 <- array(rnorm(120), dim = c(dataset = 1, member = 1, - ftime = 3, lon = 2, lat = 4, sdate = 5)) + ftime = 3, lon = 2, lat = 4, sdate = 5)) # dat2 exp2 <- exp1 set.seed(1) @@ -26,6 +26,43 @@ context("s2dv::Clim tests") obs3 <- array(rnorm(40), dim = c(dat = 1, ensemble = 1, lon = 2, lat = 4, date = 5)) + # dat4 + set.seed(1) + exp4 <- array(rnorm(30), dim = c(dataset = 1, member = 3, sdate = 5)) + set.seed(2) + obs4 <- array(rnorm(10), dim = c(dataset = 1, member = 1, sdate = 5)) + + # dat5 + set.seed(1) + exp5 <- array(rnorm(30), dim = c(member = 3, sdate = 5)) + set.seed(2) + obs5 <- array(rnorm(10), dim = c(member = 1, sdate = 5)) + + # dat6 + set.seed(1) + exp6 <- array(rnorm(30), dim = c(dataset = 1, member = 3, sdate = 5)) + set.seed(2) + obs6 <- array(rnorm(10), dim = c(dataset = 1, sdate = 5)) + + # dat7 + set.seed(1) + exp7 <- array(rnorm(30), dim = c(dataset = 1, member = 3, sdate = 5)) + set.seed(2) + obs7 <- array(rnorm(10), dim = c(sdate = 5)) + + # dat8 + set.seed(1) + exp8 <- array(rnorm(30), dim = c(member = 3, sdate = 5)) + set.seed(2) + obs8 <- array(rnorm(10), dim = c(sdate = 5)) + + # dat9 + set.seed(1) + exp9 <- array(rnorm(30), dim = c(sdate = 5)) + set.seed(2) + obs9 <- array(rnorm(10), dim = c(sdate = 5)) + + ############################################## test_that("1. Input checks", { @@ -47,10 +84,6 @@ test_that("1. Input checks", { "Parameter 'exp' and 'obs' must have dimension names." ) expect_error( - Clim(array(1:10, dim = c(a = 2, c = 5)), array(1:4, dim = c(a = 2, b = 2))), - "Parameter 'exp' and 'obs' must have same dimension name" - ) - expect_error( Clim(exp1, obs1, method = TRUE), "Parameter 'method' must be one of 'clim', 'kharin' or 'NDV'." ) @@ -68,7 +101,7 @@ test_that("1. Input checks", { ) expect_error( Clim(exp1, obs1, dat_dim = c('member', 'dat')), - "Parameter 'dat_dim' is not found in 'exp' or 'obs' dimension." + "Parameter 'dat_dim' is not found in 'exp' dimensions." ) expect_error( Clim(exp1, obs1, method = 'NDV', ftime_dim = 4), @@ -88,7 +121,7 @@ test_that("1. Input checks", { ) expect_error( Clim(exp1, obs1, memb = FALSE, memb_dim = 'memb'), - "Parameter 'memb_dim' is not found in 'exp' or 'obs' dimension." + "Parameter 'memb_dim' is not found in 'exp' dimension." ) expect_error( Clim(exp1, obs1, na.rm = na.omit), @@ -101,8 +134,7 @@ test_that("1. Input checks", { expect_error( Clim(array(1:10, dim = c(dataset = 2, member = 5, sdate = 4, ftime = 3)), array(1:4, dim = c(dataset = 2, member = 2, sdate = 5, ftime = 3))), - paste0("Parameter 'exp' and 'obs' must have same length of ", - "all dimension expect 'dat_dim'.") + "Parameter 'exp' and 'obs' must have the same dimensions expect 'dat_dim'." ) }) @@ -110,58 +142,79 @@ test_that("1. Input checks", { ############################################## test_that("2. Output checks: dat1", { + # dimension expect_equal( dim(Clim(exp1, obs1)$clim_exp), c(dataset = 1, member = 3, ftime = 3, lon = 2, lat = 4) ) expect_equal( - dim(Clim(exp1, obs1, memb = FALSE)$clim_exp), - c(dataset = 1, ftime = 3, lon = 2, lat = 4) + dim(Clim(exp1, obs1)$clim_obs), + c(dataset = 1, member = 1, ftime = 3, lon = 2, lat = 4) ) expect_equal( - dim(Clim(exp1, obs1, time_dim = 'lon')$clim_exp), - c(dataset = 1, member = 3, sdate = 5, ftime = 3, lat = 4) + dim(Clim(exp1, obs1, memb = FALSE)$clim_exp), + c(dataset = 1, ftime = 3, lon = 2, lat = 4) ) expect_equal( - dim(Clim(exp1, obs1, method = 'kharin')$clim_exp), - c(sdate = 5, dataset = 1, member = 3, ftime = 3, lon = 2, lat = 4) + dim(Clim(exp1, obs1, memb = FALSE)$clim_obs), + c(dataset = 1, ftime = 3, lon = 2, lat = 4) ) expect_equal( - dim(Clim(exp1, obs1, method = 'NDV')$clim_exp), - c(sdate = 5, dataset = 1, member = 3, ftime = 3, lon = 2, lat = 4) + dim(Clim(exp1, obs1, time_dim = 'lon')$clim_exp), + c(dataset = 1, member = 3, sdate = 5, ftime = 3, lat = 4) ) + # clim_exp expect_equal( - dim(Clim(exp1, obs1)$clim_obs), - c(dataset = 1, member = 1, ftime = 3, lon = 2, lat = 4) + (Clim(exp1, obs1, memb = TRUE)$clim_exp)[1:5], + c(0.10592542, 0.10971142, 0.08689170, 0.14149945, 0.02359945), + tolerance = 0.001 ) expect_equal( - dim(Clim(exp1, obs1, method = 'kharin')$clim_obs), - c(dataset = 1, member = 1, ftime = 3, lon = 2, lat = 4) + (Clim(exp1, obs1, memb = FALSE)$clim_exp)[1:5], + c(0.10084284, 0.06407350, 0.09028584, 0.17526332, 0.18004387), + tolerance = 0.001 ) expect_equal( - dim(Clim(exp1, obs1, method = 'NDV')$clim_obs), - c(dataset = 1, member = 1, ftime = 3, lon = 2, lat = 4) + max(Clim(exp1, obs1)$clim_exp, na.rm = T), + 1.026186, + tolerance = 0.001 ) + # clim_obs expect_equal( (Clim(exp1, obs1)$clim_obs)[1:5], c(0.14831161, -0.60462627, 0.06609153, -0.23378059, 0.50553522), tolerance = 0.001 ) expect_equal( - (Clim(exp1, obs1, memb = FALSE)$clim_exp)[1:5], - c(0.10084284, 0.06407350, 0.09028584, 0.17526332, 0.18004387), + (Clim(exp1, obs1, memb = F)$clim_obs)[1:5], + c(0.14831161, -0.60462627, 0.06609153, -0.23378059, 0.50553522), tolerance = 0.001 ) + + # method = 'kharin' expect_equal( - max(Clim(exp1, obs1)$clim_exp, na.rm = T), - 1.026186, - tolerance = 0.001 + dim(Clim(exp1, obs1, method = 'kharin')$clim_exp), + c(sdate = 5, dataset = 1, member = 3, ftime = 3, lon = 2, lat = 4) + ) + expect_equal( + dim(Clim(exp1, obs1, method = 'kharin')$clim_obs), + c(dataset = 1, member = 1, ftime = 3, lon = 2, lat = 4) ) expect_equal( max(Clim(exp1, obs1, method = 'kharin')$clim_exp, na.rm = T), 2.282634, tolerance = 0.001 ) + + # method = 'NDV' + expect_equal( + dim(Clim(exp1, obs1, method = 'NDV')$clim_exp), + c(sdate = 5, dataset = 1, member = 3, ftime = 3, lon = 2, lat = 4) + ) + expect_equal( + dim(Clim(exp1, obs1, method = 'NDV')$clim_obs), + c(dataset = 1, member = 1, ftime = 3, lon = 2, lat = 4) + ) expect_equal( min(Clim(exp1, obs1, method = 'NDV')$clim_exp, na.rm = T), -4.025745, @@ -212,9 +265,520 @@ test_that("4. Output checks: dat3", { tolerance = 0.00001 ) +}) + + +############################################## +test_that("5. Output checks: dat4", { +res1 <- Clim(exp4, obs4, memb = T) +res2 <- Clim(exp4, obs4, memb = F) +expect_equal( +dim(res1$clim_exp), +c(dataset = 1, member = 3) +) +expect_equal( +dim(res1$clim_obs), +c(dataset = 1, member = 1) +) +expect_equal( +dim(res2$clim_exp), +c(dataset = 1) +) +expect_equal( +dim(res2$clim_obs), +c(dataset = 1) +) +expect_equal( +as.vector(res1$clim_exp), +c(0.1059254, 0.1097114, 0.0868917), +tolerance = 0.0001 +) +expect_equal( +as.vector(res1$clim_obs), +-0.06696949, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_exp), +0.1008428, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_obs), +-0.06696949, +tolerance = 0.0001 +) +# method = 'kharin' +res1 <- Clim(exp4, obs4, memb = T, method = 'kharin') +res2 <- Clim(exp4, obs4, memb = F, method = 'kharin') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5, dataset = 1, member = 3) +) +expect_equal( +dim(res1$clim_obs), +c(dataset = 1, member = 1) +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5, dataset = 1) +) +expect_equal( +dim(res2$clim_obs), +c(dataset = 1) +) + +# method = 'NDV' +exp4 <- array(exp4, dim = c(dim(exp4), ftime = 1)) +obs4 <- array(obs4, dim = c(dim(obs4), ftime = 1)) +res1 <- Clim(exp4, obs4, memb = T, method = 'NDV') +res2 <- Clim(exp4, obs4, memb = F, method = 'NDV') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5, dataset = 1, member = 3, ftime = 1) +) +expect_equal( +dim(res1$clim_obs), +c(dataset = 1, member = 1, ftime = 1) +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5, dataset = 1, ftime = 1) +) +expect_equal( +dim(res2$clim_obs), +c(dataset = 1, ftime = 1) +) + +}) + + +############################################## +test_that("6. Output checks: dat5", { +res1 <- Clim(exp5, obs5, dat_dim = 'member', memb = T) +res2 <- Clim(exp5, obs5, dat_dim = 'member', memb = F) +expect_equal( +dim(res1$clim_exp), +c(member = 3) +) +expect_equal( +dim(res1$clim_obs), +c(member = 1) +) +expect_equal( +dim(res2$clim_exp), +NULL +) +expect_equal( +dim(res2$clim_obs), +NULL +) +expect_equal( +as.vector(res1$clim_exp), +c(0.1059254, 0.1097114, 0.0868917), +tolerance = 0.0001 +) +expect_equal( +as.vector(res1$clim_obs), +-0.06696949, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_exp), +0.1008428, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_obs), +-0.06696949, +tolerance = 0.0001 +) + +# method = 'kharin' +res1 <- Clim(exp5, obs5, memb = T, dat_dim = 'member', method = 'kharin') +res2 <- Clim(exp5, obs5, memb = F, dat_dim = 'member', method = 'kharin') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5, member = 3) +) +expect_equal( +dim(res1$clim_obs), +c(member = 1) +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5) +) +expect_equal( +dim(res2$clim_obs), +NULL +) + +# method = 'NDV' +exp5 <- array(exp5, dim = c(dim(exp5), ftime = 1)) +obs5 <- array(obs5, dim = c(dim(obs5), ftime = 1)) +res1 <- Clim(exp5, obs5, memb = T, dat_dim = 'member', method = 'NDV') +res2 <- Clim(exp5, obs5, memb = F, dat_dim = 'member', method = 'NDV') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5, member = 3, ftime = 1) +) +expect_equal( +dim(res1$clim_obs), +c(member = 1, ftime = 1) +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5, ftime = 1) +) +expect_equal( +dim(res2$clim_obs), +c(ftime = 1) +) + +}) + +############################################## +test_that("7. Output checks: dat6", { +res1 <- Clim(exp6, obs6, memb = T) +res2 <- Clim(exp6, obs6, memb = F) +expect_equal( +dim(res1$clim_exp), +c(dataset = 1, member = 3) +) +expect_equal( +dim(res1$clim_obs), +c(dataset = 1) +) +expect_equal( +dim(res2$clim_exp), +c(dataset = 1) +) +expect_equal( +dim(res2$clim_obs), +c(dataset = 1) +) +expect_equal( +as.vector(res1$clim_exp), +c(0.1059254, 0.1097114, 0.0868917), +tolerance = 0.0001 +) +expect_equal( +as.vector(res1$clim_obs), +-0.06696949, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_exp), +0.1008428, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_obs), +-0.06696949, +tolerance = 0.0001 +) + +# method = 'kharin' +res1 <- Clim(exp6, obs6, memb = T, method = 'kharin') +res2 <- Clim(exp6, obs6, memb = F, method = 'kharin') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5, dataset = 1, member = 3) +) +expect_equal( +dim(res1$clim_obs), +c(dataset = 1) +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5, dataset = 1) +) +expect_equal( +dim(res2$clim_obs), +c(dataset = 1) +) +# method = 'NDV' +exp6 <- array(exp6, dim = c(dim(exp6), ftime = 1)) +obs6 <- array(obs6, dim = c(dim(obs6), ftime = 1)) +res1 <- Clim(exp6, obs6, memb = T, method = 'NDV') +res2 <- Clim(exp6, obs6, memb = F, method = 'NDV') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5, dataset = 1, member = 3, ftime = 1) +) +expect_equal( +dim(res1$clim_obs), +c(dataset = 1, ftime = 1) +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5, dataset = 1, ftime = 1) +) +expect_equal( +dim(res2$clim_obs), +c(dataset = 1, ftime = 1) +) +}) + +############################################## +test_that("8. Output checks: dat7", { +res1 <- Clim(exp7, obs7, memb = T) +res2 <- Clim(exp7, obs7, memb = F) +expect_equal( +dim(res1$clim_exp), +c(dataset = 1, member = 3) +) +expect_equal( +dim(res1$clim_obs), +NULL +) +expect_equal( +dim(res2$clim_exp), +c(dataset = 1) +) +expect_equal( +dim(res2$clim_obs), +NULL +) +expect_equal( +as.vector(res1$clim_exp), +c(0.1059254, 0.1097114, 0.0868917), +tolerance = 0.0001 +) +expect_equal( +as.vector(res1$clim_obs), +-0.06696949, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_exp), +0.1008428, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_obs), +-0.06696949, +tolerance = 0.0001 +) + +# method = 'kharin' +res1 <- Clim(exp7, obs7, memb = T, method = 'kharin') +res2 <- Clim(exp7, obs7, memb = F, method = 'kharin') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5, dataset = 1, member = 3) +) +expect_equal( +dim(res1$clim_obs), +NULL +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5, dataset = 1) +) +expect_equal( +dim(res2$clim_obs), +NULL +) + +# method = 'NDV' +exp7 <- array(exp7, dim = c(dim(exp7), ftime = 1)) +obs7 <- array(obs7, dim = c(dim(obs7), ftime = 1)) +res1 <- Clim(exp7, obs7, memb = T, method = 'NDV') +res2 <- Clim(exp7, obs7, memb = F, method = 'NDV') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5, dataset = 1, member = 3, ftime = 1) +) +expect_equal( +dim(res1$clim_obs), +c(ftime = 1) +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5, dataset = 1, ftime = 1) +) +expect_equal( +dim(res2$clim_obs), +c(ftime = 1) +) }) + +############################################## +test_that("9. Output checks: dat8", { +res1 <- Clim(exp8, obs8, dat_dim = 'member', memb = T) +res2 <- Clim(exp8, obs8, dat_dim = 'member', memb = F) +expect_equal( +dim(res1$clim_exp), +c(member = 3) +) +expect_equal( +dim(res1$clim_obs), +NULL +) +expect_equal( +dim(res2$clim_exp), +NULL +) +expect_equal( +dim(res2$clim_obs), +NULL +) +expect_equal( +as.vector(res1$clim_exp), +c(0.1059254, 0.1097114, 0.0868917), +tolerance = 0.0001 +) +expect_equal( +as.vector(res1$clim_obs), +-0.06696949, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_exp), +0.1008428, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_obs), +-0.06696949, +tolerance = 0.0001 +) + +# method = 'kharin' +res1 <- Clim(exp8, obs8, dat_dim = 'member', memb = T, method = 'kharin') +res2 <- Clim(exp8, obs8, dat_dim = 'member', memb = F, method = 'kharin') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5, member = 3) +) +expect_equal( +dim(res1$clim_obs), +NULL +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5) +) +expect_equal( +dim(res2$clim_obs), +NULL +) + +# method = 'NDV' +exp8 <- array(exp8, dim = c(dim(exp8), ftime = 1)) +obs8 <- array(obs8, dim = c(dim(obs8), ftime = 1)) +res1 <- Clim(exp8, obs8, dat_dim = 'member', memb = T, method = 'NDV') +res2 <- Clim(exp8, obs8, dat_dim = 'member', memb = F, method = 'NDV') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5, member = 3, ftime = 1) +) +expect_equal( +dim(res1$clim_obs), +c(ftime = 1) +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5, ftime = 1) +) +expect_equal( +dim(res2$clim_obs), +c(ftime = 1) +) + +}) + +############################################## +test_that("10. Output checks: dat9", { +res1 <- Clim(exp9, obs9, dat_dim = NULL, memb = T) +res2 <- Clim(exp9, obs9, dat_dim = NULL, memb_dim = NULL, memb = F) +expect_equal( +dim(res1$clim_exp), +NULL +) +expect_equal( +dim(res1$clim_obs), +NULL +) +expect_equal( +dim(res2$clim_exp), +NULL +) +expect_equal( +dim(res2$clim_obs), +NULL +) +expect_equal( +as.vector(res1$clim_exp), +0.1292699, +tolerance = 0.0001 +) +expect_equal( +as.vector(res1$clim_obs), +-0.06696949, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_exp), +0.1292699, +tolerance = 0.0001 +) +expect_equal( +as.vector(res2$clim_obs), +-0.06696949, +tolerance = 0.0001 +) + +# method = 'kharin' +res1 <- Clim(exp9, obs9, dat_dim = NULL, memb = T, method = 'kharin') +res2 <- Clim(exp9, obs9, dat_dim = NULL, memb_dim = NULL, memb = F, method = 'kharin') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5) +) +expect_equal( +dim(res1$clim_obs), +NULL +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5) +) +expect_equal( +dim(res2$clim_obs), +NULL +) + +# method = 'NDV' +exp9 <- array(exp9, dim = c(dim(exp9), ftime = 1)) +obs9 <- array(obs9, dim = c(dim(obs9), ftime = 1)) +res1 <- Clim(exp9, obs9, dat_dim = NULL, memb = T, method = 'NDV') +res2 <- Clim(exp9, obs9, dat_dim = NULL, memb_dim = NULL, memb = F, method = 'NDV') +expect_equal( +dim(res1$clim_exp), +c(sdate = 5, ftime = 1) +) +expect_equal( +dim(res1$clim_obs), +c(ftime = 1) +) +expect_equal( +dim(res2$clim_exp), +c(sdate = 5, ftime = 1) +) +expect_equal( +dim(res2$clim_obs), +c(ftime = 1) +) + + +}) + +##############################################