From 0b36ea1ed72d13e0b0da6e4d0e610ccb40e52ade Mon Sep 17 00:00:00 2001 From: vagudets Date: Wed, 10 Jan 2024 12:59:22 +0100 Subject: [PATCH 1/6] Add new function CST_ChangeDimNames() --- R/CST_ChangeDimNames.R | 74 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 R/CST_ChangeDimNames.R diff --git a/R/CST_ChangeDimNames.R b/R/CST_ChangeDimNames.R new file mode 100644 index 00000000..503b67aa --- /dev/null +++ b/R/CST_ChangeDimNames.R @@ -0,0 +1,74 @@ +#'Change the name of one or more dimensions for an object of class s2dv_cube +#' +#'Change the names of the dimensions specified in 'original_names' to the names +#'in 'new_names'. The coordinate names and the dimensions of any attributes +#'are also modified accordingly. +#' +#'@author Agudetse Roures Victoria, \email{victoria.agudetse@bsc.es} +#' +#'@param data An object of class \code{s2dv_cube} whose dimension names +#' should be changed. +#'@param original_names A single character string or a vector indicating the +#' dimensions to be renamed. +#'@param new_names A single character string or a vector indicating the new +#' dimension names, in the same order as the dimensions in 'original_names'. +#' +#'@return An object of class \code{s2dv_cube} with similar data, coordinates and +#'attributes as the \code{data} input, but with modified dimension names. +#' +#'@examples +#'#Example with sample data: +#'# Check original dimensions and coordinates +#'lonlat_temp$exp$dims +#'names(lonlat_temp$exp$coords) +#'dim(lonlat_temp$exp$attrs$Dates) +#'# Change 'dataset' to 'dat' and 'ftime' to 'time' +#'exp <- CST_ChangeDimNames(lonlat_temp$exp, +#' original_names = c("dataset", "ftime"), +#' new_names = c("dat", "time")) +#'# Check new dimensions and coordinates +#'exp$dims +#'names(exp$coords) +#'dim(lonlat_temp$exp$attrs$Dates) +#' +#'@export +CST_ChangeDimNames <- function(data, original_names, new_names) { + if (!inherits(data, "s2dv_cube")) { + stop("Parameter 'data' must be an object of class 's2dv_cube'") + } + if (!(length(original_names) == length(new_names))) { + stop("The number of dimension names in 'new_names' must be the same + as in 'original_names'") + } + if (!all(original_names %in% names(data$dims))) { + stop("Some of the dimensions in 'original_names' could not be found in + 'data'") + } + for (index in 1:length(original_names)) { + original_name <- original_names[index] + new_name <- new_names[index] + # Step 1: Change dims and data + names(data$dims)[which(names(data$dims) == original_name)] <- new_name + dim(data$data) <- data$dims + # Step 2: Change coords + names(data$coords)[which(names(data$coords) == original_name)] <- new_name + # Step 3: Change attrs + # 3.1 - Dates + if (original_name %in% names(dim(data$attrs$Dates))) { + names(dim(data$attrs$Dates))[which(names(dim(data$attrs$Dates)) + == original_name)] <- new_name + } + # 3.2 - Variable metadata + if (original_name %in% names(data$attrs$Variable$metadata)) { + names(data$attrs$Variable$metadata)[which(names(data$attrs$Variable$metadata) + == original_name)] <- new_name + } + # 3.3 - Source files + if (original_name %in% names(dim(data$attrs$source_files))) { + names(dim(data$attrs$source_files))[which(names(dim(data$attrs$source_files)) + == original_name)] <- new_name + } + } + return(data) +} + -- GitLab From 16d762d1d3f2c4fcfca3564e9f1a557db651fd33 Mon Sep 17 00:00:00 2001 From: vagudets Date: Wed, 10 Jan 2024 13:23:28 +0100 Subject: [PATCH 2/6] Update DESCRIPTION, fix example --- DESCRIPTION | 2 +- R/CST_ChangeDimNames.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3af5dcb1..4e41770d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -90,5 +90,5 @@ VignetteBuilder: knitr License: GPL-3 Encoding: UTF-8 LazyData: true -RoxygenNote: 7.2.0 +RoxygenNote: 7.2.3 Config/testthat/edition: 3 diff --git a/R/CST_ChangeDimNames.R b/R/CST_ChangeDimNames.R index 503b67aa..a36f42a3 100644 --- a/R/CST_ChangeDimNames.R +++ b/R/CST_ChangeDimNames.R @@ -29,7 +29,7 @@ #'# Check new dimensions and coordinates #'exp$dims #'names(exp$coords) -#'dim(lonlat_temp$exp$attrs$Dates) +#'dim(exp$attrs$Dates) #' #'@export CST_ChangeDimNames <- function(data, original_names, new_names) { -- GitLab From 897035a01258146107b3d1df330e23d31d3478b3 Mon Sep 17 00:00:00 2001 From: vagudets Date: Wed, 10 Jan 2024 17:00:06 +0100 Subject: [PATCH 3/6] Improve efficiency, add modification of attributes, add dots to error messages --- R/CST_ChangeDimNames.R | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/R/CST_ChangeDimNames.R b/R/CST_ChangeDimNames.R index a36f42a3..99347b00 100644 --- a/R/CST_ChangeDimNames.R +++ b/R/CST_ChangeDimNames.R @@ -34,22 +34,26 @@ #'@export CST_ChangeDimNames <- function(data, original_names, new_names) { if (!inherits(data, "s2dv_cube")) { - stop("Parameter 'data' must be an object of class 's2dv_cube'") + stop("Parameter 'data' must be an object of class 's2dv_cube'.") } if (!(length(original_names) == length(new_names))) { stop("The number of dimension names in 'new_names' must be the same - as in 'original_names'") + as in 'original_names'.") } if (!all(original_names %in% names(data$dims))) { stop("Some of the dimensions in 'original_names' could not be found in - 'data'") + 'data'.") } for (index in 1:length(original_names)) { original_name <- original_names[index] new_name <- new_names[index] - # Step 1: Change dims and data + # Step 1: Change dims names(data$dims)[which(names(data$dims) == original_name)] <- new_name - dim(data$data) <- data$dims + # dim(data$data) <- data$dims + # ## TODO: Improve code + # if !(is.null(attributes(data$data)$dimensions)) { + # attributes(data$data)$dimensions <- names(data$dims) + # } # Step 2: Change coords names(data$coords)[which(names(data$coords) == original_name)] <- new_name # Step 3: Change attrs @@ -69,6 +73,13 @@ CST_ChangeDimNames <- function(data, original_names, new_names) { == original_name)] <- new_name } } + # Change data dimnames after renaming all dimensions + dim(data$data) <- data$dims + if (!is.null(attributes(data$data)$dimensions)) { + attributes(data$data)$dimensions <- names(data$dims) + } + # Change $Dates 'dim' attribute + attr(attributes(data$attrs$Dates)$dim, "names") <- names(dim(data$attrs$Dates)) return(data) } -- GitLab From d66509df44d3d45458cda54be862a78a6641361a Mon Sep 17 00:00:00 2001 From: vagudets Date: Wed, 10 Jan 2024 17:00:48 +0100 Subject: [PATCH 4/6] update function --- R/CST_ChangeDimNames.R | 5 ----- 1 file changed, 5 deletions(-) diff --git a/R/CST_ChangeDimNames.R b/R/CST_ChangeDimNames.R index 99347b00..876f5183 100644 --- a/R/CST_ChangeDimNames.R +++ b/R/CST_ChangeDimNames.R @@ -49,11 +49,6 @@ CST_ChangeDimNames <- function(data, original_names, new_names) { new_name <- new_names[index] # Step 1: Change dims names(data$dims)[which(names(data$dims) == original_name)] <- new_name - # dim(data$data) <- data$dims - # ## TODO: Improve code - # if !(is.null(attributes(data$data)$dimensions)) { - # attributes(data$data)$dimensions <- names(data$dims) - # } # Step 2: Change coords names(data$coords)[which(names(data$coords) == original_name)] <- new_name # Step 3: Change attrs -- GitLab From 93544eb67d98e1b4e88ec2db319b56df23a7f247 Mon Sep 17 00:00:00 2001 From: vagudets Date: Wed, 10 Jan 2024 17:03:22 +0100 Subject: [PATCH 5/6] Add checks for 'original_names' and 'new_names' parameters --- R/CST_ChangeDimNames.R | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/R/CST_ChangeDimNames.R b/R/CST_ChangeDimNames.R index 876f5183..1c79890e 100644 --- a/R/CST_ChangeDimNames.R +++ b/R/CST_ChangeDimNames.R @@ -36,6 +36,15 @@ CST_ChangeDimNames <- function(data, original_names, new_names) { if (!inherits(data, "s2dv_cube")) { stop("Parameter 'data' must be an object of class 's2dv_cube'.") } + if (!is.character(original_names)) { + stop("Parameter 'original_names' must be a character string or a + vector of character strings.") + } + if (!is.character(new_names)) { + stop("Parameter 'new_names' must be a character string or a + vector of character strings.") + } + if (!(length(original_names) == length(new_names))) { stop("The number of dimension names in 'new_names' must be the same as in 'original_names'.") -- GitLab From 90894e1a2171e0bcbf01c6bc97bf8c2a1098de0f Mon Sep 17 00:00:00 2001 From: Eva Rifa Date: Thu, 11 Jan 2024 09:24:43 +0100 Subject: [PATCH 6/6] Add unit test, add few style spaces and update NAMESPACE. --- NAMESPACE | 1 + R/CST_ChangeDimNames.R | 18 ++--- man/CST_ChangeDimNames.Rd | 46 ++++++++++++ tests/testthat/test-CST_ChangeDimNames.R | 95 ++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 9 deletions(-) create mode 100644 man/CST_ChangeDimNames.Rd create mode 100644 tests/testthat/test-CST_ChangeDimNames.R diff --git a/NAMESPACE b/NAMESPACE index 012f76cf..a03e7c8b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -19,6 +19,7 @@ export(CST_BEI_Weighting) export(CST_BiasCorrection) export(CST_Calibration) export(CST_CategoricalEnsCombination) +export(CST_ChangeDimNames) export(CST_DynBiasCorrection) export(CST_EnsClustering) export(CST_InsertDim) diff --git a/R/CST_ChangeDimNames.R b/R/CST_ChangeDimNames.R index 1c79890e..433039b6 100644 --- a/R/CST_ChangeDimNames.R +++ b/R/CST_ChangeDimNames.R @@ -17,7 +17,7 @@ #'attributes as the \code{data} input, but with modified dimension names. #' #'@examples -#'#Example with sample data: +#'# Example with sample data: #'# Check original dimensions and coordinates #'lonlat_temp$exp$dims #'names(lonlat_temp$exp$coords) @@ -37,21 +37,21 @@ CST_ChangeDimNames <- function(data, original_names, new_names) { stop("Parameter 'data' must be an object of class 's2dv_cube'.") } if (!is.character(original_names)) { - stop("Parameter 'original_names' must be a character string or a - vector of character strings.") + stop("Parameter 'original_names' must be a character string or a ", + "vector of character strings.") } if (!is.character(new_names)) { - stop("Parameter 'new_names' must be a character string or a - vector of character strings.") + stop("Parameter 'new_names' must be a character string or a ", + "vector of character strings.") } if (!(length(original_names) == length(new_names))) { - stop("The number of dimension names in 'new_names' must be the same - as in 'original_names'.") + stop("The number of dimension names in 'new_names' must be the same ", + "as in 'original_names'.") } if (!all(original_names %in% names(data$dims))) { - stop("Some of the dimensions in 'original_names' could not be found in - 'data'.") + stop("Some of the dimensions in 'original_names' could not be found in ", + "'data'.") } for (index in 1:length(original_names)) { original_name <- original_names[index] diff --git a/man/CST_ChangeDimNames.Rd b/man/CST_ChangeDimNames.Rd new file mode 100644 index 00000000..86806be0 --- /dev/null +++ b/man/CST_ChangeDimNames.Rd @@ -0,0 +1,46 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/CST_ChangeDimNames.R +\name{CST_ChangeDimNames} +\alias{CST_ChangeDimNames} +\title{Change the name of one or more dimensions for an object of class s2dv_cube} +\usage{ +CST_ChangeDimNames(data, original_names, new_names) +} +\arguments{ +\item{data}{An object of class \code{s2dv_cube} whose dimension names +should be changed.} + +\item{original_names}{A single character string or a vector indicating the +dimensions to be renamed.} + +\item{new_names}{A single character string or a vector indicating the new +dimension names, in the same order as the dimensions in 'original_names'.} +} +\value{ +An object of class \code{s2dv_cube} with similar data, coordinates and +attributes as the \code{data} input, but with modified dimension names. +} +\description{ +Change the names of the dimensions specified in 'original_names' to the names +in 'new_names'. The coordinate names and the dimensions of any attributes +are also modified accordingly. +} +\examples{ +# Example with sample data: +# Check original dimensions and coordinates +lonlat_temp$exp$dims +names(lonlat_temp$exp$coords) +dim(lonlat_temp$exp$attrs$Dates) +# Change 'dataset' to 'dat' and 'ftime' to 'time' +exp <- CST_ChangeDimNames(lonlat_temp$exp, + original_names = c("dataset", "ftime"), + new_names = c("dat", "time")) +# Check new dimensions and coordinates +exp$dims +names(exp$coords) +dim(exp$attrs$Dates) + +} +\author{ +Agudetse Roures Victoria, \email{victoria.agudetse@bsc.es} +} diff --git a/tests/testthat/test-CST_ChangeDimNames.R b/tests/testthat/test-CST_ChangeDimNames.R new file mode 100644 index 00000000..ceef7375 --- /dev/null +++ b/tests/testthat/test-CST_ChangeDimNames.R @@ -0,0 +1,95 @@ +############################################## +test_that("1. Input checks", { + expect_error( + CST_ChangeDimNames(1), + "Parameter 'data' must be an object of class 's2dv_cube'." + ) + expect_error( + CST_ChangeDimNames(lonlat_prec_st, 1, 'bbb'), + paste0("Parameter 'original_names' must be a character string or a ", + "vector of character strings.") + ) + expect_error( + CST_ChangeDimNames(lonlat_prec_st, 'aaa', 1), + paste0("Parameter 'new_names' must be a character string or a ", + "vector of character strings.") + ) + expect_error( + CST_ChangeDimNames(lonlat_prec_st, 'aaa', c('aaa', 'bbb')), + paste0("The number of dimension names in 'new_names' must be the same ", + "as in 'original_names'.") + ) + expect_error( + CST_ChangeDimNames(lonlat_prec_st, 'aaa', 'bbb'), + paste0("Some of the dimensions in 'original_names' could not be found in ", + "'data'.") + ) +}) +############################################## +test_that("2. Output checks", { + exp <- CST_ChangeDimNames(lonlat_temp_st$exp, + original_names = c("lon", 'ftime', 'sdate'), + new_names = c("lons", 'ftimes', 'sdates')) + # dims + expect_equal( + dim(exp$data), + c(dataset = 1, var = 1, member = 15, sdates = 6, ftimes = 3, lat = 22, lons = 53) + ) + expect_equal( + exp$dims, + dim(exp$data) + ) + expect_equal( + as.vector(exp$data), + as.vector(lonlat_temp_st$exp$data) + ) + # coords + expect_equal( + names(exp$coords), + c("dataset", "var", "member", "sdates", "ftimes", "lat", "lons") + ) + # dim Dates + expect_equal( + dim(exp$attrs$Dates), + c(sdates = 6, ftimes = 3) + ) + # variable metadata + expect_equal( + names(exp$attrs$Variable$metadata), + c("lat", "lons", "ftimes", "tas" ) + ) + # source_files + expect_equal( + dim(exp$attrs$source_files), + c(dataset = 1, var = 1, sdates = 6) + ) + # Dates 'dim' attribute + dat <- CST_ChangeDimNames(lonlat_prec, + original_names = c("lon", 'ftime', 'sdate', 'member'), + new_names = c("lons", 'ftimes', 'sdates', 'members')) + expect_equal( + as.vector(lonlat_prec$data), + as.vector(dat$data) + ) + expect_equal( + attributes(dat$attrs$Dates)$dim, + c(ftimes = 31, sdates = 3) + ) + expect_equal( + attributes(exp$attrs$Dates)$dim, + c(sdates = 6, ftimes = 3) + ) + expect_equal( + as.vector(dat$attrs$Dates), + as.vector(lonlat_prec$attrs$Dates) + ) + # attribute dimensions + expect_equal( + attributes(dat$data)$dimensions, + names(dim(dat$data)) + ) + expect_equal( + attributes(exp$data)$dimensions, + NULL + ) +}) \ No newline at end of file -- GitLab