Commit 29abdda1 authored by Dorchies David's avatar Dorchies David
Browse files

v1.6.8.20 feat: add .AggregConvertFunTable data.frame

- This public data.frame allows the user to watch and modify the auto-guess operations to perform in SeriesAggreg

Refs #41
parent c6fe7049
Pipeline #17989 failed with stages
in 1 minute and 24 seconds
Package: airGR
Type: Package
Title: Suite of GR Hydrological Models for Precipitation-Runoff Modelling
Version: 1.6.8.19
Version: 1.6.8.20
Date: 2020-12-01
Authors@R: c(
person("Laurent", "Coron", role = c("aut", "trl"), comment = c(ORCID = "0000-0002-1503-6204")),
......
......@@ -65,6 +65,7 @@ export(TransfoParam_Lag)
export(plot)
export(plot.OutputsModel)
export(.ErrorCrit)
export(.AggregConvertFunTable)
......
......@@ -2,12 +2,13 @@
### 1.6.8.10 Release Notes (2020-11-21)
### 1.6.8.20 Release Notes (2020-12-01)
#### New features
- Added <code>SeriesAggreg</code> S3 method with functions for `InputsModel`, `OutputsModel`, `list`, `data.frame` class objects. This new version of the <code>SeriesAggreg()</code> function allows to compute regimes.
- Added<code>.AggregConvertFun()</code> private function in order to choose automatically the <code>ConvertFun</code> to apply on each element of <code>InputsModel</code> and <code>OutputsModel</code> objects.
- Added <code>getAggregConvertFun()</code> private function in order to choose automatically the <code>ConvertFun</code> to apply on each element of objects used in <code>SeriesAggreg</code>.
- Added <code>.AggregConvertFunTable</code> data.frame that allows the user to see what names of list items or data.frame column names are guessed and eventually customise this correspondence table.
#### Bug fixes
......
SeriesAggreg.data.frame <- function(TabSeries,
Format,
ConvertFun = .AggregConvertFun(names(TabSeries)[-1]),
ConvertFun = getAggregConvertFun(names(TabSeries)[-1]),
TimeFormat = NULL,
NewTimeFormat = NULL,
YearFirstMonth = 1,
......
......@@ -68,7 +68,7 @@ SeriesAggreg.list <- function(TabSeries,
}
dfOut <- NULL
if (length(cols)) {
ConvertFun2 <- .AggregConvertFun(names(cols))
ConvertFun2 <- getAggregConvertFun(names(cols))
if (is.null(recursive)) {
if (missing(ConvertFun)) {
stop("'ConvertFun' argument should provided if 'recursive = NULL'")
......@@ -104,7 +104,7 @@ SeriesAggreg.list <- function(TabSeries,
listCols <- listCols[setdiff(names(listCols), names(dfCols))]
if (length(listCols) > 0) {
# Check for predefined ConvertFun for all sub-elements
ConvertFun <- .AggregConvertFun(names(listCols))
ConvertFun <- getAggregConvertFun(names(listCols))
# Run SeriesAggreg for each embedded list
listRes <-
lapply(names(listCols),
......@@ -143,7 +143,7 @@ SeriesAggreg.list <- function(TabSeries,
"), it will be ignored in the aggregation"
)
} else {
ConvertFun <- rep(.AggregConvertFun(key), ncol(m))
ConvertFun <- rep(getAggregConvertFun(key), ncol(m))
res[[key]] <- SeriesAggreg(data.frame(DatesR, m),
Format = Format,
ConvertFun = ConvertFun)
......
......@@ -11,32 +11,6 @@
# }
# }
## =================================================================================
## function to manage Fortran outputs
## =================================================================================
.AggregConvertFun <- function(Outputs) {
Table <- rbind(
data.frame(ConvertFun = "mean",
Outputs = c("Prod","Rout","Exp","SnowPack","ThermalState",
"Gratio","Temp","Gthreshold","Glocalmax","LayerTempMean", "T")),
data.frame(ConvertFun = "sum",
Outputs = c("zzz","PotEvap","Precip","Pn","Ps","AE","Perc","PR","Q9",
"Q1","Exch","AExch1","AExch2","AExch","QR","QRExp",
"QD","Qsim","Pliq","Psol","PotMelt","Melt","PliqAndMelt",
"LayerPrecip","LayerFracSolidPrecip", "Qmm", "Qls", "E", "P", "Qupstream"))
)
res <- sapply(Outputs, function(iOutputs) {
iRes <- Table$ConvertFun[Table$Outputs == iOutputs]
iRes <- ifelse(any(is.na(iRes)), NA, iRes)
})
return(res)
}
## =================================================================================
## function to manage Fortran outputs
## =================================================================================
......
......@@ -40,4 +40,24 @@ getSeriesAggregClass <- function(Format) {
m = "monthly",
Y = "yearly"
)
}
\ No newline at end of file
}
.AggregConvertFunTable <- rbind(
data.frame(ConvertFun = "mean",
Outputs = c("Prod","Rout","Exp","SnowPack","ThermalState",
"Gratio","Temp","Gthreshold","Glocalmax","LayerTempMean", "T")),
data.frame(ConvertFun = "sum",
Outputs = c("zzz","PotEvap","Precip","Pn","Ps","AE","Perc","PR","Q9",
"Q1","Exch","AExch1","AExch2","AExch","QR","QRExp",
"QD","Qsim","Pliq","Psol","PotMelt","Melt","PliqAndMelt",
"LayerPrecip","LayerFracSolidPrecip", "Qmm", "Qls", "E", "P", "Qupstream"))
)
getAggregConvertFun <- function(Outputs) {
res <- sapply(Outputs, function(iOutputs) {
iRes <- .AggregConvertFunTable$ConvertFun[.AggregConvertFunTable$Outputs == iOutputs]
iRes <- ifelse(any(is.na(iRes)), NA, iRes)
})
return(res)
}
......@@ -24,13 +24,16 @@ Warning: on the aggregated outputs, the dates correspond to the beginning of the
\code{\link{SeriesAggreg.InputsModel}} and \code{\link{SeriesAggreg.OutputsModel}}
call \code{\link{SeriesAggreg.list}} which itself calls \code{\link{SeriesAggreg.data.frame}}.
So, all arguments passed to any \code{\link{SeriesAggreg}} method will be passed to \code{\link{SeriesAggreg.data.frame}}.
If \code{ConvertFun} is not provided, the operation to perform is guessed from the name of the list items or column
name dataframe in respect with the matching table \code{.AggregConvertFunTable}.
}
\usage{
\method{SeriesAggreg}{data.frame}(TabSeries,
Format,
ConvertFun = .AggregConvertFun(names(TabSeries)[-1]),
ConvertFun = getAggregConvertFun(names(TabSeries)[-1]),
TimeFormat = NULL,
NewTimeFormat = NULL,
YearFirstMonth = 1,
......@@ -61,7 +64,7 @@ Warning: on the aggregated outputs, the dates correspond to the beginning of the
\item{NewTimeFormat}{(deprecated) [character] output time step format (i.e. \code{"hourly"}, \code{"daily"}, \code{"monthly"} or \code{"yearly"}). Use the \code{TabSeries} argument instead}
\item{ConvertFun}{[character] names of aggregation functions (e.g. for P[mm], T[degC], Q[mm]: \code{ConvertFun = c("sum", "mean", "sum"})) (Default: use the name of the column or "mean" for regime calculation)}
\item{ConvertFun}{[character] names of aggregation functions (e.g. for P[mm], T[degC], Q[mm]: \code{ConvertFun = c("sum", "mean", "sum"})) (Default: use the name of the column (See details) or "mean" for regime calculation)}
\item{YearFirstMonth}{(optional) [numeric] integer used when \code{Format = "\%Y"} to set when the starting month of the year (e.g. 01 for calendar year or 09 for hydrological year starting in September)}
......
  • @david.dorchies don't you find it is confusing for the user if getAggregConvertFun() is private? It means that he can't see what is the default values of the ConvertFun argument does: getAggregConvertFun(names(x)[-1])

    Edited by Delaigue Olivier
  • mentioned in issue #77 (closed)

    Toggle commit list
  • You are right. Since it is a default argument of ConvertFun argument of SeriesAggreg it should be documented. But I don't think that this function is useful for the user.

    The only information really useful for the user is the data.frame .AggregConvertFunTable which is already public.

    So I suggest to use an argument ConvertFunTable = .AggregConvertFunTable instead of ConvertFun = .AggregConvertFun(names(TabSeries)[-1]) in SeriesAggreg and to call the private function getAggregConvertFun(ConvertFunTable) in SeriesAggreg.

  • ... And .AggregConvertFunTable should be better documented either in the SeriesAggreg page or in a dedicated page.

  • In this case, why not just keep only the argument ConvertFun = NULL by default and explain in the help page that in this case it uses the table .AggregConvertFunTable. A ConvertFunTable argument will not be very easy to check. Don't you think so?

    Edited by Delaigue Olivier
  • A ConvertFunTable argument will not be very easy to check. Don't you think so?

    I don't think so. It involves only 4 conditions:

    if(!is.data.frame(ConvertFunTable) stop...
    if(names(ConvertFunTable) != c("ConvertFun", "Outputs")) stop...
    if(!all(ConvertFunTable$ConvertFun %in% c("mean", "sum"))) stop...
    if(!is.character(ConvertFunTable$Outputs)) stop

    I still think that exposing ConvertFunTable instead of ConvertFunis a better idea because:

    • it's more complicated for the user to write a ConvertFun function than modifying .AggregConvertFunTable or create is own two column-data.frame
    • now that you've added messages in getAggregConvertFun for unknown object, it should not be overwritten by the user in SeriesAggreg
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment