Commit a5691ecf authored by Nuria Pérez-Zanón's avatar Nuria Pérez-Zanón
Browse files

Merge branch 'develop-doc' into 'master'

Documentation in roxygen format for submission to CRAN

See merge request !21
parents 538eb09c 43495ad4
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
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)
#'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
#'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
......
#'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
......
#'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
......
#'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
......
#'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)),
......
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
}
......@@ -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
......
% 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')
}
}
}
}