diff --git a/DESCRIPTION b/DESCRIPTION index 68a4320bd1b8d59d356bc8ccf0b99e4dee6018e9..e8382cd0b7f07c91ba1223f52002a40090724ab1 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,11 +1,12 @@ Package: s2dv Title: A Set of Common Tools for Seasonal to Decadal Verification -Version: 1.1.0 +Version: 1.2.0 Authors@R: c( person("BSC-CNS", role = c("aut", "cph")), person("An-Chi", "Ho", , "an.ho@bsc.es", role = c("aut", "cre")), person("Nuria", "Perez-Zanon", , "nuria.perez@bsc.es", role = "aut"), person("Roberto", "Bilbao", , "roberto.bilbao@bsc.es", role = "ctb"), + person("Josep", "Cos", , "josep.cos@bsc.es", role = "ctb"), person("Carlos", "Delgado", , "carlos.delgado@bsc.es", role = "ctb"), person("Llorenç", "Lledó", , "llorenc.lledo@bsc.es", role = "ctb"), person("Andrea", "Manrique", , "andrea.manrique@bsc.es", role = "ctb"), diff --git a/NEWS.md b/NEWS.md index 71993f0e554bb260e19b2678f9c455d5e0923f2f..df06e6bcd12346ae1be57426798cd0c64e632590 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,17 @@ +# s2dv 1.2.0 (Release date: 2022-06-16) +- Cluster(): Fix a bug of calculating nclusters ("K"): the function didn't use the whole data to calculate "K" if parameter "nclusters" is NULL.; Add missing output dimension names +- Clim(): Correct the output dimensions for some cases; allow dat_dim to be NULL; obs doesn't need to have dat_dim. +- MeanDims(): if the result is a number and drop = T, return a numeric instead of an array +- Load(): Bugfix for R >= 4.0.0 regarding list and vector confusion +- PlotLayout(): Bugfix when param "var" is a list +- ACC(): Add area-weighting into the calculation and ensure the data has a spatial mean of zero. "space_dim" is deprecated and replaced by "lat_dim" and "lon_dim". "dat_dim" can be NULL. +- PlotEquiMap(): Add useRaster = TRUE in image() if possible (i.e., latitude and longitude are regularly spaced.) +- PlotEquiMap(): New parameters xlonshft ylatshft xlabels ylabels for self-defined axis +- PlotEquiMap(): Flexible map longitude range +- New function: WeightCells, DiffCorr, ResidualCorr, RPSS, RPSSS +- Clim() and MeanDims() efficiency improvement +- CDORemap(): Add time metadata to avoid cdo warning like Warning (find_time_vars): Time variable >time< not found! + # s2dv 1.1.0 (Release date: 2021-12-14) - New functions: RatioPredictableComponents, SignalNoiseRatio - CDORemap(): Able to interpolate irregular grid to regular grid; include new cdo methods 'con2', 'laf' and 'nn' diff --git a/R/AMV.R b/R/AMV.R index a51a819def8e8b163e10b01eb36cad4673692b13..e14897b291de60fa2c6ad5051e1e070eed72f094 100644 --- a/R/AMV.R +++ b/R/AMV.R @@ -98,10 +98,10 @@ AMV <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'lo stop("Parameter 'data' must be a numeric array.") } # data_lats and data_lons part1 - if (!(class(data_lats) == 'numeric' | class(data_lats) == 'integer')) { + if (!(inherits(data_lats, 'numeric') | inherits(data_lats, 'integer'))) { stop("Parameter 'data_lats' must be a numeric vector.") } - if (!(class(data_lons) == 'numeric' | class(data_lons) == 'integer')) { + if (!(inherits(data_lons, 'numeric') | inherits(data_lons, 'integer'))) { stop("Parameter 'data_lons' must be a numeric vector.") } # type diff --git a/R/GMST.R b/R/GMST.R index 0d6c49e8aa3a827d69d5dc9905fab23c4197efd7..85b382d524fc763f166971994067c98cc604777b 100644 --- a/R/GMST.R +++ b/R/GMST.R @@ -125,10 +125,10 @@ GMST <- function(data_tas, data_tos, data_lats, data_lons, mask_sea_land, sea_va stop("The dimension of data_tas and data_tos must be identical.") } # data_lats and data_lons part1 - if (!(class(data_lats) == 'numeric' | class(data_lats) == 'integer')) { + if (!(inherits(data_lats, 'numeric') | inherits(data_lats, 'integer'))) { stop("Parameter 'data_lats' must be a numeric vector.") } - if (!(class(data_lons) == 'numeric' | class(data_lons) == 'integer')) { + if (!(inherits(data_lons, 'numeric') | inherits(data_lons, 'integer'))) { stop("Parameter 'data_lons' must be a numeric vector.") } # lat_dim diff --git a/R/GSAT.R b/R/GSAT.R index 1774bd684533081137b75961907dac3750ad9a21..30975b9b1b7f2678f823f3488226a7d10cff0714 100644 --- a/R/GSAT.R +++ b/R/GSAT.R @@ -94,10 +94,10 @@ GSAT <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'l stop("Parameter 'data' must be a numeric array.") } # data_lats and data_lons part1 - if (!(class(data_lats) == 'numeric' | class(data_lats) == 'integer')) { + if (!(inherits(data_lats, 'numeric') | inherits(data_lats, 'integer'))) { stop("Parameter 'data_lats' must be a numeric vector.") } - if (!(class(data_lons) == 'numeric' | class(data_lons) == 'integer')) { + if (!(inherits(data_lons, 'numeric') | inherits(data_lons, 'integer'))) { stop("Parameter 'data_lons' must be a numeric vector.") } # type diff --git a/R/Load.R b/R/Load.R index 3c3aa8ea0d9c6408c272f3c1ecf4e49f2ae25666..e188299aa3cbacc9ae8a4da0f19c6fa19ab29917 100644 --- a/R/Load.R +++ b/R/Load.R @@ -2121,7 +2121,7 @@ Load <- function(var, exp = NULL, obs = NULL, sdates, nmember = NULL, }) - if (class(errors) == 'try-error') { + if (inherits(errors, 'try-error')) { invisible(list(load_parameters = load_parameters)) } else { # Before ending, the data is arranged in the common format, with the following diff --git a/R/Persistence.R b/R/Persistence.R index 5a53857f797c47db5e99bb912c2be44d52e8b001..9895f479a460e22dafc731185bed30fa50f22cdf 100644 --- a/R/Persistence.R +++ b/R/Persistence.R @@ -122,7 +122,7 @@ Persistence <- function(data, dates, time_dim = 'time', start, end, ft_start, stop(paste0("Parameter 'dates' must be a sequence of integer (YYYY) or ", "string (YYYY-MM-DD) in class 'Date'.")) } - } else if (class(dates) == 'Date') { #(YYYY-MM-DD) + } else if (inherits(dates, 'Date')) { #(YYYY-MM-DD) } else { stop(paste0("Parameter 'dates' must be a sequence of integer (YYYY) or ", @@ -148,7 +148,7 @@ Persistence <- function(data, dates, time_dim = 'time', start, end, ft_start, stop(paste0("Parameter 'start' must start at least 40 time steps after ", "the first 'dates'.")) } - } else if (class(start) == 'Date') { + } else if (inherits(start, 'Date')) { if (length(start) > 1 | any(start < as.Date(ISOdate(1850, 1, 1))) | any(start > as.Date(ISOdate(2021, 1, 1)))) { stop(paste0("Parameter 'start' must be an integer or a string in class ", @@ -176,7 +176,7 @@ Persistence <- function(data, dates, time_dim = 'time', start, end, ft_start, stop(paste0("Parameter 'end' must end at most 1 time steps after ", "the last 'dates'.")) } - } else if (class(end) == 'Date') { + } else if (inherits(end, 'Date')) { if (length(end) > 1 | any(end < as.Date(ISOdate(1850, 1, 1))) | any(end > as.Date(ISOdate(2020, 12, 31)))) { stop(paste0("Parameter 'end' must be an integer or a string in class ", diff --git a/R/PlotLayout.R b/R/PlotLayout.R index b6bc46724334dc27d2edd1dce1719c8ae1a2946b..742478e08db3ad08563ae00b6619379b9448bb9b 100644 --- a/R/PlotLayout.R +++ b/R/PlotLayout.R @@ -57,18 +57,18 @@ #' of each sub-list match the names of the parameters to be adjusted, and #' each value in a sub-list contains the value of the corresponding parameter. #' For example, if the plots are two maps with different arguments, the -#' structure would be like:\n -#' var:\n -#' List of 2\n -#' $ : num [1:360, 1:181] 1 3.82 5.02 6.63 8.72 ...\n -#' $ : num [1:360, 1:181] 2.27 2.82 4.82 7.7 10.32 ...\n -#' special_args:\n -#' List of 2\n -#' $ :List of 2\n -#' ..$ arg1: ...\n -#' ..$ arg2: ...\n -#' $ :List of 1\n -#' ..$ arg1: ...\n +#' structure would be like:\cr +#' var:\cr +#' List of 2\cr +#' $ : num [1:360, 1:181] 1 3.82 5.02 6.63 8.72 ...\cr +#' $ : num [1:360, 1:181] 2.27 2.82 4.82 7.7 10.32 ...\cr +#' special_args:\cr +#' List of 2\cr +#' $ :List of 2\cr +#' ..$ arg1: ...\cr +#' ..$ arg2: ...\cr +#' $ :List of 1\cr +#' ..$ arg1: ...\cr #'@param nrow Numeric value to force the number of rows in the automatically #' generated layout. If higher than the required, this will yield blank cells #' in the layout (which can then be populated). If lower than the required diff --git a/R/Regression.R b/R/Regression.R index 244ddc729e94f8046b9c0ff1f0c47c89b08df62b..1cd12e6e206bfda316bca0ac5d98f7da1f703228 100644 --- a/R/Regression.R +++ b/R/Regression.R @@ -123,7 +123,7 @@ Regression <- function(datay, datax, reg_dim = 'sdate', formula = y ~ x, stop("Parameter 'reg_dim' is not found in 'datay' or 'datax' dimension.") } ## formula - if (class(formula) != 'formula') { + if (!inherits(formula, 'formula')) { stop("Parameter 'formula' must the an object of class 'formula'.") } ## pval diff --git a/R/SPOD.R b/R/SPOD.R index 51717b31ee05cedb757347e3bcf7b02ba644c75b..2599477900b13d3b8d89ae7a282d7fd4158502e6 100644 --- a/R/SPOD.R +++ b/R/SPOD.R @@ -97,10 +97,10 @@ SPOD <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'l stop("Parameter 'data' must be a numeric array.") } # data_lats and data_lons part1 - if (!(class(data_lats) == 'numeric' | class(data_lats) == 'integer')) { + if (!(inherits(data_lats, 'numeric') | inherits(data_lats, 'integer'))) { stop("Parameter 'data_lats' must be a numeric vector.") } - if (!(class(data_lons) == 'numeric' | class(data_lons) == 'integer')) { + if (!(inherits(data_lons, 'numeric') | inherits(data_lons, 'integer'))) { stop("Parameter 'data_lons' must be a numeric vector.") } # type diff --git a/R/TPI.R b/R/TPI.R index 80d958ea2fb27d20acbceb26f0f4a00e29ba0f3d..d3f0550613a831f9428d8adaf43863b81c12bd93 100644 --- a/R/TPI.R +++ b/R/TPI.R @@ -96,10 +96,10 @@ TPI <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'lo stop("Parameter 'data' must be a numeric array.") } # data_lats and data_lons part1 - if (!(class(data_lats) == 'numeric' | class(data_lats) == 'integer')) { + if (!(inherits(data_lats, 'numeric') | inherits(data_lats, 'integer'))) { stop("Parameter 'data_lats' must be a numeric vector.") } - if (!(class(data_lons) == 'numeric' | class(data_lons) == 'integer')) { + if (!(inherits(data_lons, 'numeric') | inherits(data_lons, 'integer'))) { stop("Parameter 'data_lons' must be a numeric vector.") } # type @@ -181,7 +181,7 @@ TPI <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'lo } # indices_for_clim if (!is.null(indices_for_clim)) { - if (!class(indices_for_clim) %in% c('numeric', 'integer') + if (!(inherits(indices_for_clim, 'numeric') | inherits(indices_for_clim, 'integer')) & !(is.logical(indices_for_clim) & !any(indices_for_clim))) { stop(paste0("The parameter 'indices_for_clim' must be a numeric vector ", "or NULL to compute the anomalies based on the whole period, ", diff --git a/man/PlotLayout.Rd b/man/PlotLayout.Rd index eaa2197b77cb32bcbb78daa9d3150e78ee2f52f8..f8e7bae376763de767cd967a4f3baee1d608ceef 100644 --- a/man/PlotLayout.Rd +++ b/man/PlotLayout.Rd @@ -96,18 +96,18 @@ b) providing a list of named sub-lists in 'special_args', where the names of each sub-list match the names of the parameters to be adjusted, and each value in a sub-list contains the value of the corresponding parameter. For example, if the plots are two maps with different arguments, the -structure would be like:\n -var:\n - List of 2\n - $ : num [1:360, 1:181] 1 3.82 5.02 6.63 8.72 ...\n - $ : num [1:360, 1:181] 2.27 2.82 4.82 7.7 10.32 ...\n -special_args:\n - List of 2\n - $ :List of 2\n - ..$ arg1: ...\n - ..$ arg2: ...\n - $ :List of 1\n - ..$ arg1: ...\n} +structure would be like:\cr +var:\cr + List of 2\cr + $ : num [1:360, 1:181] 1 3.82 5.02 6.63 8.72 ...\cr + $ : num [1:360, 1:181] 2.27 2.82 4.82 7.7 10.32 ...\cr +special_args:\cr + List of 2\cr + $ :List of 2\cr + ..$ arg1: ...\cr + ..$ arg2: ...\cr + $ :List of 1\cr + ..$ arg1: ...\cr} \item{nrow}{Numeric value to force the number of rows in the automatically generated layout. If higher than the required, this will yield blank cells diff --git a/man/RPS.Rd b/man/RPS.Rd index 5062671e53b053fc9aa58b395456cca7afd5c528..ee5c24142cd840615cd2759ae0180b805028d773 100644 --- a/man/RPS.Rd +++ b/man/RPS.Rd @@ -43,7 +43,9 @@ The default value is FALSE.} \item{weights}{A named two-dimensional numerical array of the weights for each member and time. The dimension names should include 'memb_dim' and -'time_dim'. The default value is NULL.} +'time_dim'. The default value is NULL. The ensemble should have at least 70 +members or span at least 10 time steps and have more than 45 members if +consistency between the weighted and unweighted methodologies is desired.} \item{ncores}{An integer indicating the number of cores to use for parallel computation. The default value is NULL.} diff --git a/man/RPSS.Rd b/man/RPSS.Rd index ca33c07174cb051fab060cdf3cad2b778c5cd755..5b8bd7ec07dfc58f5a588fd2113009b441eb1445 100644 --- a/man/RPSS.Rd +++ b/man/RPSS.Rd @@ -50,7 +50,9 @@ The default value is FALSE.} \item{weights}{A named two-dimensional numerical array of the weights for each member and time. The dimension names should include 'memb_dim' and -'time_dim'. The default value is NULL.} +'time_dim'. The default value is NULL. The ensemble should have at least 70 +members or span at least 10 time steps and have more than 45 members if +consistency between the weighted and unweighted methodologies is desired.} \item{ncores}{An integer indicating the number of cores to use for parallel computation. The default value is NULL.} diff --git a/man/s2dv-package.Rd b/man/s2dv-package.Rd index 557692115e5ac3f458a52161ca4323658bfb8a25..871a8b66db5a8c04e35d2a39149c5e4756159f48 100644 --- a/man/s2dv-package.Rd +++ b/man/s2dv-package.Rd @@ -6,15 +6,7 @@ \alias{s2dv-package} \title{s2dv: A Set of Common Tools for Seasonal to Decadal Verification} \description{ -The advanced version of package 's2dverification'. It is - intended for 'seasonal to decadal' (s2d) climate forecast verification, but - it can also be used in other kinds of forecasts or general climate analysis. - This package is specially designed for the comparison between the experimental - and observational datasets. The functionality of the included functions covers - from data retrieval, data post-processing, skill scores against observation, - to visualization. Compared to 's2dverification', 's2dv' is more compatible - with the package 'startR', able to use multiple cores for computation and - handle multi-dimensional arrays with a higher flexibility. +The advanced version of package 's2dverification'. It is intended for 'seasonal to decadal' (s2d) climate forecast verification, but it can also be used in other kinds of forecasts or general climate analysis. This package is specially designed for the comparison between the experimental and observational datasets. The functionality of the included functions covers from data retrieval, data post-processing, skill scores against observation, to visualization. Compared to 's2dverification', 's2dv' is more compatible with the package 'startR', able to use multiple cores for computation and handle multi-dimensional arrays with a higher flexibility. } \references{ \url{https://earth.bsc.es/gitlab/es/s2dv/} diff --git a/man/sampleDepthData.Rd b/man/sampleDepthData.Rd index 77e4a7a290855556aa7b36f8a6c46af2e2791ca7..47e2f1b742e3231496502c05f6741ff1c54b82d2 100644 --- a/man/sampleDepthData.Rd +++ b/man/sampleDepthData.Rd @@ -5,7 +5,8 @@ \alias{sampleDepthData} \title{Sample of Experimental Data for Forecast Verification In Function Of Latitudes And Depths} -\format{The data set provides with a variable named 'sampleDepthData'.\cr\cr +\format{ +The data set provides with a variable named 'sampleDepthData'.\cr\cr sampleDepthData$exp is an array that contains the experimental data and the dimension meanings and values are:\cr @@ -18,7 +19,8 @@ but in this sample is not defined (NULL).\cr\cr sampleDepthData$depths is an array with the 7 longitudes covered by the data.\cr\cr -sampleDepthData$lat is an array with the 21 latitudes covered by the data.\cr\cr} +sampleDepthData$lat is an array with the 21 latitudes covered by the data.\cr\cr +} \usage{ data(sampleDepthData) } diff --git a/man/sampleMap.Rd b/man/sampleMap.Rd index eaf8aa5a686f589db7e223ccc651af29266203e6..e4ec5a5b2be18b7f4ac4bfef511e6a8333205a49 100644 --- a/man/sampleMap.Rd +++ b/man/sampleMap.Rd @@ -4,7 +4,8 @@ \name{sampleMap} \alias{sampleMap} \title{Sample Of Observational And Experimental Data For Forecast Verification In Function Of Longitudes And Latitudes} -\format{The data set provides with a variable named 'sampleMap'.\cr\cr +\format{ +The data set provides with a variable named 'sampleMap'.\cr\cr sampleMap$mod is an array that contains the experimental data and the dimension meanings and values are:\cr c(# of experimental datasets, # of members, # of starting dates, # of lead-times, # of latitudes, # of longitudes)\cr @@ -16,7 +17,8 @@ sampleMap$obs is an array that contains the observational data and the dimension sampleMap$lat is an array with the 2 latitudes covered by the data (see examples on Load() for details on why such low resolution).\cr\cr - sampleMap$lon is an array with the 3 longitudes covered by the data (see examples on Load() for details on why such low resolution).} + sampleMap$lon is an array with the 3 longitudes covered by the data (see examples on Load() for details on why such low resolution). +} \usage{ data(sampleMap) } diff --git a/man/sampleTimeSeries.Rd b/man/sampleTimeSeries.Rd index 05a8e7980116c649d6b156a4746f16b2c45fea4e..7f058e20443f04b3fae5e9658f07f17e0e58c5ce 100644 --- a/man/sampleTimeSeries.Rd +++ b/man/sampleTimeSeries.Rd @@ -4,7 +4,8 @@ \name{sampleTimeSeries} \alias{sampleTimeSeries} \title{Sample Of Observational And Experimental Data For Forecast Verification As Area Averages} -\format{The data set provides with a variable named 'sampleTimeSeries'.\cr\cr +\format{ +The data set provides with a variable named 'sampleTimeSeries'.\cr\cr sampleTimeSeries$mod is an array that contains the experimental data and the dimension meanings and values are:\cr c(# of experimental datasets, # of members, # of starting dates, # of lead-times)\cr @@ -16,7 +17,8 @@ sampleTimeSeries$obs is an array that contains the observational data and the di sampleTimeSeries$lat is an array with the 2 latitudes covered by the data that was area averaged to calculate the time series (see examples on Load() for details on why such low resolution).\cr\cr -sampleTimeSeries$lon is an array with the 3 longitudes covered by the data that was area averaged to calculate the time series (see examples on Load() for details on why such low resolution).} +sampleTimeSeries$lon is an array with the 3 longitudes covered by the data that was area averaged to calculate the time series (see examples on Load() for details on why such low resolution). +} \usage{ data(sampleTimeSeries) } diff --git a/s2dv-manual.pdf b/s2dv-manual.pdf index b6faa89fbc92c8735e85d4fa7bc4d0f68d47030b..dab70611f5a50086733b604b43015acbc0240458 100644 Binary files a/s2dv-manual.pdf and b/s2dv-manual.pdf differ