diff --git a/NEWS.md b/NEWS.md index 92ad49b15e6eb43f3efc4e27c2e361fe35ed1dc7..e57b835859743a5c64e74f3ef5367139517de885 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,6 +10,7 @@ - Fixes: + PlotForecastPDF correctly displays terciles labels + CST_SaveExp correctly save time units + + CST_SplitDims returns ordered output following ascending order provided in indices when it is numeric ### CSTools 3.1.0 **Submission date to CRAN: 02-07-2020** diff --git a/R/CST_SplitDim.R b/R/CST_SplitDim.R index 46cd97cca21aeb1787b6d572f30662fdffb4181e..3326d435af6ecf535bc66ebe09d7d05a14cd499b 100644 --- a/R/CST_SplitDim.R +++ b/R/CST_SplitDim.R @@ -8,6 +8,7 @@ #'@param split_dim a character string indicating the name of the dimension to split #'@param indices a vector of numeric indices or dates. If left at NULL, the dates provided in the s2dv_cube object (element Dates) will be used. #'@param freq a character string indicating the frequency: by 'day', 'month' and 'year' or 'monthly' (by default). 'month' identifies months between 1 and 12 independently of the year they belong to, while 'monthly' differenciates months from different years. +#'@param new_dim_name a character string indicating the name of the new dimension. #' #'@import abind #'@import s2dverification @@ -34,12 +35,13 @@ #'dim(new_data$data) #'@export CST_SplitDim <- function(data, split_dim = 'time', indices = NULL, - freq = 'monthly') { + freq = 'monthly', new_dim_name = NULL) { if (!inherits(data, 's2dv_cube')) { stop("Parameter 'data' must be of the class 's2dv_cube', ", "as output by CSTools::CST_Load.") } if (is.null(indices)) { + if (any(split_dim %in% c('ftime', 'time', 'sdate'))) { if (is.list(data$Dates)) { indices <- data$Dates[[1]] } else { @@ -53,9 +55,10 @@ CST_SplitDim <- function(data, split_dim = 'time', indices = NULL, indices <- indices[1 : dim(data$data)[which(names(dim(data$data)) == split_dim)]] } + } } data$data <- SplitDim(data$data, split_dim = split_dim, indices = indices, - freq = freq) + freq = freq, new_dim_name = new_dim_name) return(data) } #'Function to Split Dimension @@ -67,8 +70,8 @@ CST_SplitDim <- function(data, split_dim = 'time', indices = NULL, #'@param data an n-dimensional array with named dimensions #'@param split_dim a character string indicating the name of the dimension to split #'@param indices a vector of numeric indices or dates -#'@param freq a character string indicating the frequency: by 'day', 'month' and 'year' or 'monthly' (by default). 'month' identifies months between 1 and 12 independetly of the year they belong to, while 'monthly' differenciates months from different years. Parameter 'freq' can also be numeric indicating the length in which to subset the dimension -#' +#'@param freq a character string indicating the frequency: by 'day', 'month' and 'year' or 'monthly' (by default). 'month' identifies months between 1 and 12 independetly of the year they belong to, while 'monthly' differenciates months from different years. Parameter 'freq' can also be numeric indicating the length in which to subset the dimension. +#'@param new_dim_name a character string indicating the name of the new dimension. #'@import abind #'@import s2dverification #'@examples @@ -85,7 +88,8 @@ CST_SplitDim <- function(data, split_dim = 'time', indices = NULL, #'new_data <- SplitDim(data, indices = time, freq = 'month') #'new_data <- SplitDim(data, indices = time, freq = 'year') #'@export -SplitDim <- function(data, split_dim = 'time', indices, freq = 'monthly') { +SplitDim <- function(data, split_dim = 'time', indices, freq = 'monthly', + new_dim_name = NULL) { # check data if (is.null(data)) { stop("Parameter 'data' cannot be NULL.") @@ -123,6 +127,7 @@ SplitDim <- function(data, split_dim = 'time', indices, freq = 'monthly') { } indices <- rep(1 : (dims[pos_split] / freq), freq) indices <- sort(indices) + repited <- sort(unique(indices)) } } else if (is.numeric(indices)) { if (!is.null(freq)) { @@ -131,6 +136,7 @@ SplitDim <- function(data, split_dim = 'time', indices, freq = 'monthly') { "parameter 'indices' is numeric.") } } + repited <- sort(unique(indices)) } else { # Indices should be Dates and freq character if (!is.character(freq)) { @@ -161,19 +167,33 @@ SplitDim <- function(data, split_dim = 'time', indices, freq = 'monthly') { if (!is.numeric(indices)) { if (freq == 'day') { indices <- as.numeric(strftime(indices, format = "%d")) + repited <- unique(indices) } else if (freq == 'month') { indices <- as.numeric(strftime(indices, format = "%m")) + repited <- unique(indices) } else if (freq == 'year') { indices <- as.numeric(strftime(indices, format = "%Y")) + repited <- unique(indices) } else if (freq == 'monthly' ) { indices <- as.numeric(strftime(indices, format = "%m%Y")) + repited <- unique(indices) } else { stop("Parameter 'freq' must be numeric or a character: ", "by 'day', 'month', 'year' or 'monthly' (for ", "distinguishable month).") } } - repited <- unique(indices) + # check new_dim_name + if (!is.null(new_dim_name)) { + if (!is.character(new_dim_name)) { + stop("Parameter 'new_dim_name' must be character string") + } + if (length(new_dim_name) > 1) { + new_dim_name <- new_dim_name[1] + warning("Parameter 'new_dim_name' has length greater than 1 ", + "and only the first elemenst is used.") + } + } max_times <- max(unlist(lapply(repited, function(x){sum(indices == x)}))) data <- lapply(repited, function(x) {rebuild(x, data, along = split_dim, @@ -184,6 +204,9 @@ SplitDim <- function(data, split_dim = 'time', indices, freq = 'monthly') { } else { names(dim(data)) <- c(names(dims), 'index') } + if (!is.null(new_dim_name)) { + names(dim(data)) <- c(names(dims), new_dim_name) + } return(data) } diff --git a/man/CST_SplitDim.Rd b/man/CST_SplitDim.Rd index ee93aedc2075b38292d392a655a57b83955aecbf..11aca488f25b43346911c1735642b2e2eec5d360 100644 --- a/man/CST_SplitDim.Rd +++ b/man/CST_SplitDim.Rd @@ -4,7 +4,13 @@ \alias{CST_SplitDim} \title{Function to Split Dimension} \usage{ -CST_SplitDim(data, split_dim = "time", indices = NULL, freq = "monthly") +CST_SplitDim( + data, + split_dim = "time", + indices = NULL, + freq = "monthly", + new_dim_name = NULL +) } \arguments{ \item{data}{a 's2dv_cube' object} @@ -14,6 +20,8 @@ CST_SplitDim(data, split_dim = "time", indices = NULL, freq = "monthly") \item{indices}{a vector of numeric indices or dates. If left at NULL, the dates provided in the s2dv_cube object (element Dates) will be used.} \item{freq}{a character string indicating the frequency: by 'day', 'month' and 'year' or 'monthly' (by default). 'month' identifies months between 1 and 12 independently of the year they belong to, while 'monthly' differenciates months from different years.} + +\item{new_dim_name}{a character string indicating the name of the new dimension.} } \description{ This function split a dimension in two. The user can select the dimension to split and provide indices indicating how to split that dimension or dates and the frequency expected (monthly or by day, month and year). The user can also provide a numeric frequency indicating the length of each division. diff --git a/man/SplitDim.Rd b/man/SplitDim.Rd index f07e4756bd2fdbdeaafd4d7cfae30010ec29009a..a49043062c8e2dea743b9f391f53f9929bd41530 100644 --- a/man/SplitDim.Rd +++ b/man/SplitDim.Rd @@ -4,7 +4,13 @@ \alias{SplitDim} \title{Function to Split Dimension} \usage{ -SplitDim(data, split_dim = "time", indices, freq = "monthly") +SplitDim( + data, + split_dim = "time", + indices, + freq = "monthly", + new_dim_name = NULL +) } \arguments{ \item{data}{an n-dimensional array with named dimensions} @@ -13,7 +19,9 @@ SplitDim(data, split_dim = "time", indices, freq = "monthly") \item{indices}{a vector of numeric indices or dates} -\item{freq}{a character string indicating the frequency: by 'day', 'month' and 'year' or 'monthly' (by default). 'month' identifies months between 1 and 12 independetly of the year they belong to, while 'monthly' differenciates months from different years. Parameter 'freq' can also be numeric indicating the length in which to subset the dimension} +\item{freq}{a character string indicating the frequency: by 'day', 'month' and 'year' or 'monthly' (by default). 'month' identifies months between 1 and 12 independetly of the year they belong to, while 'monthly' differenciates months from different years. Parameter 'freq' can also be numeric indicating the length in which to subset the dimension.} + +\item{new_dim_name}{a character string indicating the name of the new dimension.} } \description{ This function split a dimension in two. The user can select the dimension to split and provide indices indicating how to split that dimension or dates and the frequency expected (monthly or by day, month and year). The user can also provide a numeric frequency indicating the length of each division. diff --git a/tests/testthat/test-CST_SplitDim.R b/tests/testthat/test-CST_SplitDim.R index 800344c192cb93ec275c815b976ef4da1f37e25b..d595b76f3d2de806f004bdda2a48a5a6d14a15a7 100644 --- a/tests/testthat/test-CST_SplitDim.R +++ b/tests/testthat/test-CST_SplitDim.R @@ -73,4 +73,20 @@ library(CSTools) result$data <- output expect_equal(CST_SplitDim(data = lonlat_data$exp, split_dim = 'ftime'), result) + + expect_equal(dim(CST_SplitDim(data = lonlat_data$exp, split_dim = 'member', + freq = 5)$data), + c(dataset = 1, member = 5, sdate = 6, ftime = 3, + lat = 22, lon = 53, index = 3)) + expect_warning(CST_SplitDim(data = lonlat_data$exp, split_dim = 'member', + freq = 5, new_dim_name = c('a', 'b')), + paste0("Parameter 'new_dim_name' has length greater than 1 ", + "and only the first elemenst is used.")) + expect_error(CST_SplitDim(data = lonlat_data$exp, split_dim = 'member', + freq = 5, new_dim_name = 3), + "Parameter 'new_dim_name' must be character string") + expect_equal(dim(CST_SplitDim(data = lonlat_data$exp, split_dim = 'member', + freq = 5, new_dim_name = 'wt')$data), + c(dataset = 1, member = 5, sdate = 6, ftime = 3, + lat = 22, lon = 53, wt = 3)) })