diff --git a/NAMESPACE b/NAMESPACE index bd962e3950d32688aaf09de65cdce61921755fec..1457c4b441e45a4037f987e684d7fa4f97108667 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -24,6 +24,7 @@ export(PlotVsLTime) export(RMS) export(RMSSS) export(Regression) +export(Reorder) export(Season) export(ToyModel) export(Trend) diff --git a/R/MeanDims.R b/R/MeanDims.R index 2b734cea0d183ca5be3049f93ffe989d72ef4957..aea09c51ca6d72493c753f2ff46afb264c1f9e6c 100644 --- a/R/MeanDims.R +++ b/R/MeanDims.R @@ -20,10 +20,10 @@ #'1.1 - 2015-03 (N. Manubens, \email{nicolau.manubens@@ic3.cat}) - Improved memory usage #'3.0 - 2020-01 (A. Ho, \email{an.ho@bsc.es}) - Preserve dimension names #'@examples -#'a <- array(rnorm(24), dim = c(2, 3, 4)) -#'print(a) -#'print(Mean1Dim(a, 2)) -#'print(MeanListDim(a, c(2, 3))) +#'a <- array(rnorm(24), dim = c(a = 2, b= 3, c = 4)) +#'print(dim(MeanDims(a, 2))) +#'print(dim(MeanDims(a, c(2, 3)))) +#'print(dim(MeanDims(a, c('a', 'b')))) #'@export MeanDims <- function(data, dims, na.rm = TRUE) { diff --git a/R/Reorder.R b/R/Reorder.R new file mode 100644 index 0000000000000000000000000000000000000000..4da21740e3b248e2a6c573014c8584c2882da8ed --- /dev/null +++ b/R/Reorder.R @@ -0,0 +1,88 @@ +#'Reorder the dimension of an array +#' +#'Reorder the dimension order of a multi-dimensional array +#' +#'@param data An array of which the dimension to be reordered. +#'@param posdim An integer indicating the position of the new dimension. +#'@param lendim An integer indicating the length of the new dimension. +#' +#'@return An array which has the same values as parameter 'data' but with +#' different dimension order. +#' +#'@keywords datagen +#'@author History:\cr +#'@examples +#' dat1 <- array(c(1:30), dim = c(dat = 1, sdate = 3, ftime = 2, lon = 5)) +#' print(dim(Reorder(dat1, c(2, 1, 4, 3)))) +#' print(dim(Reorder(dat1, c('sdate', 'dat', 'lon', 'ftime')))) +#' dat2 <- array(c(1:10), dim = c(2, 1, 5)) +#' print(dim(Reorder(dat2, c(2, 1, 3)))) +#'@export +Reorder <- function(data, order) { + + # Check inputs + ## data + if (is.null(data)) { + stop("Parameter 'data' cannot be NULL.") + } + if (!is.array(data)) { + stop("Parameter 'data' must be an array.") + } + + ## order + if (is.null(order)) { + stop("Parameter 'order' cannot be NULL.") + } + if (!is.vector(order) | (is.vector(order) & !is.numeric(order) & !is.character(order))) { + stop("Parameter 'order' must be a vector of numeric or character string.") + } + if (is.numeric(order)) { + if (any(order < 1) | any(order %% 1 != 0)) { + stop("Parameter 'order' must be positive integers.") + } else if (any(order > length(dim(data)))) { + stop("Parameter 'order' exceeds the dimension length of parameter 'data'.") + } + } + if (is.character(order)) { + if (!all(order %in% names(dim(data)))) { + stop("Parameter 'order' do not match the dimension names of parameter 'data'.") + } + } + if (length(order) != length(dim(data))) { + stop(paste0("The length of parameter 'order' should be the same with the ", + "dimension length of parameter 'data'.")) + } + + + + ############################### + # Reorder + + ## If order is character string, find the indices + if (is.character(order)) { + tmp <- rep(0, length(order)) + for (i in 1:length(order)) { + tmp[i] <- which(names(dim(data)) == order[i]) + } + order <- tmp + } + + ## reorder + old_dims <- dim(data) + attr_bk <- attributes(data) + if ('dim' %in% names(attr_bk)) { + attr_bk[['dim']] <- NULL + } + if (is.numeric(data)) { + data <- aperm(data, order) + } else { + y <- array(1:length(data), dim = dim(data)) + y <- aperm(y, order) + data <- data[as.vector(y)] + } + dim(data) <- old_dims[order] + attributes(data) <- c(attributes(data), attr_bk) + data +} + + diff --git a/man/MeanDims.Rd b/man/MeanDims.Rd index bab7e83029d71444ad43d18435c2e2f291d5782e..f1c05bd99571bf34f6ffce0daa0a4cc311cf6892 100644 --- a/man/MeanDims.Rd +++ b/man/MeanDims.Rd @@ -25,10 +25,10 @@ This function returns the mean of an array along a set of dimensions and preserves the dimension names if it has. } \examples{ -a <- array(rnorm(24), dim = c(2, 3, 4)) -print(a) -print(Mean1Dim(a, 2)) -print(MeanListDim(a, c(2, 3))) +a <- array(rnorm(24), dim = c(a = 2, b= 3, c = 4)) +print(dim(MeanDims(a, 2))) +print(dim(MeanDims(a, c(2, 3)))) +print(dim(MeanDims(a, c('a', 'b')))) } \author{ History:\cr diff --git a/man/Reorder.Rd b/man/Reorder.Rd new file mode 100644 index 0000000000000000000000000000000000000000..6b44810364f53b92605d25f43de04134c71730e3 --- /dev/null +++ b/man/Reorder.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Reorder.R +\name{Reorder} +\alias{Reorder} +\title{Reorder the dimension of an array} +\usage{ +Reorder(data, order) +} +\arguments{ +\item{data}{An array of which the dimension to be reordered.} + +\item{posdim}{An integer indicating the position of the new dimension.} + +\item{lendim}{An integer indicating the length of the new dimension.} +} +\value{ +An array which has the same values as parameter 'data' but with + different dimension order. +} +\description{ +Reorder the dimension order of a multi-dimensional array +} +\examples{ + dat1 <- array(c(1:30), dim = c(dat = 1, sdate = 3, ftime = 2, lon = 5)) + print(dim(Reorder(dat1, c(2, 1, 4, 3)))) + print(dim(Reorder(dat1, c('sdate', 'dat', 'lon', 'ftime')))) + dat2 <- array(c(1:10), dim = c(2, 1, 5)) + print(dim(Reorder(dat2, c(2, 1, 3)))) +} +\author{ +History:\cr +} +\keyword{datagen} + diff --git a/tests/testthat/test-Reorder.R b/tests/testthat/test-Reorder.R new file mode 100644 index 0000000000000000000000000000000000000000..6cc799b950c1f01b3dcc9b12259a595671b2ec18 --- /dev/null +++ b/tests/testthat/test-Reorder.R @@ -0,0 +1,103 @@ +context("s2dv::Reorder tests") + +############################################## + # dat1 + dat1 <- array(c(1:30), dim = c(dat = 1, sdate = 3, ftime = 2, lon = 5)) + + # dat2 + set.seed(10) + dat2 <- array(rnorm(10), dim = c(2, 1, 5)) + + # dat3 + dat3 <- array(c(1:30), dim = c(dat = 1, 3, ftime = 2, 5)) + +############################################## +test_that("1. Input checks", { + + expect_error( + Reorder(c()), + "Parameter 'data' cannot be NULL." + ) + expect_error( + Reorder(c(1:3)), + "Parameter 'data' must be an array." + ) + expect_error( + Reorder(data = dat1, c()), + "Parameter 'order' cannot be NULL." + ) + expect_error( + Reorder(data = dat1, order = list(1,2)), + "Parameter 'order' must be a vector of numeric or character string." + ) + expect_error( + Reorder(data = dat1, order = TRUE), + "Parameter 'order' must be a vector of numeric or character string." + ) + expect_error( + Reorder(data = dat1, order = c(-1:2)), + "Parameter 'order' must be positive integers." + ) + expect_error( + Reorder(data = dat1, order = c(1:5)), + "Parameter 'order' exceeds the dimension length of parameter 'data'." + ) + expect_error( + Reorder(data = dat1, order = c('dat', 'time')), + "Parameter 'order' do not match the dimension names of parameter 'data'." + ) + expect_error( + Reorder(data = dat1, order = 1:3), + paste0("The length of parameter 'order' should be the same with the ", + "dimension length of parameter 'data'.") + ) + expect_error( + Reorder(data = dat1, order = 'ftime'), + paste0("The length of parameter 'order' should be the same with the ", + "dimension length of parameter 'data'.") + ) + +}) + +############################################## +test_that("2. Output checks: dat1", { + + expect_equal( + dim(Reorder(dat1, c(2,1,4,3))), + c(sdate = 3, dat = 1, lon = 5, ftime = 2) + ) + expect_equal( + dim(Reorder(dat1, c('sdate', 'dat', 'lon', 'ftime'))), + c(sdate = 3, dat = 1, lon = 5, ftime = 2) + ) + expect_equal( + summary(Reorder(dat1, c(2, 1, 4, 3)))[3], + c(Median = 15.50), + tolerance = 0.01 + ) + +}) + + +############################################## +test_that("3. Output checks: dat2", { + + expect_equal( + dim(Reorder(dat2, c(2, 1, 3))), + c(1, 2, 5) + ) + +}) + + +############################################## +test_that("4. Output checks: dat3", { + + expect_equal( + dim(Reorder(dat3, c(4, 2, 1, 3))), + c(5, 3, dat = 1, ftime = 2) + ) + +}) + +##############################################