transNcdfMerge <- function(
### merge several ncdf files
file.names ##<< character vector: names of the files to merge.
, name.change = function(x) return(x)
, time.diff = NULL ##<< maximum time difference to be allowed between
## two subsequent input files.
, fun.start = NULL##<< function: function to retrieve the start date from
## the file name e.g. function(x) substr(x, nchar(x)-15, nchar(x)-10)
, fun.end = NULL##<< see fun.start
, time.range.out = c() ##<< POSIXct vector: (start date, end date): start
## and end dates of the final file. If not supplied, all available data
## are used.
, format = character() ##<< character string: see ?transNcdfCutFile
, convert = .getChronDateFromName1
, path.target = getwd() ##<< file path: where to copy to the results files.
, target.name = ''
) {
##details<<
## Convenience wrapper around cdo to merge several ncdf files containing
## subsequent time steps into one continuous file.
##TODO provide example
##TODO useful defaults
##TODO detect overlapping time spans
if (!length(format)) format <- '%Y%m'
if (!is.null(fun.start) & !is.null(fun.end)) {
date.start.in <- .convertFilename2Date(file.names, fun.start, convert)
date.end.in <- .convertFilename2Date(file.names, fun.end, convert)
file.names <- file.names[order(date.start.in)]
date.end.in <- date.end.in[order(date.start.in)]
date.start.in <- date.start.in[order(date.start.in)]
} else {
date.start.in.l <- list()
date.end.in.l <- list()
for (i in 1:length(file.names)) {
times <- readNcdfTime(file.names[i])
date.start.in.l[[i]] <- min(times)
date.end.in.l[[i]] <- max(times)
}
date.start.in <- as.POSIXct(unlist(date.start.in.l), origin = '1970-01-01')
date.end.in <- as.POSIXct(unlist(date.end.in.l), origin = '1970-01-01')
}
if (length(time.range.out) == 2) {
files.remove <- c(which(date.end.in < time.range.out[1]),
which(date.start.in > time.range.out[2]))
if (length(files.remove) > 0 ) {
file.names <- file.names[-files.remove]
date.end.in <- date.end.in[-files.remove]
date.start.in <- date.start.in[-files.remove]
}
}
if (!is.null(time.diff)) {
if (sum(!(
date.start.in[-1] - date.end.in[-length(date.end.in)] <= time.diff)) > 0
) {
paste('Time period missing!')
return('Time period missing!')
}
}
date.start.out <- date.start.in[1]
date.end.out <- date.end.in[length(date.end.in)]
if (length(time.range.out) == 2) {
files.delete <- c()
if (date.start.in[1] < time.range.out[1]) {
file.start.new <- transNcdfCutFiles(
file.names[1], time.range.out = c(time.range.out[1], date.end.in[1])
, fun.start = fun.start, fun.end = fun.end, format = format
, convert = convert)
file.names[1] <- file.start.new
files.delete <- c(files.delete, file.start.new)
date.start.out <- time.range.out[1]
date.start.in[1] <- time.range.out[1]
}
if (date.end.in[length(date.end.in)] > time.range.out[2]) {
file.end.new <- transNcdfCutFiles(
file.names[length(file.names)]
, time.range.out = c(date.start.in[length(date.start.in)], time.range.out[2])
, fun.start = fun.start, fun.end = fun.end, format = format
, convert = convert)
file.names[length(file.names)] <- file.end.new
files.delete <- c(files.delete, file.end.new)
date.end.out <- time.range.out[2]
date.end.in[length(date.end.in)] <- time.range.out[2]
}
}
Sys.setenv(SKIP_SAME_TIME = 1)
if (nchar(target.name) == 0) {
ofile <- file.path(path.target, do.call(name.change, list(
sub(do.call(fun.end, list(file.names[1]))
, do.call(fun.end, list(file.names[length(file.names)]))
, file.names[1]))))
} else {
ofile <- file.path(path.target, target.name)
}
cmd <- paste0(
'cdo -O mergetime ', paste(file.names, collapse = ' '), ' ', ofile)
system(cmd )
if (exists('files.delete') && length(files.delete) > 0 )
for (file.t in files.delete)
file.remove(file.t)
##value<< list: name of the file created and its time range.
invisible(list(file.out = ofile, date.range = c(date.start.out, date.end.out)))
}
.getChronDateFromName1 <- function(
### construct a chron date from string
x ## string scalar or vector
){
##seealso<< \code{\link{transNcdfCutFiles}}
chron(
paste(x, '15', sep = '')
, format = 'ymd'
, out.format = 'd-m-y')
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.