diff --git a/DESCRIPTION b/DESCRIPTION index c3c0b6be1b1be81562c1d99fef98efaf4b547a5d..cce6a4a387368b71f8877c4033e91dff7566bcde 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,17 +1,22 @@ Package: easyNCDF -Title: Tools to Easily Read/Write NetCDF Files into/from Multidimensional R Arrays -Version: 0.0.7 +Title: Tools to Easily Read/Write NetCDF Files into/from Multidimensional R + Arrays +Version: 0.1.0 Authors@R: c( person("BSC-CNS", role = c("aut", "cph")), - person("Nicolau", "Manubens", , "nicolau.manubens@bsc.es", role = c("aut", "cre"))) -Description: Set of wrappers for the 'ncdf4' package to simplify and extend its reading/writing capabilities into/from multidimensional R arrays. + person("Nicolau", "Manubens", , "nicolau.manubens@bsc.es", role = c("aut")), + person("Nuria", "Perez-Zanon", , "nuria.perez@bsc.es", role = c("ctb", "cre"), comment = c(ORCID = "0000-0001-8568-3071"))) +Description: Set of wrappers for the 'ncdf4' package to simplify and extend its + reading/writing capabilities into/from multidimensional R arrays. Depends: - R (>= 2.14.1) + R (>= 3.2.0) Imports: ncdf4, + ClimProjDiags, abind License: LGPL-3 URL: https://earth.bsc.es/gitlab/es/easyNCDF/wikis/home BugReports: https://earth.bsc.es/gitlab/es/easyNCDF/issues LazyData: true SystemRequirements: netcdf development libraries +RoxygenNote: 5.0.0 diff --git a/NAMESPACE b/NAMESPACE index 9baf4ba8a111978db85cafadba98485dab962144..4a7fb54635fc61ddb84652029967979a82f3a7c7 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,3 +1,11 @@ -exportPattern("^[^\\.]") -import(ncdf4, abind) -importFrom("stats", "setNames") +# Generated by roxygen2: do not edit by hand + +export(ArrayToNc) +export(NcClose) +export(NcOpen) +export(NcReadDims) +export(NcReadVarNames) +export(NcToArray) +import(ncdf4) +importFrom(ClimProjDiags,Subset) +importFrom(stats,setNames) diff --git a/R/ArrayToNc.R b/R/ArrayToNc.R index de3367e7cdbfbeec39b22bbea765dbc45ddca546..68fdc76c3f72c3f7fa8dd0884107a0f61e768f3d 100644 --- a/R/ArrayToNc.R +++ b/R/ArrayToNc.R @@ -1,3 +1,194 @@ +#'Save multidimensional R arrays into NetCDF files +#' +#'@author N. Manubens \email{nicolau.manubens at bsc.es} +#'@description This function takes as input one or a list of multidimensional R arrays and stores them in a NetCDF file, using the \code{ncdf4} package. The full path and name of the resulting file must be specified. Metadata can be attached to the arrays and propagated into the NetCDF file in 3 possible ways:\cr +#' \itemize{ + #' \item{Via the list names if a list of arrays is provided:}{Each name in the input list, corresponding to one multidimensional array, will be interpreted as the name of the variable it contains.\cr +#'E.g:\cr +#' \code{ +#'ArrayToNc(arrays = list(temperature = array(1:9, c(3, 3))), +#' file_path = 'example.nc') +#' } +#' } +#' \item{Via the dimension names of each provided array:}{The dimension names of each of the provided arrays will be interpreted as names for the dimensions of the NetCDF files. Read further for special dimension names that will trigger special behaviours, such as 'time' and 'var'.\cr +#'E.g:\cr +#' \code{ +#'temperature <- array(rnorm(100 * 50 * 10), dim = c(100, 50, 10)) +#'names(dim(temperature)) <- c('longitude', 'latitude', 'time') +#'ArrayToNc(list(temperature = temperature), file_path = 'example.nc') +#' } +#' } +#' \item{Via the attribute 'variables' of each provided array:}{The arrays can be provided with metadata in an attribute named 'variables', which is expected to be a named list of named lists, where the names of the container list are the names of the variables present in the provided array, and where each sub-list contains metadata for each of the variables. The attribute names and values supported in the sub-lists must follow the same format the package \code{ncdf4} uses to represent the NetCDF file headers.\cr +#'E.g:\cr +#' \code{ +#'a <- array(1:400, dim = c(5, 10, 4, 2)) +#'metadata <- list( +#' tos = list(addOffset = 100, +#' scaleFact = 10, +#' dim = list(list(name = 'time', +#' unlim = FALSE))) +#' ) +#'attr(a, 'variables') <- metadata +#'names(dim(a)) <- c('lat', 'lon', 'time', 'var') +#'ArrayToNc(a, 'tmp.nc') +#' } +#' } +#' } +#'The special dimension names are 'var'/'variable' and 'time'.\cr +#'If a dimension is named 'var' or 'variable', \code{ArrayToNc} will interpret each array entry along such dimension corresponds to a separate new variable, hence will create a new variable inside the NetCDF file and will use it to store all the data in the provided array for the corresponding entry along the 'var'/'variable' dimension.\cr +#'If a dimension is named 'time', by default it will be interpreted and built as an unlimited dimension. The 'time' dimension must be the last dimension of the array (the right-most). If a 'var'/'variable' dimension is present, the 'time' dimension can be also placed on its left (i.e. the one before the last dimension). The default behaviour of creating the 'time' as unlimited dimension can be disabled by setting manually the attribute \code{unlim = FALSE}, as shown in the previous example.\cr\cr +#'\code{a2nc} is an alias of \code{ArrayToNc}. +#' +#'@param arrays One or a list of multidimensional data arrays. The list can be provided with names, which will be interpreted as variable names. The arrays can be provided with dimension names. The arrays can be provided with metadata in the attribute 'variables' (read section Description for details). +#'@param file_path Path and name of the NetCDF file to be created. +#' +#'@return This function returns NULL. +#' +#'@import ncdf4 +#'@importFrom ClimProjDiags Subset +#'@importFrom stats setNames +#'@examples +#' \dontrun{ +#'# Minimal use case +#'ArrayToNc(array(1:9, c(3, 3)), 'tmp.nc') +#'# Works with arrays of any number of dimensions +#'ArrayToNc(array(1:27, c(3, 3, 3)), 'tmp.nc') +#' +#'# Arrays can also be provided in [named] lists +#'ArrayToNc(list(tos = array(1:27, c(3, 3, 3))), 'tmp.nc') +#' +#'# Or with dimension names +#'# 'var' dimension name will generate multiple variables in the +#'# resulting NetCDF file +#'a <- array(1:27, dim = c(3, 3, 3)) +#'names(dim(a)) <- c('lon', 'lat', 'var') +#'ArrayToNc(a, 'tmp.nc') +#' +#'# 'variable' as dimension name will do the same +#'a <- array(1:27, dim = c(3, 3, 3)) +#'names(dim(a)) <- c('lon', 'lat', 'variable') +#'ArrayToNc(a, 'tmp.nc') +#' +#'# The 'time' dimension will be built as unlimited dimension, by default +#'a <- array(1:1600, dim = c(10, 20, 4, 2)) +#'names(dim(a)) <- c('lat', 'lon', 'time', 'var') +#'ArrayToNc(a, 'tmp.nc') +#' +#'# The dimension 'var'/'variable' can be in any position and can have any length +#'a <- array(1:1600, dim = c(10, 20, 4, 2)) +#'names(dim(a)) <- c('lat', 'var', 'lon', 'time') +#'ArrayToNc(a, 'tmp.nc') +#' +#'# Multiple arrays can be provided in a list +#'a <- array(1:400, dim = c(5, 10, 4, 2)) +#'names(dim(a)) <- c('lat', 'lon', 'time', 'var') +#'ArrayToNc(list(a, a), 'tmp.nc') +#' +#'# If no dimension names are given to an array, new names will be automatically +#'# generated +#'a <- array(1:400, dim = c(5, 10, 4, 2)) +#'b <- array(1:400, dim = c(5, 11, 4, 2)) +#'names(dim(a)) <- c('lat', 'lon', 'time', 'var') +#'ArrayToNc(list(a, b), 'tmp.nc') +#' +#'# Metadata can be provided for each variable in each array, via the +#'# attribute 'variables'. In this example the metadata is empty. +#'a <- array(1:400, dim = c(5, 10, 4, 2)) +#'metadata <- list( +#' tos = list(), +#' tas = list()) +#'attr(a, 'variables') <- metadata +#'names(dim(a)) <- c('lat', 'lon', 'time', 'var') +#'ArrayToNc(a, 'tmp.nc') +#' +#'# Variable names can be manually specified +#'a <- array(1:400, dim = c(5, 10, 4, 2)) +#'metadata <- list( +#' tos = list(name = 'name1'), +#' tas = list(name = 'name2')) +#'attr(a, 'variables') <- metadata +#'names(dim(a)) <- c('lat', 'lon', 'time', 'var') +#'ArrayToNc(a, 'tmp.nc') +#'# Units can be specified +#'a <- array(1:400, dim = c(5, 10, 4, 2)) +#'metadata <- list( +#' tos = list(units = 'K'), +#' tas = list(units = 'K')) +#'attr(a, 'variables') <- metadata +#'names(dim(a)) <- c('lat', 'lon', 'time', 'var') +#'ArrayToNc(a, 'tmp.nc') +#' +#'# addOffset and scaleFactor can be specified +#'a <- array(1:400, dim = c(5, 10, 4, 2)) +#'metadata <- list( +#' tos = list(addOffset = 100, +#' scaleFact = 10), +#' tas = list(addOffset = 100, +#' scaleFact = 10)) +#'attr(a, 'variables') <- metadata +#'names(dim(a)) <- c('lat', 'lon', 'time', 'var') +#'ArrayToNc(a, 'tmp.nc') +#' +#'# Global attributes can be specified +#'a <- array(rnorm(10), dim = c(a = 5, b = 2)) +#'attrs <- list(variables = +#' list(tas = list(var_attr_1 = 'test_1_var', +#' var_attr_2 = 2)), +#' global_attrs = list(global_attr_name_1 = 'test_1_global', +#' global_attr_name_2 = 2)) +#'attributes(a) <- c(attributes(a), attrs) +#'ArrayToNc(a, 'tmp.nc') +#' +#'# Unlimited dimensions can be manually created +#'a <- array(1:400, dim = c(5, 10, 4, 2)) +#'metadata <- list( +#' tos = list(addOffset = 100, +#' scaleFact = 10, +#' dim = list(list(name = 'unlimited', +#' unlim = TRUE))), +#' tas = list(addOffset = 100, +#' scaleFact = 10, +#' dim = list(list(name = 'unlimited', +#' unlim = TRUE)))) +#'attr(a, 'variables') <- metadata +#'names(dim(a)) <- c('lat', 'lon', 'unlimited', 'var') +#'ArrayToNc(a, 'tmp.nc') +#' +#'# A 'time' dimension can be built without it necessarily being unlimited +#'a <- array(1:400, dim = c(5, 10, 4, 2)) +#'metadata <- list( +#' tos = list(addOffset = 100, +#' scaleFact = 10, +#' dim = list(list(name = 'time', +#' unlim = FALSE))), +#' tas = list(addOffset = 100, +#' scaleFact = 10, +#' dim = list(list(name = 'time', +#' unlim = FALSE)))) +#'attr(a, 'variables') <- metadata +#'names(dim(a)) <- c('lat', 'lon', 'time', 'var') +#'ArrayToNc(a, 'tmp.nc') +#' +# Multiple arrays with data for multiple variables can be saved into a +# NetCDF file at once. +#'tos <- array(1:400, dim = c(5, 10, 4)) +#'metadata <- list(tos = list(units = 'K')) +#'attr(tos, 'variables') <- metadata +#'names(dim(tos)) <- c('lat', 'lon', 'time') +#'lon <- seq(0, 360 - 360 / 10, length.out = 10) +#'dim(lon) <- length(lon) +#'metadata <- list(lon = list(units = 'degrees_east')) +#'attr(lon, 'variables') <- metadata +#'names(dim(lon)) <- 'lon' +#'lat <- seq(-90, 90, length.out = 5) +#'dim(lat) <- length(lat) +#'metadata <- list(lat = list(units = 'degrees_north')) +#'attr(lat, 'variables') <- metadata +#'names(dim(lat)) <- 'lat' +#'ArrayToNc(list(tos, lon, lat), 'tmp.nc') +#'} +#' +#'@export ArrayToNc <- function(arrays, file_path) { # Check parameter arrays. if (is.array(arrays)) { @@ -335,5 +526,5 @@ ArrayToNc <- function(arrays, file_path) { nc_close(ncdf_object) invisible(NULL) } - +#' @rdname ArrayToNc a2nc <- ArrayToNc diff --git a/R/NcClose.R b/R/NcClose.R index 309b78ef931c9c28874a75b71434f1011356563d..bd46c4cdd446eec05d19cf16779cf4c0a412c460 100644 --- a/R/NcClose.R +++ b/R/NcClose.R @@ -1,3 +1,31 @@ +#'Close a NEtCDF File +#' +#'@author N. Manubens \email{nicolau.manubens at bsc.es} +#' +#'@description Close a \code{ncdf4} open connection to a file. +#' +#'@param file_object NetCDF object as returned by \code{ncdf4::nc_open}. +#' +#'@return The result of \code{ncdf4::nc_close}. +#' +#'@import ncdf4 +#'@examples +#'# Create an array from R +#'file_path <- tempfile(fileext = '.nc') +#'a <- array(1:9, dim = c(member = 3, time = 3)) +#'# Store into a NetCDF twice, as two different variables +#'ArrayToNc(list(var_1 = a, var_2 = a + 1), file_path) +#'# Read the dimensions and variables in the created file +#'fnc <- NcOpen(file_path) +#'fnc_dims <- NcReadDims(fnc) +#'var_names <- NcReadVarNames(fnc) +#'# Read the two variables from the file into an R array +#'a_from_file <- NcToArray(fnc, vars_to_read = var_names) +#'NcClose(fnc) +#'# Check the obtained array matches the original array +#'print(a) +#'print(a_from_file[1, , ]) +#'@export NcClose <- function(file_object) { result <- NULL diff --git a/R/NcOpen.R b/R/NcOpen.R index 7f7e64dcaf47448ea5454866464dab9b3fb692c9..0cd6ec23ccd55116d2ed7864f71fe8b902ed2a3f 100644 --- a/R/NcOpen.R +++ b/R/NcOpen.R @@ -1,3 +1,32 @@ +#'Open a NetCDF File +#' +#'@author N. Manubens \email{nicolau.manubens at bsc.es} +#' +#'@description Silently opens a NetCDF file with \code{ncdf4::nc_open}. Returns NULL on failure. +#' +#'@param file_path Character string with the path to the file to be opened. +#' +#'@import ncdf4 +#' +#'@return A NetCDF object as returned by \code{ncdf4::nc_open} or NULL on failure. +#'@examples +#'# Create an array from R +#'file_path <- tempfile(fileext = '.nc') +#'a <- array(1:9, dim = c(member = 3, time = 3)) +#'# Store into a NetCDF twice, as two different variables +#'ArrayToNc(list(var_1 = a, var_2 = a + 1), file_path) +#'# Read the dimensions and variables in the created file +#'fnc <- NcOpen(file_path) +#'fnc_dims <- NcReadDims(fnc) +#'var_names <- NcReadVarNames(fnc) +#'# Read the two variables from the file into an R array +#'a_from_file <- NcToArray(fnc, vars_to_read = var_names) +#'NcClose(fnc) +#'# Check the obtained array matches the original array +#'print(a) +#'print(a_from_file[1, , ]) +#' +#'@export NcOpen <- function(file_path) { result <- NULL diff --git a/R/NcReadDims.R b/R/NcReadDims.R index 5d2d87cd395b7c13a6c569ca3b2567064bb75e82..9cdff4402a50da39beb66d469157f6023769802e 100644 --- a/R/NcReadDims.R +++ b/R/NcReadDims.R @@ -1,3 +1,30 @@ +#'Read Dimensions of a NetCDF File +#' +#'@author N. Manubens \email{nicolau.manubens at bsc.es} +#'@description Reads the dimension names and sizes of a set of variables in a NetCDF file, using the package \code{ncdf4}. The different variables in the file are considered to be stored along a dimension called 'var', so reading the dimensions of a variable 'foo' with dimensions 'lat' and 'lon' would result in a vector with the format c('var' = 1, 'lat' = n_lats, 'lon' = n_lons). +#' +#'@param file_to_read Path to the file to be read or a NetCDF object as returned by \code{easyNCDF::NcOpen} or \code{ncdf4::nc_open}. +#'@param var_names Vector of character strings with the names of the variables which to read the dimensions for. If multiple variables are requested, their dimensions will be merged and returned in a single vector. +#' +#'@import ncdf4 +#'@examples +#'# Create an array from R +#'file_path <- tempfile(fileext = '.nc') +#'a <- array(1:9, dim = c(member = 3, time = 3)) +#'# Store into a NetCDF twice, as two different variables +#'ArrayToNc(list(var_1 = a, var_2 = a + 1), file_path) +#'# Read the dimensions and variables in the created file +#'fnc <- NcOpen(file_path) +#'fnc_dims <- NcReadDims(fnc) +#'var_names <- NcReadVarNames(fnc) +#'# Read the two variables from the file into an R array +#'a_from_file <- NcToArray(fnc, vars_to_read = var_names) +#'NcClose(fnc) +#'# Check the obtained array matches the original array +#'print(a) +#'print(a_from_file[1, , ]) +#' +#'@export NcReadDims <- function(file_to_read, var_names = NULL) { file_opener <- nc_open file_closer <- nc_close diff --git a/R/NcReadVarNames.R b/R/NcReadVarNames.R index ccab8bc9d758a8814d00b67c83832b79a4b82d27..0af89590f685c635a5677a7c1c8a8e1310a13cf6 100644 --- a/R/NcReadVarNames.R +++ b/R/NcReadVarNames.R @@ -1,3 +1,30 @@ +#'Read Names of Variables in a NetCDF File +#' +#'@author N. Manubens \email{nicolau.manubens at bsc.es} +#' +#'@description Reads the names of the variables in a NetCDF file and returns them as a vector of character strings. +#' +#'@param file_to_read Path to the file to be read or a NetCDF object as returned by \code{easyNCDF::NcOpen} or \code{ncdf4::nc_open}. +#' +#'@return Vector of character strings with the names of the variables in the NetCDF file. +#'@examples +#'# Create an array from R +#'file_path <- tempfile(fileext = '.nc') +#'a <- array(1:9, dim = c(member = 3, time = 3)) +#'# Store into a NetCDF twice, as two different variables +#'ArrayToNc(list(var_1 = a, var_2 = a + 1), file_path) +#'# Read the dimensions and variables in the created file +#'fnc <- NcOpen(file_path) +#'fnc_dims <- NcReadDims(fnc) +#'var_names <- NcReadVarNames(fnc) +#'# Read the two variables from the file into an R array +#'a_from_file <- NcToArray(fnc, vars_to_read = var_names) +#'NcClose(fnc) +#'# Check the obtained array matches the original array +#'print(a) +#'print(a_from_file[1, , ]) +#' +#'@export NcReadVarNames <- function(file_to_read) { file_opener <- nc_open file_closer <- nc_close diff --git a/R/NcToArray.R b/R/NcToArray.R index 4ad00eae134571b30e41633b20b86181d8951353..0fc047ed2b2a08013a1203120e14e4823e53dcb5 100644 --- a/R/NcToArray.R +++ b/R/NcToArray.R @@ -1,3 +1,49 @@ +#'Read Names of Variables in a NetCDF File +#' +#'@author N. Manubens, \email{nicolau.manubens at bsc.es} +#' +#'@description Reads the names of the variables in a NetCDF file and returns them as a vector of character strings. +#' +#'@param file_to_read Path to the file to be read or a NetCDF object as returned by \code{easyNCDF::NcOpen} or \code{ncdf4::nc_open}. +#'@param dim_indices Named list with numeric vectors of indices to take for each dimension. The names should correspond to the dimension names which to take the indices for. Non-consecutive indices can be specified. If \code{expect_all_indices = FALSE} (default), it is not mandatory to specify the indices for all (or even any of) the dimensions. In that case all the indices along such dimensions will be read in. If \code{expect_all_indices = TRUE}, then indices for all the dimensions have to be specified for the function to return a data array. In that case, \code{NA} can be used to request all indices for a dimension if desired. +#'\cr\cr +#'Since this function considers the variables in a NetCDF file are stored along a 'var' dimension, indices for the (actually non-existing) 'var'/'variable' dimension can be specified. They can be specified in 3 ways:\cr +#' - A vector of numeric indices: e.g. \code{list(var = c(1, 3, 5))} to take the 1st, 3rd and 5th found variables.\cr +#' - A vector of character strings with variable names: e.g. \code{list(var = c('foo', 'bar'))}.\cr +#' - A list of vectors with numeric indices or character strings: e.g. \code{list(var = list(c(1, 3, 'foo'), c(2, 'bar')))}\cr +#'Vectors with combined numeric indices and character strings are accepted.\cr +#'Whereas the first two options will return a single extended array with the merged variables, the second option will return a list with an array for each requested variable. +#' +#'@param vars_to_read This parameter is a shortcut to (and has less priority than) specifying the requested variable names via \code{dim_indices = list(var = ...)}. It is useful when all the indices for all the requested variables have to be taken, so the parameter \code{dim_indices} can be skipped, but still only a specific variable or set of variables have to be taken. Check the documentation for the parameter \code{dim_indices} to see the three possible ways to specify this parameter. +#' +#'@param drop_var_dim Whether to drop the 'var' dimension this function assumes (read description). If multiple variables are requested in a vector and \code{unlist = TRUE}, the drop won't be performed (not possible). +#' +#'@param unlist Whether to merge the resulting array variables into a single array if possible (default) or not. Otherwise a list with as many arrays as requested variables is returned. +#' +#'@param expect_all_indices Whether the function should stop if indices are not provided for all the dimensions of any of the requested variables (TRUE) rather than assuming that all the indices are requested for the unspecified dimensions (FALSE). By default the later is done (FALSE). +#' +#'@param allow_out_of_range Whether to allow indices out of range (simply disregard them) or to stop if indices out of range are found. +#' +#'@return Vector of character strings with the names of the variables in the NetCDF file. +#' +#'@examples +#'# Create an array from R +#'file_path <- tempfile(fileext = '.nc') +#'a <- array(1:9, dim = c(member = 3, time = 3)) +#'# Store into a NetCDF twice, as two different variables +#'ArrayToNc(list(var_1 = a, var_2 = a + 1), file_path) +#'# Read the dimensions and variables in the created file +#'fnc <- NcOpen(file_path) +#'fnc_dims <- NcReadDims(fnc) +#'var_names <- NcReadVarNames(fnc) +#'# Read the two variables from the file into an R array +#'a_from_file <- NcToArray(fnc, vars_to_read = var_names) +#'NcClose(fnc) +#'# Check the obtained array matches the original array +#'print(a) +#'print(a_from_file[1, , ]) +#' +#'@export NcToArray <- function(file_to_read, dim_indices = NULL, vars_to_read = NULL, drop_var_dim = FALSE, unlist = TRUE, expect_all_indices = FALSE, allow_out_of_range = TRUE) { @@ -203,7 +249,7 @@ NcToArray <- function(file_to_read, dim_indices = NULL, vars_to_read = NULL, (length(file_object[['var']][[var_name]][['dim']]) > 1)) { start <- c(1, start) count <- c(-1, count) - ## original_ncvar_get_inner <- ncdf4:::ncvar_get_inner + ## original_ncvar_get_inner <- ncvar_get_inner ## assignInNamespace('ncvar_get_inner', .ncvar_get_inner, 'ncdf4') } var_result <- do.call('[', c(list(ncvar_get(file_object, var_name, start, count, collapse_degen = FALSE)), diff --git a/R/Subset.R b/R/Subset.R deleted file mode 100644 index d10629c59dea260cc4d5b9e37dcb14706aae6cc3..0000000000000000000000000000000000000000 --- a/R/Subset.R +++ /dev/null @@ -1,93 +0,0 @@ -Subset <- function(x, along, indices, drop = FALSE) { - # Check x - if (!is.array(x)) { - stop("Input array 'x' must be a numeric array.") - } - - # Take the input array dimension names - dim_names <- attr(x, 'dimensions') - if (!is.character(dim_names)) { - dim_names <- names(dim(x)) - } - if (!is.character(dim_names)) { - if (any(sapply(along, is.character))) { - stop("The input array 'x' doesn't have labels for the dimensions but the parameter 'along' contains dimension names.") - } - } - - # Check along - if (any(sapply(along, function(x) !is.numeric(x) && !is.character(x)))) { - stop("All provided dimension indices in 'along' must be integers or character strings.") - } - if (any(sapply(along, is.character))) { - req_dimnames <- along[which(sapply(along, is.character))] - if (length(unique(req_dimnames)) < length(req_dimnames)) { - stop("The parameter 'along' must not contain repeated dimension names.") - } - along[which(sapply(along, is.character))] <- match(req_dimnames, dim_names) - if (any(is.na(along))) { - stop("Could not match all dimension names in 'indices' with dimension names in input array 'x'.") - } - along <- as.numeric(along) - } - - # Check indices - if (!is.list(indices)) { - indices <- list(indices) - } - - # Check parameter drop - dims_to_drop <- c() - if (is.character(drop)) { - if (drop == 'all') { - drop <- TRUE - } else if (any(drop %in% c('selected', 'non-selected', 'none'))) { - if (drop == 'selected') { - dims_to_drop <- along[which(sapply(indices, length) == 1)] - } else if (drop == 'non-selected') { - dims_to_drop <- dim(x) == 1 - dims_to_drop[along] <- FALSE - dims_to_drop <- which(dims_to_drop) - } - drop <- FALSE - } else { - stop("Parameter 'drop' must be one of TRUE, FALSE, 'all', 'selected', 'non-selected', 'none'.") - } - } else if (!is.logical(drop)) { - stop("Parameter 'drop' must be one of TRUE, FALSE, 'all', 'selected', 'non-selected', 'none'.") - } - - # Take the subset - nd <- length(dim(x)) - index <- as.list(rep(TRUE, nd)) - index[along] <- indices - subset <- eval(as.call(c(as.name("["), as.name("x"), index, drop = drop))) - # If dropped all dimensions, need to drop dimnames too - if (is.character(dim_names) && drop == TRUE) { - dim_names_to_remove <- unique(c(along[which(sapply(indices, length) == 1)], - which(dim(x) == 1))) - if (length(dim_names_to_remove) > 0) { - dim_names <- dim_names[-dim_names_to_remove] - } - } - - # Amend the final dimensions and put dimnames and attributes - metadata <- attributes(x) - metadata[['dim']] <- dim(subset) - if (length(dims_to_drop) > 0) { - metadata[['dim']] <- metadata[['dim']][-dims_to_drop] - if (is.character(dim_names)) { - names(metadata[['dim']]) <- dim_names[-dims_to_drop] - metadata[['dimensions']] <- dim_names[-dims_to_drop] - } - if (length(metadata[['dim']]) == 0) { - metadata['dim'] <- list(NULL) - metadata['dimensions'] <- list(NULL) - } - } else if (is.character(dim_names)) { - names(metadata[['dim']]) <- dim_names - metadata[['dimensions']] <- dim_names - } - attributes(subset) <- metadata - subset -} diff --git a/R/Utils.R b/R/Utils.R index fde2c95c2599850b35bb9f56c6c4b63714cf4990..15e56c1a6afc89cb31d14ec49d248f16876e71da 100644 --- a/R/Utils.R +++ b/R/Utils.R @@ -192,13 +192,13 @@ na_array_dims <- dim(array2) na_array_dims[j] <- dim(array1)[j] - dim(array2)[j] na_array <- array(dim = na_array_dims) - array2 <- abind(array2, na_array, along = j) + array2 <- abind::abind(array2, na_array, along = j) names(dim(array2)) <- names(na_array_dims) } else { na_array_dims <- dim(array1) na_array_dims[j] <- dim(array2)[j] - dim(array1)[j] na_array <- array(dim = na_array_dims) - array1 <- abind(array1, na_array, along = j) + array1 <- abind::abind(array1, na_array, along = j) names(dim(array1)) <- names(na_array_dims) } } @@ -209,7 +209,7 @@ stop("The dimension specified in 'along' is not present in the ", "provided arrays.") } - array1 <- abind(array1, array2, along = which(names(dim(array1)) == along)) + array1 <- abind::abind(array1, array2, along = which(names(dim(array1)) == along)) names(dim(array1)) <- names(dim(array2)) } else if (is.null(array1)) { array1 <- array2 diff --git a/easyNCDF-manual.pdf b/easyNCDF-manual.pdf deleted file mode 100644 index 621593b4134b376a16f33b53150f06027b4f1462..0000000000000000000000000000000000000000 Binary files a/easyNCDF-manual.pdf and /dev/null differ diff --git a/man/ArrayToNc.Rd b/man/ArrayToNc.Rd index 7e33ee0de66122a178ff7fdf0a00194270226bec..379137d36c73e9b572149a6d78ca7e34755090a8 100644 --- a/man/ArrayToNc.Rd +++ b/man/ArrayToNc.Rd @@ -1,59 +1,65 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ArrayToNc.R \name{ArrayToNc} \alias{ArrayToNc} \alias{a2nc} \title{Save multidimensional R arrays into NetCDF files} -\description{This function takes as input one or a list of multidimensional R arrays and stores them in a NetCDF file, using the \code{ncdf4} package. The full path and name of the resulting file must be specified. Metadata can be attached to the arrays and propagated into the NetCDF file in 3 possible ways:\cr - \itemize{ - \item{Via the list names if a list of arrays is provided:}{Each name in the input list, corresponding to one multidimensional array, will be interpreted as the name of the variable it contains.\cr +\usage{ +ArrayToNc(arrays, file_path) + +a2nc(arrays, file_path) +} +\arguments{ +\item{arrays}{One or a list of multidimensional data arrays. The list can be provided with names, which will be interpreted as variable names. The arrays can be provided with dimension names. The arrays can be provided with metadata in the attribute 'variables' (read section Description for details).} + +\item{file_path}{Path and name of the NetCDF file to be created.} +} +\value{ +This function returns NULL. +} +\description{ +This function takes as input one or a list of multidimensional R arrays and stores them in a NetCDF file, using the \code{ncdf4} package. The full path and name of the resulting file must be specified. Metadata can be attached to the arrays and propagated into the NetCDF file in 3 possible ways:\cr + \itemize{ + \item{Via the list names if a list of arrays is provided:}{Each name in the input list, corresponding to one multidimensional array, will be interpreted as the name of the variable it contains.\cr E.g:\cr - \code{ + \code{ ArrayToNc(arrays = list(temperature = array(1:9, c(3, 3))), - file_path = 'example.nc') - } - } - \item{Via the dimension names of each provided array:}{The dimension names of each of the provided arrays will be interpreted as names for the dimensions of the NetCDF files. Read further for special dimension names that will trigger special behaviours, such as 'time' and 'var'.\cr + file_path = 'example.nc') + } + } + \item{Via the dimension names of each provided array:}{The dimension names of each of the provided arrays will be interpreted as names for the dimensions of the NetCDF files. Read further for special dimension names that will trigger special behaviours, such as 'time' and 'var'.\cr E.g:\cr - \code{ + \code{ temperature <- array(rnorm(100 * 50 * 10), dim = c(100, 50, 10)) names(dim(temperature)) <- c('longitude', 'latitude', 'time') ArrayToNc(list(temperature = temperature), file_path = 'example.nc') - } - } - \item{Via the attribute 'variables' of each provided array:}{The arrays can be provided with metadata in an attribute named 'variables', which is expected to be a named list of named lists, where the names of the container list are the names of the variables present in the provided array, and where each sub-list contains metadata for each of the variables. The attribute names and values supported in the sub-lists must follow the same format the package \code{ncdf4} uses to represent the NetCDF file headers.\cr + } + } + \item{Via the attribute 'variables' of each provided array:}{The arrays can be provided with metadata in an attribute named 'variables', which is expected to be a named list of named lists, where the names of the container list are the names of the variables present in the provided array, and where each sub-list contains metadata for each of the variables. The attribute names and values supported in the sub-lists must follow the same format the package \code{ncdf4} uses to represent the NetCDF file headers.\cr E.g:\cr - \code{ + \code{ a <- array(1:400, dim = c(5, 10, 4, 2)) metadata <- list( - tos = list(addOffset = 100, - scaleFact = 10, - dim = list(list(name = 'time', - unlim = FALSE))) - ) + tos = list(addOffset = 100, + scaleFact = 10, + dim = list(list(name = 'time', + unlim = FALSE))) + ) attr(a, 'variables') <- metadata names(dim(a)) <- c('lat', 'lon', 'time', 'var') ArrayToNc(a, 'tmp.nc') - } - } - } + } + } + } The special dimension names are 'var'/'variable' and 'time'.\cr If a dimension is named 'var' or 'variable', \code{ArrayToNc} will interpret each array entry along such dimension corresponds to a separate new variable, hence will create a new variable inside the NetCDF file and will use it to store all the data in the provided array for the corresponding entry along the 'var'/'variable' dimension.\cr If a dimension is named 'time', by default it will be interpreted and built as an unlimited dimension. The 'time' dimension must be the last dimension of the array (the right-most). If a 'var'/'variable' dimension is present, the 'time' dimension can be also placed on its left (i.e. the one before the last dimension). The default behaviour of creating the 'time' as unlimited dimension can be disabled by setting manually the attribute \code{unlim = FALSE}, as shown in the previous example.\cr\cr \code{a2nc} is an alias of \code{ArrayToNc}. } -\usage{ -ArrayToNc(arrays, file_path) -a2nc(arrays, file_path) -} -\arguments{ - \item{arrays}{One or a list of multidimensional data arrays. The list can be provided with names, which will be interpreted as variable names. The arrays can be provided with dimension names. The arrays can be provided with metadata in the attribute 'variables' (read section Description for details).} - \item{file_path}{Path and name of the NetCDF file to be created.} -} -\value{This function returns NULL} \examples{ - \dontrun{ + \dontrun{ # Minimal use case ArrayToNc(array(1:9, c(3, 3)), 'tmp.nc') - # Works with arrays of any number of dimensions ArrayToNc(array(1:27, c(3, 3, 3)), 'tmp.nc') @@ -77,16 +83,6 @@ a <- array(1:1600, dim = c(10, 20, 4, 2)) names(dim(a)) <- c('lat', 'lon', 'time', 'var') ArrayToNc(a, 'tmp.nc') -# Putting the 'time' dimension in a position which is not the last, or the one -# right before 'var'/'variable' will crash. Unlimited dimension must be in the -# last position -a <- array(1:1600, dim = c(10, 20, 4, 2)) -names(dim(a)) <- c('time', 'lat', 'lon', 'var') -ArrayToNc(a, 'tmp.nc') -a <- array(1:1600, dim = c(10, 20, 4, 2)) -names(dim(a)) <- c('lat', 'time', 'lon', 'var') -ArrayToNc(a, 'tmp.nc') - # The dimension 'var'/'variable' can be in any position and can have any length a <- array(1:1600, dim = c(10, 20, 4, 2)) names(dim(a)) <- c('lat', 'var', 'lon', 'time') @@ -104,21 +100,12 @@ b <- array(1:400, dim = c(5, 11, 4, 2)) names(dim(a)) <- c('lat', 'lon', 'time', 'var') ArrayToNc(list(a, b), 'tmp.nc') -# If two arrays use a same dimension but their lengths differ, the function -# will crash -a <- array(1:400, dim = c(5, 10, 4, 2)) -b <- array(1:400, dim = c(5, 11, 4, 2)) -names(dim(a)) <- c('lat', 'lon', 'time', 'var') -names(dim(b)) <- c('lat', 'lon', 'time', 'var') -ArrayToNc(list(a, b), 'tmp.nc') - # Metadata can be provided for each variable in each array, via the # attribute 'variables'. In this example the metadata is empty. a <- array(1:400, dim = c(5, 10, 4, 2)) metadata <- list( - tos = list(), - tas = list() - ) + tos = list(), + tas = list()) attr(a, 'variables') <- metadata names(dim(a)) <- c('lat', 'lon', 'time', 'var') ArrayToNc(a, 'tmp.nc') @@ -126,19 +113,16 @@ ArrayToNc(a, 'tmp.nc') # Variable names can be manually specified a <- array(1:400, dim = c(5, 10, 4, 2)) metadata <- list( - tos = list(name = 'name1'), - tas = list(name = 'name2') - ) + tos = list(name = 'name1'), + tas = list(name = 'name2')) attr(a, 'variables') <- metadata names(dim(a)) <- c('lat', 'lon', 'time', 'var') ArrayToNc(a, 'tmp.nc') - # Units can be specified a <- array(1:400, dim = c(5, 10, 4, 2)) metadata <- list( - tos = list(units = 'K'), - tas = list(units = 'K') - ) + tos = list(units = 'K'), + tas = list(units = 'K')) attr(a, 'variables') <- metadata names(dim(a)) <- c('lat', 'lon', 'time', 'var') ArrayToNc(a, 'tmp.nc') @@ -146,38 +130,35 @@ ArrayToNc(a, 'tmp.nc') # addOffset and scaleFactor can be specified a <- array(1:400, dim = c(5, 10, 4, 2)) metadata <- list( - tos = list(addOffset = 100, - scaleFact = 10), - tas = list(addOffset = 100, - scaleFact = 10) - ) + tos = list(addOffset = 100, + scaleFact = 10), + tas = list(addOffset = 100, + scaleFact = 10)) attr(a, 'variables') <- metadata names(dim(a)) <- c('lat', 'lon', 'time', 'var') ArrayToNc(a, 'tmp.nc') # Global attributes can be specified a <- array(rnorm(10), dim = c(a = 5, b = 2)) -attrs <- list(variables = - list(tas = list(var_attr_1 = 'test_1_var', - var_attr_2 = 2)), - global_attrs = list(global_attr_name_1 = 'test_1_global', - global_attr_name_2 = 2) - ) +attrs <- list(variables = + list(tas = list(var_attr_1 = 'test_1_var', + var_attr_2 = 2)), + global_attrs = list(global_attr_name_1 = 'test_1_global', + global_attr_name_2 = 2)) attributes(a) <- c(attributes(a), attrs) ArrayToNc(a, 'tmp.nc') # Unlimited dimensions can be manually created a <- array(1:400, dim = c(5, 10, 4, 2)) metadata <- list( - tos = list(addOffset = 100, - scaleFact = 10, - dim = list(list(name = 'unlimited', - unlim = TRUE))), - tas = list(addOffset = 100, - scaleFact = 10, - dim = list(list(name = 'unlimited', - unlim = TRUE))) - ) + tos = list(addOffset = 100, + scaleFact = 10, + dim = list(list(name = 'unlimited', + unlim = TRUE))), + tas = list(addOffset = 100, + scaleFact = 10, + dim = list(list(name = 'unlimited', + unlim = TRUE)))) attr(a, 'variables') <- metadata names(dim(a)) <- c('lat', 'lon', 'unlimited', 'var') ArrayToNc(a, 'tmp.nc') @@ -185,21 +166,18 @@ ArrayToNc(a, 'tmp.nc') # A 'time' dimension can be built without it necessarily being unlimited a <- array(1:400, dim = c(5, 10, 4, 2)) metadata <- list( - tos = list(addOffset = 100, - scaleFact = 10, - dim = list(list(name = 'time', - unlim = FALSE))), - tas = list(addOffset = 100, - scaleFact = 10, - dim = list(list(name = 'time', - unlim = FALSE))) - ) + tos = list(addOffset = 100, + scaleFact = 10, + dim = list(list(name = 'time', + unlim = FALSE))), + tas = list(addOffset = 100, + scaleFact = 10, + dim = list(list(name = 'time', + unlim = FALSE)))) attr(a, 'variables') <- metadata names(dim(a)) <- c('lat', 'lon', 'time', 'var') ArrayToNc(a, 'tmp.nc') -# Multiple arrays with data for multiple variables can be saved into a -# NetCDF file at once. tos <- array(1:400, dim = c(5, 10, 4)) metadata <- list(tos = list(units = 'K')) attr(tos, 'variables') <- metadata @@ -215,10 +193,10 @@ metadata <- list(lat = list(units = 'degrees_north')) attr(lat, 'variables') <- metadata names(dim(lat)) <- 'lat' ArrayToNc(list(tos, lon, lat), 'tmp.nc') - } +} + } \author{ -History:\cr -0.0 - 2017-01 (N. Manubens, \email{nicolau.manubens at bsc.es}) - Original code. +N. Manubens \email{nicolau.manubens at bsc.es} } -\keyword{datagen} + diff --git a/man/NcClose.Rd b/man/NcClose.Rd index 2c97893e47f35a1de1c9d70120247300e53ffd31..4842168d03300c987f1fb62856326a193baabccb 100644 --- a/man/NcClose.Rd +++ b/man/NcClose.Rd @@ -1,22 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/NcClose.R \name{NcClose} \alias{NcClose} -\title{ -Close a NEtCDF File -} -\description{ -Close a \code{ncdf4} open connection to a file. -} +\title{Close a NEtCDF File} \usage{ NcClose(file_object) } \arguments{ - \item{file_object}{ -NetCDF object as returned by \code{ncdf4::nc_open}. - } +\item{file_object}{NetCDF object as returned by \code{ncdf4::nc_open}.} } \value{ The result of \code{ncdf4::nc_close}. } +\description{ +Close a \code{ncdf4} open connection to a file. +} \examples{ # Create an array from R file_path <- tempfile(fileext = '.nc') @@ -35,7 +33,6 @@ print(a) print(a_from_file[1, , ]) } \author{ -History:\cr -0.0 - 2017-03 (N. Manubens, \email{nicolau.manubens at bsc.es}) - Original code +N. Manubens \email{nicolau.manubens at bsc.es} } -\keyword{datagen} + diff --git a/man/NcOpen.Rd b/man/NcOpen.Rd index 567229a9544b7ecdf6375257795409ef3c546b62..478204d88885dc1fdeaa7161e98940a61ab7c625 100644 --- a/man/NcOpen.Rd +++ b/man/NcOpen.Rd @@ -1,22 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/NcOpen.R \name{NcOpen} \alias{NcOpen} -\title{ -Open a NetCDF File -} -\description{ -Silently opens a NetCDF file with \code{ncdf4::nc_open}. Returns NULL on failure. -} +\title{Open a NetCDF File} \usage{ NcOpen(file_path) } \arguments{ - \item{file_path}{ -Character string with the path to the file to be opened. - } +\item{file_path}{Character string with the path to the file to be opened.} } \value{ A NetCDF object as returned by \code{ncdf4::nc_open} or NULL on failure. } +\description{ +Silently opens a NetCDF file with \code{ncdf4::nc_open}. Returns NULL on failure. +} \examples{ # Create an array from R file_path <- tempfile(fileext = '.nc') @@ -33,9 +31,9 @@ NcClose(fnc) # Check the obtained array matches the original array print(a) print(a_from_file[1, , ]) + } \author{ -History:\cr -0.0 - 2017-03 (N. Manubens, \email{nicolau.manubens at bsc.es}) - Original code +N. Manubens \email{nicolau.manubens at bsc.es} } -\keyword{datagen} + diff --git a/man/NcReadDims.Rd b/man/NcReadDims.Rd index 0aac104432bbeb316f96213a36bc0e77add876df..9e909fc197ca903769ee85d5e2db7a8b08908629 100644 --- a/man/NcReadDims.Rd +++ b/man/NcReadDims.Rd @@ -1,24 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/NcReadDims.R \name{NcReadDims} \alias{NcReadDims} -\title{ -Read Dimensions of a NetCDF File -} -\description{ -Reads the dimension names and sizes of a set of variables in a NetCDF file, using the package \code{ncdf4}. The different variables in the file are considered to be stored along a dimension called 'var', so reading the dimensions of a variable 'foo' with dimensions 'lat' and 'lon' would result in a vector with the format c('var' = 1, 'lat' = n_lats, 'lon' = n_lons). -} +\title{Read Dimensions of a NetCDF File} \usage{ NcReadDims(file_to_read, var_names = NULL) } \arguments{ - \item{file_to_read}{ -Path to the file to be read or a NetCDF object as returned by \code{easyNCDF::NcOpen} or \code{ncdf4::nc_open}. - } - \item{var_names}{ -Vector of character strings with the names of the variables which to read the dimensions for. If multiple variables are requested, their dimensions will be merged and returned in a single vector. - } +\item{file_to_read}{Path to the file to be read or a NetCDF object as returned by \code{easyNCDF::NcOpen} or \code{ncdf4::nc_open}.} + +\item{var_names}{Vector of character strings with the names of the variables which to read the dimensions for. If multiple variables are requested, their dimensions will be merged and returned in a single vector.} } -\value{ -Named numeric vector with the names and sizes of the dimensions for the requested variables. +\description{ +Reads the dimension names and sizes of a set of variables in a NetCDF file, using the package \code{ncdf4}. The different variables in the file are considered to be stored along a dimension called 'var', so reading the dimensions of a variable 'foo' with dimensions 'lat' and 'lon' would result in a vector with the format c('var' = 1, 'lat' = n_lats, 'lon' = n_lons). } \examples{ # Create an array from R @@ -36,9 +30,9 @@ NcClose(fnc) # Check the obtained array matches the original array print(a) print(a_from_file[1, , ]) + } \author{ -History:\cr -0.0 - 2017-03 (N. Manubens, \email{nicolau.manubens at bsc.es}) - Original code +N. Manubens \email{nicolau.manubens at bsc.es} } -\keyword{datagen} + diff --git a/man/NcReadVarNames.Rd b/man/NcReadVarNames.Rd index 447ece02e415fe770a5bba1c35b355d7d776f2b3..e8ddcae7baf0c240dc8b3591dacdb83db8302063 100644 --- a/man/NcReadVarNames.Rd +++ b/man/NcReadVarNames.Rd @@ -1,22 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/NcReadVarNames.R \name{NcReadVarNames} \alias{NcReadVarNames} -\title{ -Read Names of Variables in a NetCDF File -} -\description{ -Reads the names of the variables in a NetCDF file and returns them as a vector of character strings. -} +\title{Read Names of Variables in a NetCDF File} \usage{ NcReadVarNames(file_to_read) } \arguments{ - \item{file_to_read}{ -Path to the file to be read or a NetCDF object as returned by \code{easyNCDF::NcOpen} or \code{ncdf4::nc_open}. - } +\item{file_to_read}{Path to the file to be read or a NetCDF object as returned by \code{easyNCDF::NcOpen} or \code{ncdf4::nc_open}.} } \value{ Vector of character strings with the names of the variables in the NetCDF file. } +\description{ +Reads the names of the variables in a NetCDF file and returns them as a vector of character strings. +} \examples{ # Create an array from R file_path <- tempfile(fileext = '.nc') @@ -33,9 +31,9 @@ NcClose(fnc) # Check the obtained array matches the original array print(a) print(a_from_file[1, , ]) + } \author{ -History:\cr -0.0 - 2017-03 (N. Manubens, \email{nicolau.manubens at bsc.es}) - Original code +N. Manubens \email{nicolau.manubens at bsc.es} } -\keyword{datagen} + diff --git a/man/NcToArray.Rd b/man/NcToArray.Rd index c1d02dcea9877bb5d76ef44734f3ce39af3cf0a4..9bf99e0a5deb35842def0ebdbe0841a28aa3c7f8 100644 --- a/man/NcToArray.Rd +++ b/man/NcToArray.Rd @@ -1,52 +1,40 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/NcToArray.R \name{NcToArray} \alias{NcToArray} -\alias{nc2a} -\title{ -Read a NetCDF File Into an R Array -} -\description{ -Reads one or a set of variables together with metadata items from a single NetCDF file into an R array (see package 'startR' to read data from multiple files/data sets). Indices to retrieve (not necessarily consecutive) can be specified for each of the dimensions. Depending on the format of the request, the variables will be merged in into a single extended array or returned in a list with an array for each variable. The different variables in the file are considered to be stored along a dimension called 'var', so reading a variable 'foo' with dimensions 'lat' and 'lon' would result in an array with the dimensions c('var' = 1, 'lat' = n_lats, 'lon' = n_lons). -} +\title{Read Names of Variables in a NetCDF File} \usage{ NcToArray(file_to_read, dim_indices = NULL, vars_to_read = NULL, - drop_var_dim = FALSE, unlist = TRUE, - expect_all_indices = FALSE, allow_out_of_range = TRUE) -nc2a(file_to_read, dim_indices = NULL, vars_to_read = NULL, - drop_var_dim = FALSE, unlist = TRUE, - expect_all_indices = FALSE, allow_out_of_range = TRUE) + drop_var_dim = FALSE, unlist = TRUE, expect_all_indices = FALSE, + allow_out_of_range = TRUE) } \arguments{ - \item{file_to_read}{ -Path to the file to be read or a NetCDF object as returned by \code{easyNCDF::NcOpen} or \code{ncdf4::nc_open}. See package 'startR' if need to read data from multiple files/data sets. - } - \item{dim_indices}{ -Named list with numeric vectors of indices to take for each dimension. The names should correspond to the dimension names which to take the indices for. Non-consecutive indices can be specified. If \code{expect_all_indices = FALSE} (default), it is not mandatory to specify the indices for all (or even any of) the dimensions. In that case all the indices along such dimensions will be read in. If \code{expect_all_indices = TRUE}, then indices for all the dimensions have to be specified for the function to return a data array. In that case, \code{NA} can be used to request all indices for a dimension if desired. +\item{file_to_read}{Path to the file to be read or a NetCDF object as returned by \code{easyNCDF::NcOpen} or \code{ncdf4::nc_open}.} + +\item{dim_indices}{Named list with numeric vectors of indices to take for each dimension. The names should correspond to the dimension names which to take the indices for. Non-consecutive indices can be specified. If \code{expect_all_indices = FALSE} (default), it is not mandatory to specify the indices for all (or even any of) the dimensions. In that case all the indices along such dimensions will be read in. If \code{expect_all_indices = TRUE}, then indices for all the dimensions have to be specified for the function to return a data array. In that case, \code{NA} can be used to request all indices for a dimension if desired. \cr\cr Since this function considers the variables in a NetCDF file are stored along a 'var' dimension, indices for the (actually non-existing) 'var'/'variable' dimension can be specified. They can be specified in 3 ways:\cr - - A vector of numeric indices: e.g. \code{list(var = c(1, 3, 5))} to take the 1st, 3rd and 5th found variables.\cr - - A vector of character strings with variable names: e.g. \code{list(var = c('foo', 'bar'))}.\cr - - A list of vectors with numeric indices or character strings: e.g. \code{list(var = list(c(1, 3, 'foo'), c(2, 'bar')))}\cr +- A vector of numeric indices: e.g. \code{list(var = c(1, 3, 5))} to take the 1st, 3rd and 5th found variables.\cr +- A vector of character strings with variable names: e.g. \code{list(var = c('foo', 'bar'))}.\cr +- A list of vectors with numeric indices or character strings: e.g. \code{list(var = list(c(1, 3, 'foo'), c(2, 'bar')))}\cr Vectors with combined numeric indices and character strings are accepted.\cr -Whereas the first two options will return a single extended array with the merged variables, the second option will return a list with an array for each requested variable. - } - \item{vars_to_read}{ -This parameter is a shortcut to (and has less priority than) specifying the requested variable names via \code{dim_indices = list(var = ...)}. It is useful when all the indices for all the requested variables have to be taken, so the parameter \code{dim_indices} can be skipped, but still only a specific variable or set of variables have to be taken. Check the documentation for the parameter \code{dim_indices} to see the three possible ways to specify this parameter. - } - \item{drop_var_dim}{ -Whether to drop the 'var' dimension this function assumes (read description). If multiple variables are requested in a vector and \code{unlist = TRUE}, the drop won't be performed (not possible). - } - \item{unlist}{ -Whether to merge the resulting array variables into a single array if possible (default) or not. Otherwise a list with as many arrays as requested variables is returned. - } - \item{expect_all_indices}{ -Whether the function should stop if indices are not provided for all the dimensions of any of the requested variables (TRUE) rather than assuming that all the indices are requested for the unspecified dimensions (FALSE). By default the later is done (FALSE). - } - \item{allow_out_of_range}{ -Whether to allow indices out of range (simply disregard them) or to stop if indices out of range are found. - } +Whereas the first two options will return a single extended array with the merged variables, the second option will return a list with an array for each requested variable.} + +\item{vars_to_read}{This parameter is a shortcut to (and has less priority than) specifying the requested variable names via \code{dim_indices = list(var = ...)}. It is useful when all the indices for all the requested variables have to be taken, so the parameter \code{dim_indices} can be skipped, but still only a specific variable or set of variables have to be taken. Check the documentation for the parameter \code{dim_indices} to see the three possible ways to specify this parameter.} + +\item{drop_var_dim}{Whether to drop the 'var' dimension this function assumes (read description). If multiple variables are requested in a vector and \code{unlist = TRUE}, the drop won't be performed (not possible).} + +\item{unlist}{Whether to merge the resulting array variables into a single array if possible (default) or not. Otherwise a list with as many arrays as requested variables is returned.} + +\item{expect_all_indices}{Whether the function should stop if indices are not provided for all the dimensions of any of the requested variables (TRUE) rather than assuming that all the indices are requested for the unspecified dimensions (FALSE). By default the later is done (FALSE).} + +\item{allow_out_of_range}{Whether to allow indices out of range (simply disregard them) or to stop if indices out of range are found.} } \value{ -Array or list of arrays with the data for one or more than one of the requested variables (depending on the parameters). The dimensions are named. The arrays contain the attribute 'variables' with the metadata items found in the NetCDF file. +Vector of character strings with the names of the variables in the NetCDF file. +} +\description{ +Reads the names of the variables in a NetCDF file and returns them as a vector of character strings. } \examples{ # Create an array from R @@ -65,28 +53,8 @@ NcClose(fnc) print(a) print(a_from_file[1, , ]) -# Example with extra dimensions of length 1 -# Creating sample data with singleton dimensions. Only dimensions 'a', 'b' and -# 'c' are of length > 1. -test_var <- array(1:24, dim = c(1, 1, 2, 1, 1, 3, 1, 4, 1, 1)) -names(dim(test_var)) <- c('x', 'y', 'a', 'z', 't', 'b', 'u', 'c', 'v', 'w') -# Storing the data into a NetCDF file -a2nc(list(test_var = test_var), file_path) -# Reading the data back -fff <- nc2a(file_path, list(a = NA, b = NA, c = NA), vars_to_read = 'test_var') -# By default, if no indices are provided for the singleton dimensions, they are -# automatically read in and preserved -dim(fff) -# Reading the data back with expect_all_indices = TRUE -fff <- nc2a(file_path, list(a = NA, b = NA, c = NA), vars_to_read = 'test_var', - expect_all_indices = TRUE) -# If indices for all dimensions are not provided and expect_all_indices = TRUE, -# the function crashes, except if those dimensions are of length 1. In that -# case, the function ignores those (those are dropped) -dim(fff) } \author{ -History:\cr -0.0 - 2017-03 (N. Manubens, \email{nicolau.manubens at bsc.es}) - Original code +N. Manubens, \email{nicolau.manubens at bsc.es} } -\keyword{datagen} + diff --git a/man/Subset.Rd b/man/Subset.Rd deleted file mode 100644 index bfc499a69313a3356543763a7739a042b31ad8d3..0000000000000000000000000000000000000000 --- a/man/Subset.Rd +++ /dev/null @@ -1,48 +0,0 @@ -\name{Subset} -\alias{Subset} -\title{Subset a Data Array} -\description{ -This function allows to subset (i.e. slice, take a chunk of) an array, in a -similar way as done in the function \code{take()} in the package plyr. There -are two main inprovements:\cr\cr -The input array can have dimension names, either -in \code{names(dim(x))} or in the attribute 'dimensions', and the dimensions to -subset along can be specified via the parameter \code{along} either with -integer indices or either by their name.\cr\cr -There are additional ways to adjust which dimensions are dropped in the -resulting array: either to drop all, to drop none, to drop only the ones that -have been sliced or to drop only the ones that have not been sliced.\cr\cr -If an array is provided without dimension names, dimension names taken from -the parameter \code{dim_names} will be added to the array. -} -\usage{ -Subset(x, along, indices, drop = FALSE) -} -\arguments{ - \item{x}{ -A multidimensional array to be sliced. It can have dimension names either -in \code{names(dim(x))} or either in the attribute 'dimensions'. - } - \item{along}{ -Vector with references to the dimensions to take the subset from: either -integers or dimension names. - } - \item{indices}{ -List of indices to take from each dimension specified in 'along'. If a single -dimension is specified in 'along' the indices can be directly provided as a -single integer or as a vector. - } - \item{drop}{ -Whether to drop all the dimensions of length 1 in the resulting array, none, -only those that are specified in 'along', or only those that are not specified -in 'along'. The possible values are, respectively: 'all' or TRUE, 'none' or -FALSE, 'selected', and 'non-selected'. - } -} -\examples{ -# Create an array from R with data for 3 'var', 3 'member' and 3 'time' -a <- array(1:27, dim = c(var = 3, member = 3, time = 3)) -# Take a subset with all 'member' and 'time' for the 1st 'var' -b <- Subset(a, 'var', 1) -} -\keyword{dplot}