| Title: | Time Series Management and Analysis for Hydrological Modelling |
|---|---|
| Description: | S3 functions for management, analysis, interpolation and plotting of time series used in hydrology and related environmental sciences. In particular, this package is highly oriented to hydrological modelling tasks. The focus of this package has been put in providing a collection of tools useful for the daily work of hydrologists (although an effort was made to optimise each function as much as possible, functionality has had priority over speed). Bugs / comments / questions / collaboration of any kind are very welcomed, and in particular, datasets that can be included in this package for academic purposes. |
| Authors: | Mauricio Zambrano-Bigiarini [aut, cre, cph] (ORCID: <https://orcid.org/0000-0002-9536-643X>), Joschka Thurner [ctb] |
| Maintainer: | Mauricio Zambrano-Bigiarini <[email protected]> |
| License: | GPL (>=2) |
| Version: | 0.8-22 |
| Built: | 2026-10-11 13:13:44 UTC |
| Source: | https://github.com/hzambran/hydrotsm |
S3 functions for management, analysis, interpolation and plotting of time series used in hydrology and related environmental sciences. In particular, this package is highly oriented to hydrological modelling tasks. The focus of this package has been put in providing a collection of tools useful for the daily work of hydrologists (although an effort was made to optimise each function as much as possible, functionality has had priority over speed). Bugs / comments / questions / collaboration of any kind are very welcomed, and in particular, datasets that can be included in this package for academic purposes.
| Package: | hydroTSM |
| Type: | Package |
| Version: | 0.8-0 |
| Date: | 2026-04-27 |
| License: | GPL >= 2 |
| LazyLoad: | yes |
| Packaged: | Mon Apr 27 08:57:54 -04 2026 ; MZB |
| BuiltUnder: | R version 4.6.0 (2026-04-24) -- "Because it was There" ; aarch64-apple-darwin23 |
—————————————————————————————————————————
Datasets:
Cauquenes7336001 Hydrometeorological time series for "Cauquenes en El Arrayan" catchment. |
|
EbroPPtsMonthly Ebro Monthly Precipitation Time Series. |
|
KarameaAtGorgeQts Karamea at Gorge, time series of hourly streamflows. |
|
MaquehueTemuco San Martino, ts of daily precipitation. |
|
OcaEnOnaQts Oca in "Ona" (Q0931), time series of daily streamflows |
|
SanMartinoPPts San Martino, ts of daily precipitation. |
|
| --------------------------------------------------------------------------------------------------------------------------- |
Temporal aggregation:
annualfunction single representative annual value of a zoo object. |
|
weeklyfunction single representative weekly value of a zoo object. |
|
monthlyfunction single representative monthly value of a zoo object. |
|
seasonalfunction representative values of each weather season of a zoo object. |
|
daily2annual Aggregation from daily to annual |
|
subdaily2annual Aggregation from subdaily to annual. |
|
monthly2annual Aggregation from monthly to annual. |
|
daily2monthly Aggregation from daily to monthly. |
|
subdaily2monthly Aggregation from subdaily to monthly. |
|
submonthly2monthlyAggregation from hourly, daily, weekly or pseudo-weekly to monthly. |
|
daily2weekly Aggregation from daily to weekly. |
|
dm2seasonal Aggregation from daily or monthly to seasonal. |
|
subdaily2seasonal Aggregation from subdaily to seasonal. |
|
subdaily2daily Aggregation from subdaily to daily. |
|
subdaily2weekly Aggregation from subdaily to weekly. |
|
subhourly2hourly Aggregation from subhourly to hourly. |
|
subhourly2nhourly Aggregation from subhourly or hourly to n-hourly. |
|
subhourly2nminutesAggregation from subhourly to n-minutes. |
|
| --------------------------------------------------------------------------------------------------------------------------- |
Temporal manipulation:
dip Days in period. |
|
diy Days in year. |
|
hip Hours in period. |
|
mip Months in period. |
|
yip Years in period. |
|
izoo2rzoo Irregular zoo object to regular zoo objectl. |
|
time2season Time to weather season. |
|
vector2zoo Numeric and date/times to zoo object. |
|
| --------------------------------------------------------------------------------------------------------------------------- |
Hydrological functions:
baseflow Baseflow computation. |
|
climograph Climograph |
|
dwdays Dry and wet days. |
|
fdc Flow duration curve. |
|
fdcu Flow duration curve with uncertainty bounds. |
|
hydroplot Exploratory figure for hydrological time series. |
|
sname2plot Hydrological time series plotting and extraction. |
|
plot_pq Plot precipitation and streamflow time series in the same figure. |
|
si Seasonality Index for precipitation. |
|
spei Standardized Precipitation-Evapotranspiration Index. |
|
spi Standardized Precipitation Index for monthly precipitation. |
|
sname2ts Station Name -> Time Series. |
|
zoo2RHtest Zoo object -> RHTest. |
|
| --------------------------------------------------------------------------------------------------------------------------- |
Miscelaneous functions:
calendarHeatmap Calendar heat map. |
|
cmv Counting missing values. |
|
drawxaxis Draw a temporal horizontal axis. |
|
dwi Days with information. |
|
extract Extract a subset of a zoo object. |
|
hydropairs Visual correlation matrix. |
|
infillxy Infills NA values. |
|
istdx Inverse standarization. |
|
ma Moving average. |
|
matrixplot 2D color matrix. |
|
rm1stchar Remove first character. |
|
sfreq Sampling frequency. |
|
smry Improved summary function. |
|
stdx Standarization. |
|
| --------------------------------------------------------------------------------------------------------------------------- |
Mauricio Zambrano-Bigiarini
Maintainer: Mauricio Zambrano-Bigiarini <mzb.devel@gmail>
https://github.com/hzambran/hydroGOF.
https://github.com/hzambran/hydroPSO.
https://gitlab.com/rmarinao/hydroMOPSO.
## Loading the monthly time series (10 years) of precipitation for the Ebro River basin. data(EbroPPtsMonthly) ####### ## Ex1) Graphical correlation among the ts of monthly precipitation of the first ## 3 stations in 'EbroPPtsMonthly' (its first column stores the dates). hydropairs(EbroPPtsMonthly[,2:4]) ####### ## Ex2) Annual values of precipitation at the station "P9001" sname2ts(EbroPPtsMonthly, sname="P9001", dates=1, var.type="Precipitation", tstep.out="annual") ####### ## Ex3) Monthly and annual plots sname2plot(EbroPPtsMonthly, sname="P9001", var.type="Precipitation", pfreq="ma") ####### ## Ex5) Mean monthly values of streamflows ## Loading daily streamflows (3 years) at the station ## Oca en Ona (Ebro River basin, Spain) data(OcaEnOnaQts) monthlyfunction(OcaEnOnaQts, FUN=mean, na.rm=TRUE)## Loading the monthly time series (10 years) of precipitation for the Ebro River basin. data(EbroPPtsMonthly) ####### ## Ex1) Graphical correlation among the ts of monthly precipitation of the first ## 3 stations in 'EbroPPtsMonthly' (its first column stores the dates). hydropairs(EbroPPtsMonthly[,2:4]) ####### ## Ex2) Annual values of precipitation at the station "P9001" sname2ts(EbroPPtsMonthly, sname="P9001", dates=1, var.type="Precipitation", tstep.out="annual") ####### ## Ex3) Monthly and annual plots sname2plot(EbroPPtsMonthly, sname="P9001", var.type="Precipitation", pfreq="ma") ####### ## Ex5) Mean monthly values of streamflows ## Loading daily streamflows (3 years) at the station ## Oca en Ona (Ebro River basin, Spain) data(OcaEnOnaQts) monthlyfunction(OcaEnOnaQts, FUN=mean, na.rm=TRUE)
Generic function for transforming a (sub)DAILY/MONTHLY (weekly and quarterly) regular time series into an ANNUAL one.
daily2annual(x, ...) subdaily2annual(x, ...) monthly2annual(x, ...) ## Default S3 method: daily2annual(x, FUN, na.rm=TRUE, na.rm.max=0, out.fmt=c("%Y", "%Y-%m-%d"), start.month=1, ...) ## S3 method for class 'zoo' daily2annual(x, FUN, na.rm=TRUE, na.rm.max=0, out.fmt=c("%Y", "%Y-%m-%d"), start.month=1, ...) ## S3 method for class 'data.frame' daily2annual(x, FUN, na.rm=TRUE, na.rm.max=0, out.fmt=c("%Y", "%Y-%m-%d"), start.month=1, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...) ## S3 method for class 'matrix' daily2annual(x, FUN, na.rm = TRUE, na.rm.max=0, out.fmt=c("%Y", "%Y-%m-%d"), start.month=1, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...)daily2annual(x, ...) subdaily2annual(x, ...) monthly2annual(x, ...) ## Default S3 method: daily2annual(x, FUN, na.rm=TRUE, na.rm.max=0, out.fmt=c("%Y", "%Y-%m-%d"), start.month=1, ...) ## S3 method for class 'zoo' daily2annual(x, FUN, na.rm=TRUE, na.rm.max=0, out.fmt=c("%Y", "%Y-%m-%d"), start.month=1, ...) ## S3 method for class 'data.frame' daily2annual(x, FUN, na.rm=TRUE, na.rm.max=0, out.fmt=c("%Y", "%Y-%m-%d"), start.month=1, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...) ## S3 method for class 'matrix' daily2annual(x, FUN, na.rm = TRUE, na.rm.max=0, out.fmt=c("%Y", "%Y-%m-%d"), start.month=1, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...)
x |
zoo, data.frame or matrix object, with (sub)daily/monthly time series. |
FUN |
Function that have to be applied for aggregating from (sub)daily/monthly into annual time step (e.g., for precipitation
When |
na.rm |
Logical. Should missing values be removed? |
na.rm.max |
Numeric in [0, 1]. It is used to define the maximum percentage of missing values allowed in each year to keep the yearly aggregated value in the output object of this function. In other words, if the percentage of missing values in a given year is larger than |
out.fmt |
Character indicating the date format for the output zoo object. See |
start.month |
numeric in [1,..,12], representing the starting month (1:Jan, ..., 12:Dec) to be used in the computation of annual values. By default |
dates |
numeric, factor or Date object indicating how to obtain the dates for corresponding to each gauging station |
date.fmt |
character indicating the format in which the dates are stored in dates, e.g. %Y-%m-%d. See |
out.type |
Character that defines the desired type of output. Valid values are: |
verbose |
logical; if TRUE, progress messages are printed |
... |
arguments additional to |
When FUN!=max and FUN!=min the output is a zoo object with annual time frequency, where the time attribute has the format defined in out.fmt.
When FUN!=max and FUN!=min and out.fmt="%Y-%m-%d" the time attribute of the output zoo object will use the 1st of January of each year to create a full Date object from the corresponding year of each element of the output object (e.g., fi the year is 2022, the time attribute will be 2022-01-01). The only exception occurrs when FUN=max or FUN=min, where the time attribute of each element will correspond to the actual date where the annual maximum/minimum occurs (which is very useful for identifying the date of the annual maximum or the annual minimum of a time series).
When FUN=max or FUN=min and x is a single time series, the output is a zoo object with annual time frequency, where the time attribute has the same class than time(x), and the date(time) value corresponds to the date(time) where the maximum/minimum value actually occurs.
When FUN=max or FUN=min and x has two or more time series, the output is a list object where each element has an annual time frequency. The time attribute of each list element has the same class than time(x), and the date(time) value of each list element corresponds to the date(time) where the maximum/minimum value actually occurs.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
subhourly2hourly, daily2monthly, monthly2annual, hydroplot, annualfunction, vector2zoo, as.Date
###################### ## Ex1: Computation of annual values, removing any missing value in 'x' # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three months (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Agreggating from Daily to Annual, removing any missing value in 'x' ( a <- daily2annual(x, FUN=sum, na.rm=TRUE) ) ###################### ## Ex2: Compuation of annual values only when the percentage of NAs in each # year is lower than a user-defined percentage (10% in this example). # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three months (Jan/1921 - Mar/1921) x <- window(x, end="1921-12-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Daily to annual, only for months with less than 10% of missing values ( a2 <- daily2annual(x, FUN=sum, na.rm=TRUE, na.rm.max=0.1) ) # Verifying that the second and third month of 'x' had 10% or more of missing values cmv(x, tscale="annual") ###################### ## Ex3: Getting the annual maximum value, including the date where this annual ## maximum actually occurs daily2annual(x, FUN=max) ###################### ## Ex4: Monthly to Annual, allowing a maximum of 20% of missing values in each month m <- daily2monthly(x, FUN=sum, na.rm=TRUE, na.rm.max=0.2) monthly2annual(m, FUN=sum, na.rm=TRUE) ###################### ## Ex5: Loading the time series of HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Sub-daily to monthly ts subdaily2annual(x, FUN=mean, na.rm=TRUE) ############ ## Ex6: Loading the monthly time series of precipitation within the Ebro River basin data(EbroPPtsMonthly) # computing the annual values for the first 10 gauging stations in 'EbroPPtsMonthly' a <- monthly2annual(EbroPPtsMonthly[,1:11], FUN=sum, dates=1) # same as before, but with a nicer format of years a <- monthly2annual(EbroPPtsMonthly[,1:11], FUN=sum, dates=1, out.fmt="%Y")###################### ## Ex1: Computation of annual values, removing any missing value in 'x' # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three months (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Agreggating from Daily to Annual, removing any missing value in 'x' ( a <- daily2annual(x, FUN=sum, na.rm=TRUE) ) ###################### ## Ex2: Compuation of annual values only when the percentage of NAs in each # year is lower than a user-defined percentage (10% in this example). # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three months (Jan/1921 - Mar/1921) x <- window(x, end="1921-12-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Daily to annual, only for months with less than 10% of missing values ( a2 <- daily2annual(x, FUN=sum, na.rm=TRUE, na.rm.max=0.1) ) # Verifying that the second and third month of 'x' had 10% or more of missing values cmv(x, tscale="annual") ###################### ## Ex3: Getting the annual maximum value, including the date where this annual ## maximum actually occurs daily2annual(x, FUN=max) ###################### ## Ex4: Monthly to Annual, allowing a maximum of 20% of missing values in each month m <- daily2monthly(x, FUN=sum, na.rm=TRUE, na.rm.max=0.2) monthly2annual(m, FUN=sum, na.rm=TRUE) ###################### ## Ex5: Loading the time series of HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Sub-daily to monthly ts subdaily2annual(x, FUN=mean, na.rm=TRUE) ############ ## Ex6: Loading the monthly time series of precipitation within the Ebro River basin data(EbroPPtsMonthly) # computing the annual values for the first 10 gauging stations in 'EbroPPtsMonthly' a <- monthly2annual(EbroPPtsMonthly[,1:11], FUN=sum, dates=1) # same as before, but with a nicer format of years a <- monthly2annual(EbroPPtsMonthly[,1:11], FUN=sum, dates=1, out.fmt="%Y")
Generic functions for transforming daily, sub-daily, weekly, or pseudo-weekly time series into a MONTHLY one.
daily2monthly(x, ...) subdaily2monthly(x, ...) submonthly2monthly(x, ...) ## Default S3 method: daily2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, ...) ## S3 method for class 'zoo' daily2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, ...) ## S3 method for class 'data.frame' daily2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...) ## S3 method for class 'matrix' daily2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...) ## Default S3 method: submonthly2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, ...) ## S3 method for class 'zoo' submonthly2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, ...) ## S3 method for class 'data.frame' submonthly2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", tz=NULL, out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...) ## S3 method for class 'matrix' submonthly2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", tz=NULL, out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...)daily2monthly(x, ...) subdaily2monthly(x, ...) submonthly2monthly(x, ...) ## Default S3 method: daily2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, ...) ## S3 method for class 'zoo' daily2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, ...) ## S3 method for class 'data.frame' daily2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...) ## S3 method for class 'matrix' daily2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...) ## Default S3 method: submonthly2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, ...) ## S3 method for class 'zoo' submonthly2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, ...) ## S3 method for class 'data.frame' submonthly2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", tz=NULL, out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...) ## S3 method for class 'matrix' submonthly2monthly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", tz=NULL, out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...)
x |
zoo, data.frame or matrix object, with submonthly time series. |
FUN |
Function that have to be applied for transforming from daily to monthly time step (e.g., for precipitation
|
na.rm |
Logical. Should missing values be removed? |
na.rm.max |
Numeric in [0, 1]. It is used to define the maximum percentage of missing values allowed in each month to keep the monthly aggregated value in the output object of this function. In other words, if the percentage of missing values in a given month is larger than |
dates |
numeric, factor or Date object indicating how to obtain the dates for each gauging station. |
date.fmt |
character indicating the format in which the dates are stored in dates, e.g. %Y-%m-%d. See |
tz |
character, with the specification of the time zone used for parsing POSIXt dates when |
out.type |
Character that defines the desired type of output. Valid values are: |
out.fmt |
OPTIONAL. Only used when |
verbose |
logical; if TRUE, progress messages are printed |
... |
arguments additional to |
submonthly2monthly follows the output conventions of daily2monthly,
but it groups values directly by calendar month without requiring a regular
sampling frequency. This allows hourly, daily, weekly, and pseudo-weekly zoo
objects whose Date/POSIXt indexes are not regular enough for automatic frequency
detection. For na.rm.max, the percentage of missing values is computed
using the values observed within each month; missing unobserved regular time
steps are not inserted.
a zoo object with monthly time frequency
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
cmv, subhourly2hourly, daily2annual, subdaily2daily, monthlyfunction, hydroplot, vector2zoo, izoo2rzoo, as.Date
###################### ## Ex1: Computation of monthly values, removing any missing value in 'x' # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three months (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Agreggating from Daily to Monthly, removing any missing value in 'x' m <- daily2monthly(x, FUN=sum, na.rm=TRUE) ## Agreggating from Daily to Monthly, removing any missing value in 'x', but now ## allowing a maximum of 20% of missing values in each month m <- daily2monthly(x, FUN=sum, na.rm=TRUE, na.rm.max=0.2) ###################### ## Ex2: Computation of monthly values only when the percentage of NAs in each # month is lower than a user-defined percentage (10% in this example). # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three months (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Daily to monthly, only for months with less than 10% of missing values m2 <- daily2monthly(x, FUN=sum, na.rm=TRUE, na.rm.max=0.1) # Verifying that the second and third month of 'x' had 10% or more of missing values cmv(x, tscale="month") ###################### ## Ex3: Loading the HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Sub-daily to monthly ts subdaily2monthly(x, FUN=mean, na.rm=TRUE) ###################### ## Ex4: Pseudo-weekly dates aggregated directly to monthly values dates <- as.Date(c("2023-01-01", "2023-01-08", "2023-01-15", "2023-01-23", "2023-02-01", "2023-02-10")) x <- zoo(c(1, 2, 3, 4, 5, 6), dates) submonthly2monthly(x, FUN=sum, na.rm=TRUE)###################### ## Ex1: Computation of monthly values, removing any missing value in 'x' # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three months (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Agreggating from Daily to Monthly, removing any missing value in 'x' m <- daily2monthly(x, FUN=sum, na.rm=TRUE) ## Agreggating from Daily to Monthly, removing any missing value in 'x', but now ## allowing a maximum of 20% of missing values in each month m <- daily2monthly(x, FUN=sum, na.rm=TRUE, na.rm.max=0.2) ###################### ## Ex2: Computation of monthly values only when the percentage of NAs in each # month is lower than a user-defined percentage (10% in this example). # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three months (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Daily to monthly, only for months with less than 10% of missing values m2 <- daily2monthly(x, FUN=sum, na.rm=TRUE, na.rm.max=0.1) # Verifying that the second and third month of 'x' had 10% or more of missing values cmv(x, tscale="month") ###################### ## Ex3: Loading the HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Sub-daily to monthly ts subdaily2monthly(x, FUN=mean, na.rm=TRUE) ###################### ## Ex4: Pseudo-weekly dates aggregated directly to monthly values dates <- as.Date(c("2023-01-01", "2023-01-08", "2023-01-15", "2023-01-23", "2023-02-01", "2023-02-10")) x <- zoo(c(1, 2, 3, 4, 5, 6), dates) submonthly2monthly(x, FUN=sum, na.rm=TRUE)
Generic function for obtaining a SINGLE annual value of a zoo object, by applying any R function to ALL the values in x belonging to the same year, and then applying the same function to ALL the previously computed annual values (e.g., for computing the average annual precipitation or the mean annual streamflow of a long-term time series).
annualfunction(x, FUN, na.rm = TRUE, ...) ## Default S3 method: annualfunction(x, FUN, na.rm = TRUE, ...) ## S3 method for class 'zoo' annualfunction(x, FUN, na.rm = TRUE, ...) ## S3 method for class 'data.frame' annualfunction(x, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", verbose = TRUE, ...) ## S3 method for class 'matrix' annualfunction(x, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", verbose = TRUE, ...)annualfunction(x, FUN, na.rm = TRUE, ...) ## Default S3 method: annualfunction(x, FUN, na.rm = TRUE, ...) ## S3 method for class 'zoo' annualfunction(x, FUN, na.rm = TRUE, ...) ## S3 method for class 'data.frame' annualfunction(x, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", verbose = TRUE, ...) ## S3 method for class 'matrix' annualfunction(x, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", verbose = TRUE, ...)
x |
zoo, xts, data.frame or matrix object, with daily/monthly/annual time series. |
FUN |
Function that will be used to compute the final annual value (e.g., |
na.rm |
Logical. Should missing values be removed?. |
dates |
numeric, factor or Date object indicating how to obtain the dates corresponding to each gauging station. |
date.fmt |
character indicating the format in which the dates are stored in dates, e.g. %Y-%m-%d. See |
verbose |
Logical; if TRUE, progress messages are printed. |
... |
further arguments passed to or from other methods. |
When x is a time series, a single annual value is returned.
For a data frame, a named vector with the appropriate method being applied column by column.
FUN is first applied to all the values of x belonging to the same year and then it is applied to all the previously computed annual values to get the final result.
Its result will depend on the sampling frequency of x and the type of function provided by FUN (special attention have to be put when FUN=sum)
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
monthlyfunction, daily2annual, monthly2annual, yip
## Loading the SanMartino daily precipitation data (1921-1990) data(SanMartinoPPts) x <- SanMartinoPPts # Amount of years in 'x' (needed for computing the average) nyears <- length( seq(from=time(x[1]), to=time(x[length(x)]), by="years") ) ## Average annual precipitation for the 70 years period. # It is necessary to divide by the amount of years to obtain the average annual value, # otherwise it will give the total precipitation for all the 70 years. annualfunction(x, FUN=sum, na.rm=TRUE) / nyears ##################### ### verification #### # Daily to annual a <- daily2annual(x, FUN=sum, na.rm=TRUE) # Mean annual value mean(a) ############################## ############################## ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) x <- EbroPPtsMonthly ## Dates of 'x' dates <- as.Date(x[,1]) ## Computation of the average annual precipitation ## Not run: ## Transforming 'x' into a zoo object z <- zoo( x[, 2:ncol(x)], dates) # Amount of years in 'x' (needed for computing the average) nyears <- yip(from=start(z), to=end(z), out.type="nmbr" ) ## Average annual precipitation, for the first 5 stations in 'x' annualfunction(z[ ,1:5], FUN=sum)/nyears ## End(Not run)## Loading the SanMartino daily precipitation data (1921-1990) data(SanMartinoPPts) x <- SanMartinoPPts # Amount of years in 'x' (needed for computing the average) nyears <- length( seq(from=time(x[1]), to=time(x[length(x)]), by="years") ) ## Average annual precipitation for the 70 years period. # It is necessary to divide by the amount of years to obtain the average annual value, # otherwise it will give the total precipitation for all the 70 years. annualfunction(x, FUN=sum, na.rm=TRUE) / nyears ##################### ### verification #### # Daily to annual a <- daily2annual(x, FUN=sum, na.rm=TRUE) # Mean annual value mean(a) ############################## ############################## ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) x <- EbroPPtsMonthly ## Dates of 'x' dates <- as.Date(x[,1]) ## Computation of the average annual precipitation ## Not run: ## Transforming 'x' into a zoo object z <- zoo( x[, 2:ncol(x)], dates) # Amount of years in 'x' (needed for computing the average) nyears <- yip(from=start(z), to=end(z), out.type="nmbr" ) ## Average annual precipitation, for the first 5 stations in 'x' annualfunction(z[ ,1:5], FUN=sum)/nyears ## End(Not run)
Given a complete (without missing values) series of streamflow, this function computes the baseflow using the filter proposed by Arnold and Allen (1999).
baseflow(x, ...) ## S3 method for class 'zoo' baseflow(x, beta=0.925, from=start(x), to=end(x), n.pass=3L, pass.start=c("forward", "backward"), date.fmt, tz, na.fill=c("none", "linear", "spline"), out.type=c("last", "all"), plot=TRUE, xcol="black", bfcol=c("blue", "darkcyan", "darkorange3"), pch=15, cex=0.3, ...)baseflow(x, ...) ## S3 method for class 'zoo' baseflow(x, beta=0.925, from=start(x), to=end(x), n.pass=3L, pass.start=c("forward", "backward"), date.fmt, tz, na.fill=c("none", "linear", "spline"), out.type=c("last", "all"), plot=TRUE, xcol="black", bfcol=c("blue", "darkcyan", "darkorange3"), pch=15, cex=0.3, ...)
x |
zoo or numeric object with streamflow records. The suggested time frequency should be hourly or daily, but the algorithm will work with any time frequency. |
beta |
numeric representing the filter parameter. Default value is 0.925 as recommended by Arnold and Allen (1999) |
from |
Character indicating the starting date for subsetting |
to |
Character indicating the ending date for subsetting |
n.pass |
Integer indicating the number times the filter will be passed over the streamflow data stored in |
pass.start |
Character indicating the direction of the first pass of the filter. Subsequent passes alternate direction (e.g., forward-backward). Valid values are: |
date.fmt |
character indicating the format in which the dates are stored in |
tz |
character, with the specification of the time zone used for If This argument can be used when working with sub-daily zoo objects to force using time zones other than the local time zone for |
na.fill |
Character indicating how to fill any NA present in |
out.type |
Character indicating the type of result that is given by this function. Valid values are: |
plot |
logical. Indicates if the baseflow should be plotted or not. If plotted, the original |
xcol |
character, representing the color to be used for ploting the streamflow time series. Only used when |
bfcol |
character of lenght 3, representing the color(s) to be used for ploting the baseflow time series. The first, second and third element are used to represent the baseflow after the third, second and first pass of the filter, respectively. Only used when |
pch |
numeric, representing the symbols used for ploting the streamflow time series (both, the original series and the baseflow). Only used when |
cex |
a numerical vector giving the amount by which plotting characters and symbols should be scaled relative to the default. This works as a multiple of |
... |
further arguments passed to or from other methods. Not used yet. |
Although most procedures to separate baseflow from total streamflow are based on physical reasoning, some elements of all separation techniques are subjective.
The digital filter technique (Nathan and McMahon, 1990) implemented in this function was originally proposed by Lyne and Hollick (1979) for signal analysis and processing. Although this technique has no true physical meaning, it is objective and reproducible.
The equation of the filter is:
q(t) = Beta*q(t-1) + [ (1+Beta)/2 ]*[ Q(t) - Q(t-1) ]
where q(t) is the filtered surface runoff (quick response) at the time step t (one day), Q is the original streamflow, and Beta is the filter parameter (Beta=0.925). The value Beta=0.925 was obtained by Nathan and McMahon (1990) and Arnold et al. (1995) to give realistic results when compared to manual separation techniques.
Baseflow b(t) is then computed as:
b(t) = Q(t) - q(t)
The filter can be passed over the streamflow data three times (forward, backward, and forward), depending on the user' selected estimates of baseflow from pilot studies. In general, each pass will result in less baseflow as a percentage of total streamflow.
If out.type="last" |
(default value), only the baseflow computed after the third pass of the filter is returned. |
If out.type="all" |
the 3 baseflows computed after each pass of the filter are returned in a matrix or zoo object. |
Mauricio Zambrano-Bigiarini, mzb.devel@gmail ; Hector Garces-Figueroa
Arnold, J. G., Allen, P. M., Muttiah, R., Bernhardt, G. (1995). Automated base flow separation and recession analysis techniques. Groundwater, 33(6), 1010–1018. doi:10.1111/j.1745-6584.1995.tb00046.x.
Arnold, J. G., Allen, P. M. (1999). Automated methods for estimating baseflow and ground water recharge from streamflow records. JAWRA Journal of the American Water Resources Association, 35(2), 411–424. doi:10.1111/j.1752-1688.1999.tb03599.x.
Lyne, V., Hollick, M. (1979). Stochastic time-variable rainfall-runoff modelling. Proceedings of the Hydrology and Water Resources Symposium, Perth, 10–12 September. Institution of Engineers National Conference Publication, No. 79/10, 89–92.
Nathan, R. J., & McMahon, T. A. (1990). Evaluation of automated techniques for base flow and recession analyses. Water resources research, 26(7), 1465–1473. doi:10.1029/WR026i007p01465.
Ladson, A. R., Brown, R., Neal, B., & Nathan, R. (2013). A standard approach to baseflow separation using the Lyne and Hollick filter. Australasian Journal of Water Resources, 17(1), 25-34. doi:10.7158/13241583.2013.11465417.
###################### ## Ex1: Computing and plotting the baseflows for the full time period ## of a given time series of streamflows. ## First, we load the daily Q time series for the Cauquenes en ## El Arrayan catchment, where Q, [m3/s] are stored in the sixth column. data(Cauquenes7336001) q <- Cauquenes7336001[, 6] ## Computing the daily baseflow for the full time period #baseflow(q) # it can not run due to NA values in 'x' # filling the NA values using spline interpolation baseflow(q, na.fill="spline") ## Computing and plotting the daily baseflow for the full time period baseflow(q, na.fill="spline", plot=TRUE) ###################### ## Ex2: Computing and plotting the daily baseflow only for a ## specific time period, from April to December 2000. baseflow(q, na.fill="spline", from="2000-04-01", to="2000-12-31") ###################### ## Ex3: Computing and plotting the three daily baseflows (one for each pass ## of the filter) only for a specific time period, from April to December ## 2000. baseflow(q, na.fill="spline", from="2000-04-01", to="2000-12-31", out.type="all", plot=TRUE)###################### ## Ex1: Computing and plotting the baseflows for the full time period ## of a given time series of streamflows. ## First, we load the daily Q time series for the Cauquenes en ## El Arrayan catchment, where Q, [m3/s] are stored in the sixth column. data(Cauquenes7336001) q <- Cauquenes7336001[, 6] ## Computing the daily baseflow for the full time period #baseflow(q) # it can not run due to NA values in 'x' # filling the NA values using spline interpolation baseflow(q, na.fill="spline") ## Computing and plotting the daily baseflow for the full time period baseflow(q, na.fill="spline", plot=TRUE) ###################### ## Ex2: Computing and plotting the daily baseflow only for a ## specific time period, from April to December 2000. baseflow(q, na.fill="spline", from="2000-04-01", to="2000-12-31") ###################### ## Ex3: Computing and plotting the three daily baseflows (one for each pass ## of the filter) only for a specific time period, from April to December ## 2000. baseflow(q, na.fill="spline", from="2000-04-01", to="2000-12-31", out.type="all", plot=TRUE)
Function to plot a heatmap of a daily zoo object with a calendar shape
calendarHeatmap(x, ...) ## S3 method for class 'zoo' calendarHeatmap(x, from, to, date.fmt="%Y-%m-%d", main="Calendar Heat Map", col=colorRampPalette(c("red", "orange", "yellow", "white", "lightblue2", "deepskyblue", "blue3"), space = "Lab")(8), cuts, cuts.dec=0, cuts.labels, cuts.style=c("fisher", "equal", "pretty", "fixed", "sd", "quantile", "kmeans", "bclust", "mzb"), legend.title="", legend.fontsize=15, do.png=FALSE, png.fname="mypng.png", png.width=1500, png.height=900, png.pointsize=12, png.res=90, do.pdf=FALSE, pdf.fname="mypdf.pdf", pdf.width=11, pdf.height=8.5, pdf.pointsize=12, ...)calendarHeatmap(x, ...) ## S3 method for class 'zoo' calendarHeatmap(x, from, to, date.fmt="%Y-%m-%d", main="Calendar Heat Map", col=colorRampPalette(c("red", "orange", "yellow", "white", "lightblue2", "deepskyblue", "blue3"), space = "Lab")(8), cuts, cuts.dec=0, cuts.labels, cuts.style=c("fisher", "equal", "pretty", "fixed", "sd", "quantile", "kmeans", "bclust", "mzb"), legend.title="", legend.fontsize=15, do.png=FALSE, png.fname="mypng.png", png.width=1500, png.height=900, png.pointsize=12, png.res=90, do.pdf=FALSE, pdf.fname="mypdf.pdf", pdf.width=11, pdf.height=8.5, pdf.pointsize=12, ...)
x |
daily zoo object to be plotted. Its maximum amount of daily data should be less than 6 years or otherwise it will not be plotted. |
from |
Character indicating the starting date for subsetting |
to |
Character indicating the ending date for subsetting |
date.fmt |
character indicating the format in which the dates are stored in |
main |
character, Main chart title. |
col |
A color palette, i.e. a vector of n contiguous colors generated by functions like rainbow, heat.colors, topo.colors, bpy.colors or one of your own making, perhaps using |
cuts |
Numeric, indicating the values used to divide the range of |
cuts.dec |
Number of decimal places used to present the numbers in the legend of colours. |
cuts.labels |
Character indicating the label to be used in the colour legend for each one of the values defined by |
cuts.style |
discarded because takes too much time or not alway provide the required number of classes: "dpih", "headtails", "hclust", "jenks". |
legend.title |
text to be displayed above the legend of colours. |
legend.fontsize |
size of text (in points) used in the legend of colours. |
do.png |
Do you want to write the figure as a .png file? logical, set TRUE to save the image. |
png.fname |
character, indicating the name of the file (possibly with a meaninful file extension) that will be used to write the output file. |
png.width |
numeric, the width of the device. |
png.height |
numeric, the height of the device. |
png.pointsize |
integer, the default pointsize of plotted text, interpreted as big points (1/72 inch) at |
png.res |
integer, the nominal resolution in ppi which will be recorded in the bitmap file, if a positive integer. Also used for units other than the default, and to convert points to pixels. |
do.pdf |
Do you want to write the figure as a .pdf file? logical, set TRUE to save the image. |
pdf.fname |
character, indicating the name of the file (possibly with a significant extension) that will be used to write the output file. |
pdf.width |
numeric, the width of the device. |
pdf.height |
numeric, the height of the device. |
pdf.pointsize |
integer, the default point size to be used. Strictly speaking, in bp, that is 1/72 of an inch, but approximately in points. Defaults to 12. |
... |
further arguments passed to functions or from other methods. Not used yet. |
The original function calendarHeat was developed by Paul Bleicher, as an R version of a graphic from http://stat-computing.org/dataexpo/2009/posters/wicklin-allison.pdf (not available any longer).
The original function was made available online in 2009, but then it was removed. Now it is available at https://github.com/tavisrudd/r_users_group_1/blob/master/calendarHeat.R.
The original function has "Copyright 2009 Humedica", but it was distributed under the GPL-2 licence, as well as this new version of the function.
This slighly modified verison of the function is also distributed under the GPL-2 licence, and teh main changes with respect to the original function are:
1) uses a zoo object instead of a numeric and character vector, for values and dates, respectively.
2) it allows a customisation of the mian title of the output figure.
3) it allows a customisation of the color palette.
4) it uses a categorical legend instead of a continuos one.
5) it is named calendarHeatmap instead of calendarHeat.
The output of this function is a lattice figure with the calendar heatmap
The maximum amount of years to be plotted is six (6).
Mauricio Zambrano-Bigiarini, [email protected]
########### # EXAMPLE 1: basic plotting of a calendar heatmap ########### # Loading daily streamflow data for Karamet at Gorges. data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts x <- subdaily2daily(x, FUN=mean) # Temporal subsetting for a amaximum of 6 years x <- window(x, start="1980-01-01", end="1985-12-31") # Calendar Heatmap, 8 colours and cuts defined using Fisher method calendarHeatmap(x)########### # EXAMPLE 1: basic plotting of a calendar heatmap ########### # Loading daily streamflow data for Karamet at Gorges. data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts x <- subdaily2daily(x, FUN=mean) # Temporal subsetting for a amaximum of 6 years x <- window(x, start="1980-01-01", end="1985-12-31") # Calendar Heatmap, 8 colours and cuts defined using Fisher method calendarHeatmap(x)
Daily time series of precipitation, maximum air temperature, minimum air temperature, potential evapotranspiration, and observed streamflows for the catchment draining into the 'Cauquenes en El Arrayan' streamflow station (Cod.BNA: 7336001, Lat:-36.02, Lon:-72.38). This catchment is located in El Maule Region in Chile, with a pluvial regime, a total drainage area of 622.1 km2, and elevations ranging from 134 to 736 m a.s.l. Data were downloaded from the CAMELS-CL dataset (https://camels.cr2.cl) from 01/Jan/1979 to 31/Dec/2019 (including some missing values).
data(Cauquenes7336001)data(Cauquenes7336001)
zoo matrix with 5 time series:
-) P_mm: Spatially-averaged mean daily values of precipitation computed based on the CR2met dataset, [mm/day].
-) Tmx_degC: Spatially-averaged maximum daily values of air temperature computed based on the CR2met dataset, [degree Celsius].
-) Tmin_degC: Spatially-averaged minimum daily values of air temperature computed based on the CR2met dataset, [degree Celsius].
-) PET_mm: Spatially-averaged mean daily values of precipitation computed based on the Hargreaves-Samani equation and daily maximum and minimum air temperatures obtained from the CR2met dataset, [mm/day].
-) Qobs_mm: Daily sreamflows, [mm], measured at the "Cauquenes en El Arrayan" (7336001) station.
-) Qobs_m3s: Daily sreamflows, [m3/s], measured at the "Cauquenes en El Arrayan" (7336001) station.
Provided by Center for Climate and Resilience Research, Universidad de Chile, Santiago, Chile (https://camels.cr2.cl/, last accessed [Nov 2023]).
These data are intended to be used for research purposes only, being distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.
Alvarez-Garreton, C., Mendoza, P. A., Boisier, J. P., Addor, N., Galleguillos, M., Zambrano-Bigiarini, M., Lara, A., Puelma, C., Cortes, G., Garreaud, R., McPhee, J., and Ayala, A (2018). The CAMELS-CL dataset: catchment attributes and meteorology for large sample studies-Chile dataset. Hydrology and Earth System Sciences, 22(11), 5817-5846. doi:10.5194/hess-22-5817-2018.
Changes the time zone used by the time index of a sub-daily zoo object
whose index inherits from POSIXct or POSIXlt.
change_tz(x, ...) ## S3 method for class 'zoo' change_tz(x, new.tz, old.tz=NULL, ...)change_tz(x, ...) ## S3 method for class 'zoo' change_tz(x, new.tz, old.tz=NULL, ...)
x |
|
new.tz |
character. Time zone to assign to the output time index. |
old.tz |
character or |
... |
further arguments passed to or from other methods. |
Both old.tz and new.tz are checked against
OlsonNames.
change_tz() preserves the represented instants and changes their time
zone for display and downstream calendar grouping. For example, midnight UTC is
shown as the previous evening in "America/Santiago" when the applicable
UTC offset is negative. It does not reinterpret clock labels in a new time zone.
The values and dimensions of x are preserved; only the time index is
changed.
A zoo object with the same values as x, but with its time index
converted to new.tz.
Mauricio Zambrano-Bigiarini, [email protected]
zoo, OlsonNames,
as.POSIXct, subhourly2hourly,
subhourly2nhourly, subdaily2daily
dates <- seq(as.POSIXct("2001-01-01 00:00:00", tz="UTC"), by="hour", length.out=3) x <- zoo(1:3, dates) y <- change_tz(x, new.tz="America/Santiago") time(y) ## The represented instants and the observed values are preserved. identical(as.numeric(time(x)), as.numeric(time(y))) identical(coredata(x), coredata(y))dates <- seq(as.POSIXct("2001-01-01 00:00:00", tz="UTC"), by="hour", length.out=3) x <- zoo(1:3, dates) y <- change_tz(x, new.tz="America/Santiago") time(y) ## The represented instants and the observed values are preserved. identical(as.numeric(time(x)), as.numeric(time(y))) identical(coredata(x), coredata(y))
Function to draw a climograph based on precipitation and air temperature data, with several options for customisation.
climograph(pcp, tmean, tmx, tmn, na.rm=TRUE, from, to, date.fmt="%Y-%m-%d", main="Climograph", pcp.label="Precipitation, [mm]", tmean.label="Air temperature, [\U00B0 C]", start.month=1, pcp.solid.thr, pcp.ylim, temp.ylim,pcp.col="lightblue", pcp.solid.col="skyblue2", tmean.col="darkred", tmn.col="blue", tmx.col="red", pcp.labels=TRUE, tmean.labels=TRUE, tmx.labels=TRUE, tmn.labels=TRUE, pcp.labels.cex=0.8, temp.labels.cex=0.8, pcp.labels.dx=c(rep(ifelse(plot.pcp.probs, -0.25, 0.0),6), rep(ifelse(plot.pcp.probs, -0.25, 0.0),6)), pcp.labels.dy=rep(2, 12), temp.labels.dx=c(rep(-0.2,6), rep(0.2,6)), temp.labels.dy=rep(-0.4, 12), plot.pcp.probs=TRUE, pcp.probs=c(0.25, 0.75), plot.temp.probs=TRUE, temp.probs=c(0.25, 0.75), temp.probs.col=c("#3399FF", "#FF9966", "#FFCC66"), temp.probs.alpha=0.3, lat, lon )climograph(pcp, tmean, tmx, tmn, na.rm=TRUE, from, to, date.fmt="%Y-%m-%d", main="Climograph", pcp.label="Precipitation, [mm]", tmean.label="Air temperature, [\U00B0 C]", start.month=1, pcp.solid.thr, pcp.ylim, temp.ylim,pcp.col="lightblue", pcp.solid.col="skyblue2", tmean.col="darkred", tmn.col="blue", tmx.col="red", pcp.labels=TRUE, tmean.labels=TRUE, tmx.labels=TRUE, tmn.labels=TRUE, pcp.labels.cex=0.8, temp.labels.cex=0.8, pcp.labels.dx=c(rep(ifelse(plot.pcp.probs, -0.25, 0.0),6), rep(ifelse(plot.pcp.probs, -0.25, 0.0),6)), pcp.labels.dy=rep(2, 12), temp.labels.dx=c(rep(-0.2,6), rep(0.2,6)), temp.labels.dy=rep(-0.4, 12), plot.pcp.probs=TRUE, pcp.probs=c(0.25, 0.75), plot.temp.probs=TRUE, temp.probs=c(0.25, 0.75), temp.probs.col=c("#3399FF", "#FF9966", "#FFCC66"), temp.probs.alpha=0.3, lat, lon )
pcp |
variable of type zoo with monthly, daily or subdaily precipitation data. |
tmean |
variable of type 'zoo' with monthly, daily or subdaily mean temperature data. |
tmx |
variable of type 'zoo' with monthly, daily or subdaily maximum temperature data. |
tmn |
variable of type 'zoo' with monthly, daily or subdaily minimum temperature data.
ONLY used (together with |
na.rm |
Logical. Should missing values be removed? |
from |
OPTIONAL, used for extracting a subset of values. |
to |
OPTIONAL, used for extracting a subset of values. |
date.fmt |
Character indicating the format in which the dates are stored in dates, from and to. See |
main |
Character representing the main title of the plot. |
pcp.label |
Character used in the legend to represent the monthly average precipitation (mostly thought for languages different from English). |
tmean.label |
Character used in the legend to represent the monthly average temperature (mostly thought for languages different from English). |
start.month |
[OPTIONAL]. Only used when the (hydrological) year of interest is different from the calendar year. numeric in [1:12] indicating the starting month of the (hydrological) year. Numeric values in [1, 12] represents months in [January, December]. By default |
pcp.solid.thr |
[OPTIONAL]. Only used when using (sub)daily precipitation and temperature are gives as input data. When daily |
pcp.ylim |
[OPTIONAL] numeric of length 2 with the the range used for the precipitation axis. The second value should be larger than the first one. |
temp.ylim |
[OPTIONAL] numeric of length 2 with the the range used for the secondary temperature axis. The second value should be larger than the first one. |
pcp.col |
Color used in the legend to represent the monthly average precipitation. |
pcp.solid.col |
Color used in the legend to represent the monthly average solid precipitation. |
tmean.col |
Color used in the legend to represent the monthly average temperature. |
tmn.col |
Color used in the legend to represent the monthly minimum temperature. |
tmx.col |
Color used in the legend to represent the monthly maximum temperature. |
pcp.labels |
logical. Should monthly precipitation values to be shown above the bars?. By default |
tmean.labels |
logical. Should monthly mean temperature values to be shown above the lines?. By default |
tmx.labels |
logical. Should monthly maximum temperature values to be shown above the lines?. By default |
tmn.labels |
logical. Should monthly minimum temperature values to be shown above the lines?. By default |
pcp.labels.cex |
numeric giving the amount by which plotting characters used to show the numeric values of monthly precipitation values are scaled relative to the default. |
temp.labels.cex |
numeric giving the amount by which plotting characters used to show the numeric values of monthly air temperature values (mean, maximum, minimum) are scaled relative to the default. |
pcp.labels.dx |
numeric of length 12 giving the amount of horizontal coordinate positions that have to be used to shift the labels of monthly precipitation values. |
pcp.labels.dy |
numeric of length 12 giving the amount of vertical coordinate positions that have to be used to shift the labels of monthly precipitation values. |
temp.labels.dx |
numeric of length 12 giving the amount of horizontal coordinate positions that have to be used to shift the labels of monthly air temperature values (mean, maximum, minimum). |
temp.labels.dy |
numeric of length 12 giving the amount of vertical coordinate positions that have to be used to shift the labels of monthly air temperature values (mean, maximum, minimum). |
plot.pcp.probs |
logical used to decide whether to show uncertainty values around the monthly mean precipitation values. By default |
pcp.probs |
numeric of length 2. It defines the quantile values used to compute the lower an upper uncertainty bounds for each one of the 12 monthly precipitation values. |
plot.temp.probs |
logical used to decide whether to show uncertainty values around the monthly mean temperature values. By default |
temp.probs |
numeric of length 2. It is used to define quantile values used to compute the lower an upper uncertainty bounds for each one of the 12 monthly mean temperature values. |
temp.probs.col |
character of length 3, with the colors used to for plotting the uncertainty bands around the average monthly values of the minimum, mean and maximum air temperature, respectively. |
temp.probs.alpha |
numeric of length 1, with the factor used to modify the opacity of |
lat |
[OPTIONAL] numeric or character used to show the latitude for which the climograph was plotted for. |
lon |
[OPTIONAL] numeric or character used to show the longitude for which the climograph was plotted for. |
If the output climograph present some mixed or not legible characters, you might try resizing the graphical window and run climograph again with the new size, until you get the climograph in the way you want to.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
###################### ## Ex1: Loading the DAILY precipitation, maximum and minimum air temperature at ## station Maquehue Temuco Ad (Chile) data(MaquehueTemuco) # Subsetting to only the 1981-1990 temporal period MaquehueTemuco <- window(MaquehueTemuco, start="1981-01-01", end="1990-12-31") pcp <- MaquehueTemuco[, 1] tmx <- MaquehueTemuco[, 2] tmn <- MaquehueTemuco[, 3] ## Plotting a full climograph m <- climograph(pcp=pcp, tmx=tmx, tmn=tmn, na.rm=TRUE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Not run: ## Plotting a climograph with uncertainty bands around mean values, ## but with no labels for tmx and tmn m <- climograph(pcp=pcp, tmx=tmx, tmn=tmn, na.rm=TRUE, tmx.labels=FALSE, tmn.labels=FALSE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Plotting a climograph with uncertainty bands around mean values, but with no labels for ## tmx, tmn and pcp m <- climograph(pcp=pcp, tmx=tmx, tmn=tmn, na.rm=TRUE, pcp.labels=FALSE, tmean.labels=FALSE, tmx.labels=FALSE, tmn.labels=FALSE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Plotting a climograph with no uncertainty bands around mean values m <- climograph(pcp=pcp, tmx=tmx, tmn=tmn, na.rm=TRUE, plot.pcp.probs=FALSE, plot.temp.probs=FALSE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Plotting the most basic climograph: only mean values of precipiation and air temperature m <- climograph(pcp=pcp, tmean=0.5*(tmn+tmx), na.rm=TRUE, plot.pcp.probs=FALSE, plot.temp.probs=FALSE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Plotting a full climograph, starting in April (start.month=4) instead of January (start.month=1), ## to better represent the hydrological year in Chile (South America) m <- climograph(pcp=pcp, tmx=tmx, tmn=tmn, na.rm=TRUE, start.month=4, temp.labels.dx=c(rep(-0.2,4), rep(0.2,6),rep(-0.2,2)), main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Plotting a full climograph with monthly data pcp.m <- daily2monthly(pcp, FUN=sum) tmx.m <- daily2monthly(tmx, FUN=mean) tmn.m <- daily2monthly(tmn, FUN=mean) m <- climograph(pcp=pcp.m, tmx=tmx.m, tmn=tmn.m, na.rm=TRUE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## End(Not run)###################### ## Ex1: Loading the DAILY precipitation, maximum and minimum air temperature at ## station Maquehue Temuco Ad (Chile) data(MaquehueTemuco) # Subsetting to only the 1981-1990 temporal period MaquehueTemuco <- window(MaquehueTemuco, start="1981-01-01", end="1990-12-31") pcp <- MaquehueTemuco[, 1] tmx <- MaquehueTemuco[, 2] tmn <- MaquehueTemuco[, 3] ## Plotting a full climograph m <- climograph(pcp=pcp, tmx=tmx, tmn=tmn, na.rm=TRUE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Not run: ## Plotting a climograph with uncertainty bands around mean values, ## but with no labels for tmx and tmn m <- climograph(pcp=pcp, tmx=tmx, tmn=tmn, na.rm=TRUE, tmx.labels=FALSE, tmn.labels=FALSE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Plotting a climograph with uncertainty bands around mean values, but with no labels for ## tmx, tmn and pcp m <- climograph(pcp=pcp, tmx=tmx, tmn=tmn, na.rm=TRUE, pcp.labels=FALSE, tmean.labels=FALSE, tmx.labels=FALSE, tmn.labels=FALSE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Plotting a climograph with no uncertainty bands around mean values m <- climograph(pcp=pcp, tmx=tmx, tmn=tmn, na.rm=TRUE, plot.pcp.probs=FALSE, plot.temp.probs=FALSE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Plotting the most basic climograph: only mean values of precipiation and air temperature m <- climograph(pcp=pcp, tmean=0.5*(tmn+tmx), na.rm=TRUE, plot.pcp.probs=FALSE, plot.temp.probs=FALSE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Plotting a full climograph, starting in April (start.month=4) instead of January (start.month=1), ## to better represent the hydrological year in Chile (South America) m <- climograph(pcp=pcp, tmx=tmx, tmn=tmn, na.rm=TRUE, start.month=4, temp.labels.dx=c(rep(-0.2,4), rep(0.2,6),rep(-0.2,2)), main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## Plotting a full climograph with monthly data pcp.m <- daily2monthly(pcp, FUN=sum) tmx.m <- daily2monthly(tmx, FUN=mean) tmn.m <- daily2monthly(tmn, FUN=mean) m <- climograph(pcp=pcp.m, tmx=tmx.m, tmn=tmn.m, na.rm=TRUE, main="Maquehue Temuco Ad (Chile)", lat=-38.770, lon=-72.637) ## End(Not run)
Generic function for counting the percentage/amount of missing values in a zoo object, using a user-defined temporal scale.
cmv(x, ...) ## Default S3 method: cmv(x, tscale=c("hourly", "daily", "weekly", "monthly", "quarterly", "seasonal", "annual"), out.type=c("percentage", "amount"), dec=3, start="00:00:00", start.fmt= "%H:%M:%S", tz, start.month=1, ...) ## S3 method for class 'zoo' cmv(x, tscale=c("hourly", "daily", "weekly", "monthly", "quarterly", "seasonal", "annual"), out.type=c("percentage", "amount"), dec=3, start="00:00:00", start.fmt= "%H:%M:%S", tz, start.month=1, ...) ## S3 method for class 'data.frame' cmv(x, tscale=c("hourly", "daily", "weekly", "monthly", "quarterly", "seasonal", "annual"), out.type=c("percentage", "amount"), dec=3, start="00:00:00", start.fmt= "%H:%M:%S", tz, start.month=1, dates=1, date.fmt="%Y-%m-%d", ...) ## S3 method for class 'matrix' cmv(x, tscale=c("hourly", "daily", "weekly", "monthly", "quarterly", "seasonal", "annual"), out.type=c("percentage", "amount"), dec=3, start="00:00:00", start.fmt= "%H:%M:%S", tz, start.month=1, dates=1, date.fmt="%Y-%m-%d", ...)cmv(x, ...) ## Default S3 method: cmv(x, tscale=c("hourly", "daily", "weekly", "monthly", "quarterly", "seasonal", "annual"), out.type=c("percentage", "amount"), dec=3, start="00:00:00", start.fmt= "%H:%M:%S", tz, start.month=1, ...) ## S3 method for class 'zoo' cmv(x, tscale=c("hourly", "daily", "weekly", "monthly", "quarterly", "seasonal", "annual"), out.type=c("percentage", "amount"), dec=3, start="00:00:00", start.fmt= "%H:%M:%S", tz, start.month=1, ...) ## S3 method for class 'data.frame' cmv(x, tscale=c("hourly", "daily", "weekly", "monthly", "quarterly", "seasonal", "annual"), out.type=c("percentage", "amount"), dec=3, start="00:00:00", start.fmt= "%H:%M:%S", tz, start.month=1, dates=1, date.fmt="%Y-%m-%d", ...) ## S3 method for class 'matrix' cmv(x, tscale=c("hourly", "daily", "weekly", "monthly", "quarterly", "seasonal", "annual"), out.type=c("percentage", "amount"), dec=3, start="00:00:00", start.fmt= "%H:%M:%S", tz, start.month=1, dates=1, date.fmt="%Y-%m-%d", ...)
x |
zoo, data.frame or matrix object, with the time series to be analised. |
tscale |
character with the temporal scale to be used for analysing the mssing data. Valid values are: |
dec |
integer indicating the amount of decimal places included in the output. |
start |
character, indicating the starting time used for aggregating sub-daily time series into daily ones. It MUST be provided in the format specified by It is useful when the daily values start at a time different from |
start.fmt |
character indicating the format in which the time is provided in |
start.month |
numeric in [1,..,12], representing the starting month (1:Jan, ..., 12:Dec) to be used in the computation of annual values. By default |
tz |
character, with the specification of the time zone used in both |
dates |
numeric, factor, POSIXct or POSIXt object indicating how to obtain the dates and times for each column of |
date.fmt |
character indicating the format in which the dates are stored in |
out.type |
character indicating how should be returned the missing values for each temporal scale. Valid values are: |
... |
further arguments passed to or from other methods. |
The amount of missing values in each temporal scale is computed just by counting the amount of NAs in each hour / day / week / month / quarter / season / year, while the percentage of missing values in each temporal scale is computed by dividing the previous number by the total number of data elements in each hour / day / week / month / quarter / season / year.
This function was developed to allow the selective removal of values when agregting from a high temporal resolution into a lower temporal resolution (e.g., from hourly to daily or from daily to monthly), using any of the temporal aggregation functions available int his package (e.g., hourly2daily, daily2monthly)
a zoo object with the percentage/amount of missing values for each temporal scale selected by the user.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
dwi, subhourly2hourly, subdaily2daily, daily2monthly, daily2annual, monthlyfunction, izoo2rzoo
###################### ## Ex1: Loading the DAILY precipitation data at SanMartino (25567 daily values) data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting to only the 1981-1990 temporal period x <- window(x, start="1981-01-01", end="1990-12-31") ## Transforming into NA the 10% of values in 'x' n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA # Getting the amount of NAs in 'x' for each week (starting on Monday) cmv(x, tscale="weekly") # Getting the amount of NAs in 'x' for each month cmv(x, tscale="monthly") # Getting the amount of NAs in 'x' for each quarter cmv(x, tscale="quarterly") # Getting the amount of NAs in 'x' for each weather season cmv(x, tscale="seasonal") # Getting the amount of NAs in 'x' for each year cmv(x, tscale="annual") ###################### ## Ex2: Loading the time series of HOURLY streamflows for the station ## Karamea at Gorge (52579 hourly values) data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Subsetting to only the first two years (1981-1982) x <- window(x, end=as.POSIXct("1982-12-31 23:59:00", tz="UTC") ) ## Transforming into NA the 30% of values in 'x' n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA # Getting the amount of NAs in 'x' for each day cmv(x, tscale="daily") # Getting the amount of NAs in 'x' for each weather season cmv(x, tscale="seasonal")###################### ## Ex1: Loading the DAILY precipitation data at SanMartino (25567 daily values) data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting to only the 1981-1990 temporal period x <- window(x, start="1981-01-01", end="1990-12-31") ## Transforming into NA the 10% of values in 'x' n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA # Getting the amount of NAs in 'x' for each week (starting on Monday) cmv(x, tscale="weekly") # Getting the amount of NAs in 'x' for each month cmv(x, tscale="monthly") # Getting the amount of NAs in 'x' for each quarter cmv(x, tscale="quarterly") # Getting the amount of NAs in 'x' for each weather season cmv(x, tscale="seasonal") # Getting the amount of NAs in 'x' for each year cmv(x, tscale="annual") ###################### ## Ex2: Loading the time series of HOURLY streamflows for the station ## Karamea at Gorge (52579 hourly values) data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Subsetting to only the first two years (1981-1982) x <- window(x, end=as.POSIXct("1982-12-31 23:59:00", tz="UTC") ) ## Transforming into NA the 30% of values in 'x' n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA # Getting the amount of NAs in 'x' for each day cmv(x, tscale="daily") # Getting the amount of NAs in 'x' for each weather season cmv(x, tscale="seasonal")
Generic function for transforming a DAILY (or sub-daily) regular time series into a WEEKLY one
daily2weekly(x, ...) ## Default S3 method: daily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, week.date.format = "%Y-%W", week.grouping = "calendar", ...) ## S3 method for class 'zoo' daily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, week.date.format = "%Y-%W", week.grouping = "calendar", ...) ## S3 method for class 'data.frame' daily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", week.date.format = "%Y-%W", week.grouping = "calendar", out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...) ## S3 method for class 'matrix' daily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", week.date.format = "%Y-%W", week.grouping = "calendar", out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...)daily2weekly(x, ...) ## Default S3 method: daily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, week.date.format = "%Y-%W", week.grouping = "calendar", ...) ## S3 method for class 'zoo' daily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, week.date.format = "%Y-%W", week.grouping = "calendar", ...) ## S3 method for class 'data.frame' daily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", week.date.format = "%Y-%W", week.grouping = "calendar", out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...) ## S3 method for class 'matrix' daily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt = "%Y-%m-%d", week.date.format = "%Y-%W", week.grouping = "calendar", out.type = "data.frame", out.fmt="numeric", verbose=TRUE, ...)
x |
zoo, data.frame or matrix object, with (sub)daily time series. |
FUN |
Function that have to be applied for transforming from daily to weekly time step (e.g., for precipitation
|
na.rm |
Logical. Should missing values be removed? |
na.rm.max |
Numeric in [0, 1]. It is used to define the maximum percentage of missing values allowed in each week to keep the weekly aggregated value in the output object of this function. In other words, if the percentage of missing values in a given week is larger than |
dates |
numeric, factor or Date object indicating how to obtain the dates for each gauging station |
date.fmt |
character indicating the format in which the dates are stored in dates, e.g. %Y-%m-%d. See |
week.date.format |
character indicating how weekly dates are stored in the output object. Valid values are: |
week.grouping |
character indicating how daily values are grouped into weekly values. Valid values are: |
out.type |
Character that defines the desired type of output. Valid values are: |
out.fmt |
OPTIONAL. Only used when |
verbose |
logical; if TRUE, progress messages are printed |
... |
arguments additional to |
The argument week.grouping defines how observations are assigned to
weekly aggregation groups before FUN is applied. It is independent from
week.date.format, which only controls how the weekly groups are labelled
in the output object.
When week.grouping="calendar" (default), daily2weekly groups the
input dates using format(time(x), "%Y-%W"). This is the historical
behaviour of the function. The %W conversion uses Monday as the first day
of the week and numbers weeks within each calendar year. Days before the first
Monday of a calendar year belong to week "00". Therefore, a Monday-Sunday
week that crosses from December into January can be split into two aggregation
groups, one for the ending calendar year and one for week "00" or
"01" of the new calendar year.
When week.grouping="sequential", daily2weekly groups the input
dates into consecutive 7-day periods starting at the first date in x.
For a complete daily series, the resulting weekly labels with
week.date.format="%Y-%m-%d" correspond to
seq(start(x), end(x), by="weeks"). This option is useful when the user
wants uninterrupted 7-day blocks over the full record instead of calendar
year-week groups.
The argument week.date.format controls only the time index returned by
daily2weekly. With week.date.format="%Y-%W", the output is
labelled with year-week strings. With
week.date.format="%Y-%m-%d", the output is labelled with the first
date of each weekly group. The missing-value filter controlled by
na.rm.max is applied to the same groups defined by week.grouping.
a zoo object with weekly time frequency
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
cmv, subhourly2hourly, daily2monthly, daily2annual, subdaily2daily, weeklyfunction, hydroplot, vector2zoo, izoo2rzoo, as.Date
###################### ## Ex1: Computation of weekly values, removing any missing value in 'x' # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three weeks (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Agreggating from Daily to Weekly, removing any missing value in 'x' w <- daily2weekly(x, FUN=sum, na.rm=TRUE) ## Same aggregation, with the weekly zoo index shown as YYYY-MM-DD dates w.dates <- daily2weekly(x, FUN=sum, na.rm=TRUE, week.date.format="%Y-%m-%d") ## Aggregation using consecutive 7-day groups starting at the first date in 'x' w.seq <- daily2weekly(x, FUN=sum, na.rm=TRUE, week.grouping="sequential", week.date.format="%Y-%m-%d") ###################### ## Ex2: Computation of Weekly values only when the percentage of NAs in each # week is lower than a user-defined percentage (10% in this example). # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three weeks (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Daily to Weekly, only for weeks with less than 10% of missing values w2 <- daily2weekly(x, FUN=sum, na.rm=TRUE, na.rm.max=0.1) # Verifying that the weeks 01, 02, 06, 08, 10, 11, 12 of 'x' had 10% or more of missing values cmv(x, tscale="weekly") ###################### ## Ex3: Computation of Weekly values in a two-column zoo object, ## only when the percentage of NAs in each week is lower than a user-defined ## percentage (10% in this example). # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three weeks (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Creating a two-column zoo object X <- cbind(x, y=x) ## Daily to Weekly, only for weeks with less than 10% of missing values w2 <- daily2weekly(X, FUN=sum, na.rm=TRUE, na.rm.max=0.1) # Verifying that the weeks 01, 02, 06, 08, 10, 11, 12 of 'x' had 10% or more of missing values cmv(X, tscale="weekly")###################### ## Ex1: Computation of weekly values, removing any missing value in 'x' # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three weeks (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Agreggating from Daily to Weekly, removing any missing value in 'x' w <- daily2weekly(x, FUN=sum, na.rm=TRUE) ## Same aggregation, with the weekly zoo index shown as YYYY-MM-DD dates w.dates <- daily2weekly(x, FUN=sum, na.rm=TRUE, week.date.format="%Y-%m-%d") ## Aggregation using consecutive 7-day groups starting at the first date in 'x' w.seq <- daily2weekly(x, FUN=sum, na.rm=TRUE, week.grouping="sequential", week.date.format="%Y-%m-%d") ###################### ## Ex2: Computation of Weekly values only when the percentage of NAs in each # week is lower than a user-defined percentage (10% in this example). # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three weeks (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Daily to Weekly, only for weeks with less than 10% of missing values w2 <- daily2weekly(x, FUN=sum, na.rm=TRUE, na.rm.max=0.1) # Verifying that the weeks 01, 02, 06, 08, 10, 11, 12 of 'x' had 10% or more of missing values cmv(x, tscale="weekly") ###################### ## Ex3: Computation of Weekly values in a two-column zoo object, ## only when the percentage of NAs in each week is lower than a user-defined ## percentage (10% in this example). # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three weeks (Jan/1921 - Mar/1921) x <- window(x, end="1921-03-31") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Creating a two-column zoo object X <- cbind(x, y=x) ## Daily to Weekly, only for weeks with less than 10% of missing values w2 <- daily2weekly(X, FUN=sum, na.rm=TRUE, na.rm.max=0.1) # Verifying that the weeks 01, 02, 06, 08, 10, 11, 12 of 'x' had 10% or more of missing values cmv(X, tscale="weekly")
Given any starting and ending dates, it generates:
1) a vector of class Date with all the days between from and to (both of them included), OR
2) the amount of days between the two dates
dip(from, to, date.fmt = "%Y-%m-%d", out.type = "seq")dip(from, to, date.fmt = "%Y-%m-%d", out.type = "seq")
from |
Character indicating the starting date for creating the sequence. It has to be in the format indicated by |
to |
Character indicating the ending date for creating the sequence. It has to be in the format indicated by |
date.fmt |
character indicating the format in which the dates are stored in |
out.type |
Character indicating the type of result that is given by this function. Valid values are: |
Depending on the value of out.type, it returns:
1) a vector of class Date with all the days between from and to (both of them included), OR
2) the amount of days between the two dates
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Sequence of daily dates between "1961-01-01" and "1961-12-31" ## dip("1961-01-01", "1961-12-31") ## Number of days between "1961-01-01" and "1965-06-30", ## but using "%d-%m-%Y" as date format. dip("01-01-1961", "30-06-1965", date.fmt= "%d-%m-%Y", out.type = "nmbr")## Sequence of daily dates between "1961-01-01" and "1961-12-31" ## dip("1961-01-01", "1961-12-31") ## Number of days between "1961-01-01" and "1965-06-30", ## but using "%d-%m-%Y" as date format. dip("01-01-1961", "30-06-1965", date.fmt= "%d-%m-%Y", out.type = "nmbr")
Given a single numeric value representing a year, it generates:
1) a vector of dates with all the days within the year, OR
2) the amount of days in the specified year
diy(year, out.type = "seq")diy(year, out.type = "seq")
year |
numeric, the year for which the sequence of days will be generated |
out.type |
Character indicating the type of result that is given by this function. Valid values are: |
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Sequence of daily dates for the year 1961 diy(1961) ## Computing the number of days between in 1961 diy(1961, out.type = "nmbr")## Sequence of daily dates for the year 1961 diy(1961) ## Computing the number of days between in 1961 diy(1961, out.type = "nmbr")
Generic function for computing a seasonal value for every year of a sub-daily/daily/weekly/monthly time series
dm2seasonal(x, ...) subdaily2seasonal(x, ...) ## Default S3 method: dm2seasonal(x, season, FUN, na.rm = TRUE, out.fmt="%Y", ...) ## S3 method for class 'zoo' dm2seasonal(x, season, FUN, na.rm = TRUE, out.fmt="%Y", ...) ## S3 method for class 'data.frame' dm2seasonal(x, season, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", out.fmt="%Y", ...) ## S3 method for class 'matrix' dm2seasonal(x, season, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", out.fmt="%Y", ...)dm2seasonal(x, ...) subdaily2seasonal(x, ...) ## Default S3 method: dm2seasonal(x, season, FUN, na.rm = TRUE, out.fmt="%Y", ...) ## S3 method for class 'zoo' dm2seasonal(x, season, FUN, na.rm = TRUE, out.fmt="%Y", ...) ## S3 method for class 'data.frame' dm2seasonal(x, season, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", out.fmt="%Y", ...) ## S3 method for class 'matrix' dm2seasonal(x, season, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", out.fmt="%Y", ...)
x |
zoo, xts, data.frame or matrix object, with sub-daily, daily, weekly or monthly time series. |
season |
character, indicating the weather season to be used for selecting the data. Valid values are: |
FUN |
Function that will be applied to ALL the values of |
na.rm |
Logical. Should missing values be removed? |
out.fmt |
Character indicating the date format for the output time series. See |
dates |
numeric, factor or Date object indicating how to obtain the dates. |
date.fmt |
Character indicating the format in which the dates are stored in dates, e.g. %Y-%m-%d. See |
out.type |
Character that defines the desired type of output. Valid values are: |
... |
further arguments passed to or from other methods. |
A numeric vector with the seasonal values for all the years in which x is defined.
For any year, the FUN value for the winter season (DJF), is computed considering only January and February, and the value of December is used for computing the winter value of the next year.
FUN is applied to all the values of x belonging to the selected season, so the results of this function depends on the frequency sampling of x and the type of function given by FUN
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
, hydroplot, seasonalfunction, time2season, extract, daily2monthly, daily2annual, monthly2annual
############ ## Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts ## Winter (DJF) values of precipitation for each year of 'x' dm2seasonal(x, FUN=sum, season="DJF") ############ ## Loading the HOURLY discharge data for the Karamea at Gorge streamgauge station data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts ## Mean winter (DJF) values of streamflow for each year of 'x' dm2seasonal(x, FUN=mean, season="DJF") subdaily2seasonal(x, FUN=mean, season="DJF") # same as above############ ## Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts ## Winter (DJF) values of precipitation for each year of 'x' dm2seasonal(x, FUN=sum, season="DJF") ############ ## Loading the HOURLY discharge data for the Karamea at Gorge streamgauge station data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts ## Mean winter (DJF) values of streamflow for each year of 'x' dm2seasonal(x, FUN=mean, season="DJF") subdaily2seasonal(x, FUN=mean, season="DJF") # same as above
For a nice time series plot, this function draws a customized time axis, with annual, monthly, daily and sub-daily time marks and labels.
drawxaxis(x, tick.tstep = "auto", lab.tstep = "auto", lab.fmt=NULL, cex.axis=1, mgp=c(3, 2, 0), ...)drawxaxis(x, tick.tstep = "auto", lab.tstep = "auto", lab.fmt=NULL, cex.axis=1, mgp=c(3, 2, 0), ...)
x |
time series that will be plotted using the X axis that will be draw class(x) must be ts or zoo |
tick.tstep |
Character indicating the time step that have to be used for putting the ticks on the time axis. Valid values are: auto, years, quarters, months,weeks, days, hours, minutes, seconds. |
lab.tstep |
Character indicating the time step that have to be used for putting the labels on the time axis. Valid values are: auto, years, quarters, months,weeks, days, hours, minutes, seconds. |
lab.fmt |
Character indicating the format to be used for the label of the axis. See |
cex.axis |
magnification of axis annotation relative to |
mgp |
The margin line (in |
... |
further arguments passed to the |
From version 0.3-0 it changed its name from drawxaxis to drawTimeAxis, in order to have a more intuitive name. The old drawxaxis function is deprecated, but still be kept for compatibility reasons.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Loading the SanMartino precipitation data data(SanMartinoPPts) x <- window(SanMartinoPPts, end=as.Date("1930-12-31")) ## Plotting the daily ts only, and then automatic 'x' axis plot(x, xaxt = "n", xlab="Time") drawTimeAxis(x) ## Plotting the daily ts only, and then monthly ticks in the 'x' axis, ## with annual labels. plot(x, xaxt = "n", xlab="Time") drawTimeAxis(x, tick.tstep="months", lab.tstep="years")## Loading the SanMartino precipitation data data(SanMartinoPPts) x <- window(SanMartinoPPts, end=as.Date("1930-12-31")) ## Plotting the daily ts only, and then automatic 'x' axis plot(x, xaxt = "n", xlab="Time") drawTimeAxis(x) ## Plotting the daily ts only, and then monthly ticks in the 'x' axis, ## with annual labels. plot(x, xaxt = "n", xlab="Time") drawTimeAxis(x, tick.tstep="months", lab.tstep="years")
Given a daily time series (usually precipitation), this function computes the average amount of wet/dry days in each month.
dwdays(x, ...) ## Default S3 method: dwdays(x, thr=0, type="wet", na.rm=TRUE, ... ) ## S3 method for class 'data.frame' dwdays(x, thr=0, type="wet", na.rm=TRUE, dates=1, date.fmt="%Y-%m-%d", verbose=TRUE,...) ## S3 method for class 'matrix' dwdays(x, thr=0, type="wet", na.rm=TRUE, dates=1, date.fmt="%Y-%m-%d", verbose=TRUE,...)dwdays(x, ...) ## Default S3 method: dwdays(x, thr=0, type="wet", na.rm=TRUE, ... ) ## S3 method for class 'data.frame' dwdays(x, thr=0, type="wet", na.rm=TRUE, dates=1, date.fmt="%Y-%m-%d", verbose=TRUE,...) ## S3 method for class 'matrix' dwdays(x, thr=0, type="wet", na.rm=TRUE, dates=1, date.fmt="%Y-%m-%d", verbose=TRUE,...)
x |
zoo, data.frame or matrix object, usually with daily time series of precipitation. |
thr |
numeric. Value of daily precipitation used as threshold for classifying a day as dry/wet or not. Days with a precipitation value larger to |
type |
character, indicating if the daily values have to be classified as dry or wet days. It works linked to the values specified in |
na.rm |
Logical. Should missing values be removed before counting? |
dates |
numeric, factor or Date object indicating how to obtain the dates |
date.fmt |
character indicating the format in which the dates are stored in dates, e.g. %Y-%m-%d. See |
verbose |
logical; if TRUE, progress messages are printed |
... |
further arguments passed to or from other methods. |
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Loading the SanMartino precipitation data data(SanMartinoPPts) x <- SanMartinoPPts ## Average amount of wet days in each month (for this example, this means days ## with precipitation larger than 0.1mm) dwdays(x, thr=0.1)## Loading the SanMartino precipitation data data(SanMartinoPPts) x <- SanMartinoPPts ## Average amount of wet days in each month (for this example, this means days ## with precipitation larger than 0.1mm) dwdays(x, thr=0.1)
This function generates a table indicating the number of days with information (<>NA) within a zoo object, aggregated by year, month or month per year.
dwi(x, ...) ## Default S3 method: dwi(x, out.unit = "years", from = start(x), to = end(x), date.fmt = "%Y-%m-%d", tstep="days", ...) ## S3 method for class 'zoo' dwi(x, out.unit = "years", from = start(x), to = end(x), date.fmt = "%Y-%m-%d", tstep="days", ...) ## S3 method for class 'data.frame' dwi(x, out.unit = "years", from, to, date.fmt = "%Y-%m-%d", tstep="days", dates = 1, verbose = TRUE, ...) ## S3 method for class 'matrix' dwi(x, out.unit = "years", from, to, date.fmt = "%Y-%m-%d", tstep="days", dates = 1, verbose = TRUE, ...)dwi(x, ...) ## Default S3 method: dwi(x, out.unit = "years", from = start(x), to = end(x), date.fmt = "%Y-%m-%d", tstep="days", ...) ## S3 method for class 'zoo' dwi(x, out.unit = "years", from = start(x), to = end(x), date.fmt = "%Y-%m-%d", tstep="days", ...) ## S3 method for class 'data.frame' dwi(x, out.unit = "years", from, to, date.fmt = "%Y-%m-%d", tstep="days", dates = 1, verbose = TRUE, ...) ## S3 method for class 'matrix' dwi(x, out.unit = "years", from, to, date.fmt = "%Y-%m-%d", tstep="days", dates = 1, verbose = TRUE, ...)
x |
zoo, data.frame or matrix object, with daily/monthly/annual time series. |
out.unit |
aggregation time for the computation of the amount of days with information. Valid values are: |
from |
Character indicating the starting date for the computations. It has to be in the format indicated by |
to |
Character indicating the ending date for the computations. It has to be in the format indicated by |
date.fmt |
character indicating the format in which the dates are stored in dates, e.g. %Y-%m-%d. See |
tstep |
Time step used for storing the values in |
dates |
numeric, factor or Date object indicating how to obtain the dates for each column of |
verbose |
logical; if TRUE, progress messages are printed |
... |
further arguments passed to or from other methods. |
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Loading the SanMartino precipitation data data(SanMartinoPPts) x <- SanMartinoPPts ## Not run: ## Days with information per year dwi(x) ## Days with information per month per year. dwi(x, out.unit="mpy") ## End(Not run) ########### ## Not run: ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) ## Months with information per year in the 9 first stations of 'EbroPPtsMonthly' a <- dwi(EbroPPtsMonthly[,1:10], out.unit="years", dates=1) ## Before plotting the results in 'a', and just for obtaining a more interesting ## plot, 70 random numbers (between 1 and 11) are introduced in 'a' a[sample(length(a), size = 70)] <- rep(1:11, length=70) ## Plotting the amount of months with information per year in each station matrixplot(a, var.type="Days", main="Number of months with info per year") ## End(Not run)## Loading the SanMartino precipitation data data(SanMartinoPPts) x <- SanMartinoPPts ## Not run: ## Days with information per year dwi(x) ## Days with information per month per year. dwi(x, out.unit="mpy") ## End(Not run) ########### ## Not run: ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) ## Months with information per year in the 9 first stations of 'EbroPPtsMonthly' a <- dwi(EbroPPtsMonthly[,1:10], out.unit="years", dates=1) ## Before plotting the results in 'a', and just for obtaining a more interesting ## plot, 70 random numbers (between 1 and 11) are introduced in 'a' a[sample(length(a), size = 70)] <- rep(1:11, length=70) ## Plotting the amount of months with information per year in each station matrixplot(a, var.type="Days", main="Number of months with info per year") ## End(Not run)
Time series of monthly precipitation on 331 stations of the Ebro River basin (NW Spain), for the period January/1961 to December/1963.
data(EbroPPtsMonthly)data(EbroPPtsMonthly)
A data.frame with 331 monthly time series, plus the first field storing the dates corresponding to each row.
Monthly time series of precipitation on 331 stations of the Ebro River basin (Spain), where some data were in-filled by using the MOSS method and from daily time series used in the technical report "Estudio de Recursos de la Cuenca del Ebro".
Downloaded from the web site of the Confederacion Hidrografica del Ebro (CHE) http://www.chebro.es/ (original link http://oph.chebro.es/DOCUMENTACION/PrecipitacionMensualRelleno/PrecipitacionMensualRelleno.html, last accessed [March 2010]).
These data are intended to be used for research purposes only, being distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.
Extracts from a zoo object all the values belonging to a given month, year or weather season.
extract(x, ...) ## Default S3 method: extract(x, trgt, ...) ## S3 method for class 'zoo' extract(x, trgt, ...)extract(x, ...) ## Default S3 method: extract(x, trgt, ...) ## S3 method for class 'zoo' extract(x, trgt, ...)
x |
zoo object |
trgt |
numeric or character indicating the elements to extract from |
... |
further arguments passed to or from other methods |
a zoo object with the extracted values.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
time2season, seasonalfunction, daily2annual, daily2monthly
### Loading temperature data ## data(SanMartinoPPts) x <- SanMartinoPPts ## Extracting all the values belonging to February (FEB=2) extract(x, trgt=2) ## Extracting all the values belonging to February (FEB=2) and April (APR=4) extract(x, trgt=c(2,4)) ## Extracting all values from September to March extract(x, trgt=c(9,10,11,12,1,2,3)) ## Extracting January-March and September-December within the same calendar year extract(x, trgt=c(1,2,3,9,10,11,12)) ## Extracting all values from September to March using the SONDJFM shortcut extract(x, trgt="SONDJFM") ## Extracting all the values belonging to the year 1970 extract(x, trgt=1970) ## Extracting all the values belonging to the years 1970 and 1972 extract(x, trgt=c(1970,1972)) ## Extracting all the values belonging to the autumn extract(x, trgt="SON")### Loading temperature data ## data(SanMartinoPPts) x <- SanMartinoPPts ## Extracting all the values belonging to February (FEB=2) extract(x, trgt=2) ## Extracting all the values belonging to February (FEB=2) and April (APR=4) extract(x, trgt=c(2,4)) ## Extracting all values from September to March extract(x, trgt=c(9,10,11,12,1,2,3)) ## Extracting January-March and September-December within the same calendar year extract(x, trgt=c(1,2,3,9,10,11,12)) ## Extracting all values from September to March using the SONDJFM shortcut extract(x, trgt="SONDJFM") ## Extracting all the values belonging to the year 1970 extract(x, trgt=1970) ## Extracting all the values belonging to the years 1970 and 1972 extract(x, trgt=c(1970,1972)) ## Extracting all the values belonging to the autumn extract(x, trgt="SON")
Computes and plots the Flow Duration Curve (FDC) corresponding to a given time series of streamflow discharges.
fdc(x, ...) ## Default S3 method: fdc(x,lQ.thr=0.7,hQ.thr=0.2, plot=TRUE, log="y", main="Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col="black", pch=1, lwd=1, lty=1, cex=0.4, cex.axis=1.2, cex.lab=1.2, leg.txt=NULL, leg.cex=1, leg.pos="topright", thr.pos="bottomleft", verbose= TRUE, thr.shw=TRUE, new=TRUE, ...) ## S3 method for class 'matrix' fdc(x, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main= "Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=palette("default")[1:ncol(x)], pch=1:ncol(x), lwd=rep(1, ncol(x)), lty=1:ncol(x), cex=0.4, cex.axis=1.2, cex.lab=1.2, leg.txt=NULL, leg.cex=1, leg.pos="topright", thr.pos="bottomleft", verbose=TRUE, thr.shw=TRUE, new=TRUE, ...) ## S3 method for class 'data.frame' fdc(x, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main= "Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=palette("default")[1:ncol(x)], pch=1:ncol(x), lwd=rep(1, ncol(x)), lty=1:ncol(x), cex=0.4, cex.axis=1.2, cex.lab=1.2, leg.txt=NULL, leg.cex=1, leg.pos="topright", thr.pos="bottomleft", verbose=TRUE, thr.shw=TRUE, new=TRUE, ...) ## S3 method for class 'zoo' fdc(x, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main= "Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=palette("default")[1:NCOL(x)], pch=1:NCOL(x), lwd=rep(1, NCOL(x)), lty=1:NCOL(x), cex=0.4, cex.axis=1.2, cex.lab=1.2, leg.txt=NULL, leg.cex=1, leg.pos="topright", thr.pos="bottomleft", verbose=TRUE, thr.shw=TRUE, new=TRUE, ...)fdc(x, ...) ## Default S3 method: fdc(x,lQ.thr=0.7,hQ.thr=0.2, plot=TRUE, log="y", main="Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col="black", pch=1, lwd=1, lty=1, cex=0.4, cex.axis=1.2, cex.lab=1.2, leg.txt=NULL, leg.cex=1, leg.pos="topright", thr.pos="bottomleft", verbose= TRUE, thr.shw=TRUE, new=TRUE, ...) ## S3 method for class 'matrix' fdc(x, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main= "Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=palette("default")[1:ncol(x)], pch=1:ncol(x), lwd=rep(1, ncol(x)), lty=1:ncol(x), cex=0.4, cex.axis=1.2, cex.lab=1.2, leg.txt=NULL, leg.cex=1, leg.pos="topright", thr.pos="bottomleft", verbose=TRUE, thr.shw=TRUE, new=TRUE, ...) ## S3 method for class 'data.frame' fdc(x, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main= "Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=palette("default")[1:ncol(x)], pch=1:ncol(x), lwd=rep(1, ncol(x)), lty=1:ncol(x), cex=0.4, cex.axis=1.2, cex.lab=1.2, leg.txt=NULL, leg.cex=1, leg.pos="topright", thr.pos="bottomleft", verbose=TRUE, thr.shw=TRUE, new=TRUE, ...) ## S3 method for class 'zoo' fdc(x, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main= "Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=palette("default")[1:NCOL(x)], pch=1:NCOL(x), lwd=rep(1, NCOL(x)), lty=1:NCOL(x), cex=0.4, cex.axis=1.2, cex.lab=1.2, leg.txt=NULL, leg.cex=1, leg.pos="topright", thr.pos="bottomleft", verbose=TRUE, thr.shw=TRUE, new=TRUE, ...)
x |
numeric, zoo, data.frame or matrix object with the observed streamflows for which the flow duration curve have to be computed. |
lQ.thr |
numeric, low-flow separation threshold. If this value is different from NA, a vertical line is drawn in this value, and all the values to the right of it should be deemed as low flows. Default value is 0.7. |
hQ.thr |
numeric, high-flow separation threshold. If this value is different from NA, a vertical line is drawn in this value, and all the values to the left of it should br deemed as high flows. Default value is 0.2. |
plot |
logical. Indicates if the flow duration curve should be plotted or not. Default value is TRUE. |
log |
character, indicates which axis has to be plotted with a logarithmic scale. Default value is y |
main |
|
xlab |
A title for the x axis. See |
ylab |
A title for the y axis. See |
ylim |
The y limits of the plot. See |
yat |
Only used when |
xat |
Only used when |
col |
The colors to be used for lines and points. Multiple colors can be specified so that each point can be given its own color. If there are fewer colors than points they are recycled in the standard fashion. Lines will all be plotted in the first colour specified. See |
pch |
A vector of plotting characters or symbols: see |
lwd |
The line width, see |
lty |
The line type, see |
cex |
See |
cex.axis |
magnification of axis annotation relative to 'cex'. |
cex.lab |
Magnification to be used for x and y labels relative to the current setting of 'cex'. See '?par'. |
leg.txt |
vector with the names that have to be used for each column of |
leg.cex |
numeric, indicating the character expansion factor for the legend, *relative* to current |
leg.pos |
keyword to be used to position the legend. One of the list ‘"bottomright", "bottom", "bottomleft", "left", "topleft", "top", "topright", "right", "center"’. This places the legend on the inside of the plot frame at the given location. See |
thr.pos |
keyword to be used to position the streamflow values corresponding to the user-defined thresholds |
verbose |
logical; if TRUE, progress messages are printed (when |
thr.shw |
logical, indicating if the streamflow values corresponding to the user-defined thresholds |
new |
logical, if TRUE (default), a new plotting window is created. |
... |
further arguments passed to or from other methods (to the plotting functions) |
numeric, matrix or data.frame whose columns contains the % of time each one of the streamflow magnitudes given as input was equalled or exceeded. The resulting values have to be multiplied by 100 to get a percentage.
When plot is TRUE (default), the resulting flow duration curve is plotted in a new window.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
Vogel, R., and N. M. Fennessey (1994), Flow duration curves I: A new interpretation and confidence intervals, ASCE, Journal of Water Resources Planning and Management, 120(4).
Vogel, R., and N. Fennessey (1995), Flow duration curves II: A review of applications in water resources planning, Water Resources Bulletin, 31(6), 1029-1039, doi:10.1111/j.1752-1688.1995.tb03419.x.
Yilmaz, K. K., H. V. Gupta, and T. Wagener (2008), A process-based diagnostic approach to model evaluation: Application to the NWS distributed hydrologic model, Water Resour. Res., 44, W09417, doi:10.1029/2007WR006716.
## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) ## data(OcaEnOnaQts) ## Daily Flow Duration Curve fdc(OcaEnOnaQts) ################### # Getting the streamflow values corresponding to 5 and 95% of time equalled or # exceeded (and also the first streamflow value in 'x' just for verification) x <- OcaEnOnaQts # First streamflow value (x1=42.1 m3/s) x1 <- x[1] # Daily FDC for 'x' y <- fdc(x) # value of the FDC for x1 (y1=0.002739726) y1 <- y[1] # Performing cubic (or Hermite) spline interpolation of 'x' and 'y' f <- splinefun(y,x) # Getting the (known) streamflow value for 'y1' f(y1) # 42.1 m3/s, equal to the known 'x1' # Streamflow values corresponding to 5 and 95% of time equalled or exceeded f(c(.05, .95)) ################### ## Getting data(OcaEnOnaQts) ## Daily Flow Duration Curve fdc(OcaEnOnaQts)## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) ## data(OcaEnOnaQts) ## Daily Flow Duration Curve fdc(OcaEnOnaQts) ################### # Getting the streamflow values corresponding to 5 and 95% of time equalled or # exceeded (and also the first streamflow value in 'x' just for verification) x <- OcaEnOnaQts # First streamflow value (x1=42.1 m3/s) x1 <- x[1] # Daily FDC for 'x' y <- fdc(x) # value of the FDC for x1 (y1=0.002739726) y1 <- y[1] # Performing cubic (or Hermite) spline interpolation of 'x' and 'y' f <- splinefun(y,x) # Getting the (known) streamflow value for 'y1' f(y1) # 42.1 m3/s, equal to the known 'x1' # Streamflow values corresponding to 5 and 95% of time equalled or exceeded f(c(.05, .95)) ################### ## Getting data(OcaEnOnaQts) ## Daily Flow Duration Curve fdc(OcaEnOnaQts)
Computes and plots the Flow Duration Curve (FDC) for the streamflows given by x and for two uncertainty bounds, with the possibility of plotting an additional FDC representing simulated streamflows for x, in order to compare them.
fdcu(x, lband, uband, ...) ## Default S3 method: fdcu(x, lband, uband, sim=NULL, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main="Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=c("black", "red"), pch=c(1, 15), lwd=c(1, 0.8), lty=c(1, 3), cex=0.2, cex.axis=1.2, cex.lab=1.2, leg.txt= c("Qobs", "Qsim", "95PPU"), leg.cex=1, leg.pos="auto", verbose= TRUE, thr.shw=TRUE, border=NA, bands.col="lightcyan", bands.density=NULL, bands.angle=45, new=TRUE, ...) ## S3 method for class 'matrix' fdcu(x, lband, uband, sim=NULL, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main="Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=matrix(c(rep("black", ncol(x)), palette("default")[2:(ncol(x)+1)]), byrow=FALSE, ncol=2), pch=matrix(rep(c(1, 15), ncol(x)), byrow=TRUE, ncol=2), lwd=matrix(rep(c(1, 0.8), ncol(x)), byrow=TRUE, ncol=2), lty=matrix(rep(c(1, 3), ncol(x)), byrow=TRUE, ncol=2), cex=rep(0.1, ncol(x)), cex.axis=1.2, cex.lab=1.2, leg.txt=c("OBS", colnames(x), "95PPU"), leg.cex=1, leg.pos="auto", verbose= TRUE, thr.shw=TRUE, border=rep(NA, ncol(x)), bands.col=rep("lightcyan", ncol(x)), bands.density=rep(NULL, ncol(x)), bands.angle=rep(45, ncol(x)), new=TRUE, ...) ## S3 method for class 'data.frame' fdcu(x, lband, uband, sim=NULL, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main="Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=matrix(c(rep("black", ncol(x)), palette("default")[2:(ncol(x)+1)]), byrow=FALSE, ncol=2), pch=matrix(rep(c(1, 15), ncol(x)), byrow=TRUE, ncol=2), lwd=matrix(rep(c(1, 0.8), ncol(x)), byrow=TRUE, ncol=2), lty=matrix(rep(c(1, 3), ncol(x)), byrow=TRUE, ncol=2), cex=rep(0.1, ncol(x)), cex.axis=1.2, cex.lab=1.2, leg.txt=c("OBS", colnames(x), "95PPU"), leg.cex=1, leg.pos="auto", verbose= TRUE, thr.shw=TRUE, border=rep(NA, ncol(x)), bands.col=rep("lightcyan", ncol(x)), bands.density=rep(NULL, ncol(x)), bands.angle=rep(45, ncol(x)), new=TRUE, ...)fdcu(x, lband, uband, ...) ## Default S3 method: fdcu(x, lband, uband, sim=NULL, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main="Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=c("black", "red"), pch=c(1, 15), lwd=c(1, 0.8), lty=c(1, 3), cex=0.2, cex.axis=1.2, cex.lab=1.2, leg.txt= c("Qobs", "Qsim", "95PPU"), leg.cex=1, leg.pos="auto", verbose= TRUE, thr.shw=TRUE, border=NA, bands.col="lightcyan", bands.density=NULL, bands.angle=45, new=TRUE, ...) ## S3 method for class 'matrix' fdcu(x, lband, uband, sim=NULL, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main="Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=matrix(c(rep("black", ncol(x)), palette("default")[2:(ncol(x)+1)]), byrow=FALSE, ncol=2), pch=matrix(rep(c(1, 15), ncol(x)), byrow=TRUE, ncol=2), lwd=matrix(rep(c(1, 0.8), ncol(x)), byrow=TRUE, ncol=2), lty=matrix(rep(c(1, 3), ncol(x)), byrow=TRUE, ncol=2), cex=rep(0.1, ncol(x)), cex.axis=1.2, cex.lab=1.2, leg.txt=c("OBS", colnames(x), "95PPU"), leg.cex=1, leg.pos="auto", verbose= TRUE, thr.shw=TRUE, border=rep(NA, ncol(x)), bands.col=rep("lightcyan", ncol(x)), bands.density=rep(NULL, ncol(x)), bands.angle=rep(45, ncol(x)), new=TRUE, ...) ## S3 method for class 'data.frame' fdcu(x, lband, uband, sim=NULL, lQ.thr=0.7, hQ.thr=0.2, plot=TRUE, log="y", main="Flow Duration Curve", xlab="% Time flow equalled or exceeded", ylab="Q, [m3/s]", ylim, yat=c(0.01, 0.1, 1), xat=c(0.01, 0.025, 0.05), col=matrix(c(rep("black", ncol(x)), palette("default")[2:(ncol(x)+1)]), byrow=FALSE, ncol=2), pch=matrix(rep(c(1, 15), ncol(x)), byrow=TRUE, ncol=2), lwd=matrix(rep(c(1, 0.8), ncol(x)), byrow=TRUE, ncol=2), lty=matrix(rep(c(1, 3), ncol(x)), byrow=TRUE, ncol=2), cex=rep(0.1, ncol(x)), cex.axis=1.2, cex.lab=1.2, leg.txt=c("OBS", colnames(x), "95PPU"), leg.cex=1, leg.pos="auto", verbose= TRUE, thr.shw=TRUE, border=rep(NA, ncol(x)), bands.col=rep("lightcyan", ncol(x)), bands.density=rep(NULL, ncol(x)), bands.angle=rep(45, ncol(x)), new=TRUE, ...)
x |
numeric, zoo, data.frame or matrix object with the observed streamflows for which the flow duration curve have to be computed. |
lband |
numeric, zoo, data.frame or matrix object with the streamflows representing the the lower uncertainty bound of |
uband |
numeric, zoo, data.frame or matrix object with the streamflows representing the the upper uncertainty bound of |
sim |
OPTIONAL. |
lQ.thr |
numeric, low flows separation threshold. If this value is different from 'NA', a vertical line is drawn in this value, and all the values to the left of it are deemed low flows. |
hQ.thr |
numeric, high flows separation threshold. If this value is different from 'NA', a vertical line is drawn in this value, and all the values to the right of it are deemed high flows |
plot |
logical. Indicates if the flow duration curve should be plotted or not. |
log |
character, indicates which axis has to be plotted with a logarithmic scale. Default value is y. |
main |
|
xlab |
|
ylab |
|
ylim |
See |
yat |
Only used when |
xat |
Only used when |
col |
See |
pch |
See |
lwd |
See |
lty |
See |
cex |
See |
cex.axis |
magnification of axis annotation relative to 'cex'. |
cex.lab |
Magnification to be used for x and y labels relative to the current setting of 'cex'. See '?par'. |
leg.txt |
vector with the names that have to be used for each column of |
leg.cex |
numeric, indicating the character expansion factor for the legend, *relative* to current |
leg.pos |
keyword to be used to position the legend. One of the list ‘"bottomright", "bottom", "bottomleft", "left", "topleft", "top", "topright", "right", "center"’. This places the legend on the inside of the plot frame at the given location. See |
verbose |
logical; if TRUE, progress messages are printed |
thr.shw |
logical, indicating if the streamflow values corresponding to the user-defined thresholds |
border |
See |
bands.col |
See |
bands.density |
See |
bands.angle |
See |
new |
logical, if TRUE, a new plotting window is created. |
... |
further arguments passed to or from other methods (to the plotting functions) |
If you do not want to use logarithmic scale for the streamflow axis, you can do it by passing the log=" " to the ... argument.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
Vogel, R., and N. M. Fennessey (1994), Flow duration curves I: A new interpretation and confidence intervals, ASCE, Journal of Water Resources Planning and Management, 120(4).
Vogel, R., and N. Fennessey (1995), Flow duration curves II: A review of applications in water resources planning, Water Resources Bulletin, 31(6), 1029-1039, doi:10.1111/j.1752-1688.1995.tb03419.x.
Yilmaz, K. K., H. V. Gupta, and T. Wagener (2008), A process-based diagnostic approach to model evaluation: Application to the NWS distributed hydrologic model, Water Resour. Res., 44, W09417, doi:10.1029/2007WR006716.
## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) ## data(OcaEnOnaQts) q <- OcaEnOnaQts # Creating a fictitious lower uncertainty band lband <- q - min(q, na.rm=TRUE) # Giving a fictitious upper uncertainty band uband <- q + mean(q, na.rm=TRUE) # Plotting the flow duration curve corresponding to 'q', with two uncertainty bounds fdcu(q, lband, uband)## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) ## data(OcaEnOnaQts) q <- OcaEnOnaQts # Creating a fictitious lower uncertainty band lband <- q - min(q, na.rm=TRUE) # Giving a fictitious upper uncertainty band uband <- q + mean(q, na.rm=TRUE) # Plotting the flow duration curve corresponding to 'q', with two uncertainty bounds fdcu(q, lband, uband)
Given any starting and ending date/time objects, it generates:
1) a vector of class c("POSIXct" "POSIXt") with all the hours between the two date/time objects (both of them included), OR
2) the amount of hours between the two date/time objects
hip(from, to, date.fmt="%Y-%m-%d %H", out.type = "seq", tz="UTC")hip(from, to, date.fmt="%Y-%m-%d %H", out.type = "seq", tz="UTC")
from |
Character or POSIXct object indicating the starting date/time for creating the sequence. It has to be in the format indicated by |
to |
Character indicating the ending date/time for creating the sequence. It has to be in the format indicated by |
date.fmt |
character indicating the format in which the date/time objects are stored in |
out.type |
Character indicating the type of result that is given by this function. Valid values are: |
tz |
specification of the desired time zone yo be used. System-specific (see time zones), but |
Depending on the value of out.type, it returns:
1) a vector of class c("POSIXct" "POSIXt") with all the hours between from and to (both of them included), OR
2) the amount of hours between the two date/time objects
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
dip, mip, yip, diy, timeBasedSeq
## Sequence of hours between "1961-01-01 00:00" and "1961-01-10 00:00", giving the ## starting and ending date/time objects with hours and skipping the minutes (default) hip("1961-01-01 00", "1961-12-31 00") ## Sequence of hours between "1961-01-01 00:00" and "1961-01-10 00:00", giving the ## starting and ending date/time objects only with hours and minutes(skipping the minutes) hip("1961-01-01 00:00", "1961-12-31 00:00", date.fmt="%Y-%m-%d %H:%M") ## Number of hours between the 10:00 AM of "1961-Jan-02" and the 11:00 AM of "1961-Jan-01", ## using "%d/%m/%Y" as date/time format. hip("01/01/1961 10", "02/01/1961 11", date.fmt= "%d/%m/%Y %H", out.type = "nmbr")## Sequence of hours between "1961-01-01 00:00" and "1961-01-10 00:00", giving the ## starting and ending date/time objects with hours and skipping the minutes (default) hip("1961-01-01 00", "1961-12-31 00") ## Sequence of hours between "1961-01-01 00:00" and "1961-01-10 00:00", giving the ## starting and ending date/time objects only with hours and minutes(skipping the minutes) hip("1961-01-01 00:00", "1961-12-31 00:00", date.fmt="%Y-%m-%d %H:%M") ## Number of hours between the 10:00 AM of "1961-Jan-02" and the 11:00 AM of "1961-Jan-01", ## using "%d/%m/%Y" as date/time format. hip("01/01/1961 10", "02/01/1961 11", date.fmt= "%d/%m/%Y %H", out.type = "nmbr")
Visualization of a correlation matrix. On top the (absolute) value of the correlation plus the result of the cor.test as stars. On bottom, the bivariate scatterplots, with a fitted line. On the diagonal, an histogram of each variable.
hydropairs(x, dec = 3, use = "pairwise.complete.obs", method = "pearson",...)hydropairs(x, dec = 3, use = "pairwise.complete.obs", method = "pearson",...)
x |
data.frame or matrix object with measurements at several locations. Each column of |
dec |
decimal places to be used for showing the correlation values |
use |
See |
method |
See |
... |
further arguments passed to or from other methods, in particular it is used in the |
On top |
the (absolute) value of the correlation plus the result of the cor.test as points |
On bottom |
the bivariate scatterplots, with a fitted line |
On diagonal |
histograms (from |
Original idea taken from the R Graph Gallery (nowadays not available on its original link: http://addictedtor.free.fr/graphiques/graphcode.php?graph=137).
Histogram panel was taken from the R help of the original pairs function
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) ## Visualizing the correlation among the monthly precipitation values ## of the first 3 gauging stations in 'EbroPPtsMonthly'. ## The first column of 'EbroPPtsMonthly' has the dates. hydropairs(EbroPPtsMonthly[,2:4])## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) ## Visualizing the correlation among the monthly precipitation values ## of the first 3 gauging stations in 'EbroPPtsMonthly'. ## The first column of 'EbroPPtsMonthly' has the dates. hydropairs(EbroPPtsMonthly[,2:4])
hydroplot: When x is a zoo object it plots (a maximum of) 9 graphs (lines plot, boxplots and/or histograms) of the daily, monthly, annual and/or seasonal time series.
sname2plot: When x is a data frame whose columns contain the time series of several gauging stations, it takes the name of one gauging station and plots the graphs described above.
hydroplot(x, ...) sname2plot(x, ...) ## Default S3 method: hydroplot(x, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), from=start(x), to=end(x), dates=1, date.fmt= "%Y-%m-%d", tz=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...) ## S3 method for class 'zoo' hydroplot(x, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), from=start(x), to=end(x), dates=1, date.fmt= "%Y-%m-%d", tz=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...) ## S3 method for class 'data.frame' hydroplot(x, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), from=start(x), to=end(x), dates=1, date.fmt= "%Y-%m-%d", tz=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...) ## Default S3 method: sname2plot(x, sname, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab=NULL, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), dates=1, date.fmt = "%Y-%m-%d", from=NULL, to=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...) ## S3 method for class 'zoo' sname2plot(x, sname, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab=NULL, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), dates=1, date.fmt = "%Y-%m-%d", from=NULL, to=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...) ## S3 method for class 'data.frame' sname2plot(x, sname, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab=NULL, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), dates=1, date.fmt = "%Y-%m-%d", from=NULL, to=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...)hydroplot(x, ...) sname2plot(x, ...) ## Default S3 method: hydroplot(x, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), from=start(x), to=end(x), dates=1, date.fmt= "%Y-%m-%d", tz=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...) ## S3 method for class 'zoo' hydroplot(x, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), from=start(x), to=end(x), dates=1, date.fmt= "%Y-%m-%d", tz=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...) ## S3 method for class 'data.frame' hydroplot(x, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), from=start(x), to=end(x), dates=1, date.fmt= "%Y-%m-%d", tz=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...) ## Default S3 method: sname2plot(x, sname, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab=NULL, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), dates=1, date.fmt = "%Y-%m-%d", from=NULL, to=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...) ## S3 method for class 'zoo' sname2plot(x, sname, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab=NULL, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), dates=1, date.fmt = "%Y-%m-%d", from=NULL, to=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...) ## S3 method for class 'data.frame' sname2plot(x, sname, FUN, na.rm=TRUE, ptype="ts+boxplot+hist", pfreq="dma", var.type, var.unit="units", main=NULL, xlab="Time", ylab=NULL, win.len1=0, win.len2=0, tick.tstep="auto", lab.tstep="auto", lab.fmt=NULL, cex=0.3, cex.main=1.3, cex.lab=1.3, cex.axis=1.3, col=c("blue", "lightblue", "lightblue"), dates=1, date.fmt = "%Y-%m-%d", from=NULL, to=NULL, stype="default", season.names=c("Winter", "Spring", "Summer", "Autumn"), h=NULL, ...)
x |
zoo, xts or data.frame object, with columns storing the time series of one or more gauging stations. |
sname |
ONLY required when |
FUN |
ONLY required when |
na.rm |
Logical. Should missing values be removed before the computations? |
ptype |
Character indicating the type of plot that will be plotted. Valid values are: |
pfreq |
Character indicating how many plots are desired by the user. Valid values are: |
var.type |
ONLY required when |
var.unit |
Character representing the measurement unit of the variable being plotted. ONLY used for labelling the axes (e.g., "mm" for precipitation, "C" for temperature, and "m3/s" for flow.) |
main |
Character representing the main title of the plot. If the user do not provide a title, this is created automatically as: |
xlab |
A title for the x axis. See |
ylab |
A title for the y axis. See |
win.len1 |
number of days for being used in the computation of the first moving average. A value equal to zero indicates that this moving average is not going to be computed. |
win.len2 |
number of days for being used in the computation of the second moving average. A value equal to zero indicates that this moving average is not going to be computed. |
tick.tstep |
Character indicating the time step that have to be used for putting the ticks on the time axis. Valid values are: |
lab.tstep |
Character indicating the time step that have to be used for putting the labels on the time axis. Valid values are: |
lab.fmt |
Character indicating with the format to be used for the label of the axis. See |
cex |
A numerical value giving the amount by which plotting text and symbols should be magnified relative to the default. (See |
cex.main |
The magnification to be used for main titles relative to the current setting of |
cex.lab |
The magnification to be used for x and y labels relative to the current setting of |
cex.axis |
The magnification to be used for axis annotation relative to the current setting of |
col |
A character vector with 3 elements, representing the colors to be used for plotting the lines of the ts, the boxplots, and the histograms, respectively. |
dates |
ONLY required when |
date.fmt |
Character indicating the format in which the dates are stored in dates, from and to. See |
tz |
character, with the specification of the time zone used for If If A list of valid time zones can be obtained by calling the base function This argument can be used when working with sub-daily zoo objects to force using time zones other than the local time zone for |
from |
OPTIONAL, used for extracting a subset of values. |
to |
OPTIONAL, used for extracting a subset of values. |
stype |
OPTIONAL, only used when |
season.names |
OPTIONAL, only used when |
h |
OPTIONAL, only used when |
... |
further arguments passed to the |
Plots of the daily/monthly/annual/seasonal values of the time series given as input.
Depending on the value of pfreq, daily, monthly, annual and/or seasonal time series plots, boxplots and histograms are produced.
Depending on the value of ptype, time series plots, boxplots and/or histograms are produced.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
############# ## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) ## data(OcaEnOnaQts) ## 3 ts, 3 boxplots and 3 histograms hydroplot(OcaEnOnaQts, FUN=mean, ylab= "Q", var.unit = "m3/s") ## only the original time series hydroplot(OcaEnOnaQts, pfreq="o") ## only the year 1962 of the original time series hydroplot(OcaEnOnaQts, pfreq="o", from="1962-01-01", to="1962-12-31") ## Not run: ## seasonal plots hydroplot(OcaEnOnaQts, pfreq="seasonal", FUN=mean, stype="default") ## custom season names (let's assume to be in the Southern Hemisphere) hydroplot(OcaEnOnaQts, pfreq="seasonal", FUN=mean, stype="default", season.names=c("Summer","Autumn", "Winter","Spring")) ############# ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) op <- par(mar=c(5.1, 4.1, 4.1, 2.1)) on.exit(par(op)) ## Plotting seasonal precipitation at station "P9001" sname2plot(EbroPPtsMonthly, sname="P9001", FUN=sum, dates=1, pfreq="seasonal", stype="default") ## Plotting the monthly and annual values of precipitation at station "P9001", ## stored in 'EbroPPtsMonthly'. sname2plot(EbroPPtsMonthly, sname="P9001", var.type="Precipitation", dates=1, pfreq="ma") ## End(Not run)############# ## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) ## data(OcaEnOnaQts) ## 3 ts, 3 boxplots and 3 histograms hydroplot(OcaEnOnaQts, FUN=mean, ylab= "Q", var.unit = "m3/s") ## only the original time series hydroplot(OcaEnOnaQts, pfreq="o") ## only the year 1962 of the original time series hydroplot(OcaEnOnaQts, pfreq="o", from="1962-01-01", to="1962-12-31") ## Not run: ## seasonal plots hydroplot(OcaEnOnaQts, pfreq="seasonal", FUN=mean, stype="default") ## custom season names (let's assume to be in the Southern Hemisphere) hydroplot(OcaEnOnaQts, pfreq="seasonal", FUN=mean, stype="default", season.names=c("Summer","Autumn", "Winter","Spring")) ############# ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) op <- par(mar=c(5.1, 4.1, 4.1, 2.1)) on.exit(par(op)) ## Plotting seasonal precipitation at station "P9001" sname2plot(EbroPPtsMonthly, sname="P9001", FUN=sum, dates=1, pfreq="seasonal", stype="default") ## Plotting the monthly and annual values of precipitation at station "P9001", ## stored in 'EbroPPtsMonthly'. sname2plot(EbroPPtsMonthly, sname="P9001", var.type="Precipitation", dates=1, pfreq="ma") ## End(Not run)
Infill all the missing values (NA) in x with the corresponding values in sim.
infillxy(x, ...) ## Default S3 method: infillxy(x, sim, ...) ## S3 method for class 'matrix' infillxy(x, sim, ...) ## S3 method for class 'data.frame' infillxy(x, sim, ...)infillxy(x, ...) ## Default S3 method: infillxy(x, sim, ...) ## S3 method for class 'matrix' infillxy(x, sim, ...) ## S3 method for class 'data.frame' infillxy(x, sim, ...)
x |
numeric, data.frame or matrix in which some values are missing (NA). |
sim |
numeric, data.frame or matrix, with the same dimension of |
... |
further arguments passed to or from other methods. |
It gives as a result an object of the same dimension of x, in which all the NA values were infilled with the corresponding values of sim.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
obs <- c(1, NA, 3, 4, NA, 5) sim <- rep(2, 6) ## Filling in the missing values in 'x' with the corresponding values in 'sim' infillxy(x=obs, sim)obs <- c(1, NA, 3, 4, NA, 5) sim <- rep(2, 6) ## Filling in the missing values in 'x' with the corresponding values in 'sim' infillxy(x=obs, sim)
Generic function for identifying whether a zoo object has a regular time frequency without missing values from the first one to the last one.
isComplete(x, ...) ## S3 method for class 'zoo' isComplete(x, tz, out.type=c("single", "all"), verbose=TRUE, ...)isComplete(x, ...) ## S3 method for class 'zoo' isComplete(x, tz, out.type=c("single", "all"), verbose=TRUE, ...)
x |
zoo object with a time attribute that should have a regular time frequency (e.g., hourly, daily, monthly, annual). |
tz |
character, indicating the time zone in which the date of If If A list of valid time zones can be obtained by calling the base function This argument can be used when working with sub-daily zoo objects to force using time zones other than the local time zone for |
out.type |
Character indicating the type of result that is given by this function. Valid values are: |
verbose |
logical; if TRUE, informative messages are shown in the screen. When |
... |
further arguments passed to or from other methods. |
If out.type="single" |
(default value), it returns a logical value identifying whether |
If out.type="all" |
it returns a list with the following three elements: -) isComplete: logical value identifying whether -) NumberMissingDT: integer indicating the amount of missing layers from the first layer of -) missingDateTimes: Numeric, Date, or POSIXct vector showing the DateTime of the missing layers in |
Mauricio Zambrano-Bigiarini, [email protected]
########### # EXAMPLE 1: Hourly zoo object, with a POSIXct time attribute ########### # Loading the HOURLY streamflow data for Karamea at Gorge data(KarameaAtGorgeQts) x.h <- KarameaAtGorgeQts # Checking whether 'x' is complete or not isComplete(x.h) ########### ## EXAMPLE 2: Daily object, with a Date time attribute ########### # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x.d <- SanMartinoPPts # Checking whether 'x' is complete or not isComplete(x.d) # Removing two values and testing it again x.d <-x.d[-c(3,5)] isComplete(x.d) ########### # EXAMPLE 3: Weekly zoo object, with a Date time attribute ########### # Creating a dummy weekly object with a Date time attribute x.w <- x.d[1:12] time(x.w) <- seq(from=as.Date("2001-01-01"), to=as.Date("2001-03-19"), by="1 week") # Checking whether 'x.w' is complete or not isComplete(x.w) # Removing two values and testing it again x.w2 <- x.w[-c(3,5)] isComplete(x.w2) ########### # EXAMPLE 4: Monthly zoo object, with a yearmon time attribute ########### # Transforming the daily object into a monthly one x.m1 <- daily2monthly(x.d, FUN=sum) # Checking whether 'x.m1' is complete or not isComplete(x.m1) # Removing two values and testing it again x.m12 <- x.m1[-c(3,5)] isComplete(x.m12) ########### # EXAMPLE 5: Monthly zoo object, with a Date time attribute ########### # Creating a monthly object with a Date time attribute x.m2 <- x.m1 time(x.m2) <- as.Date( paste0( format(zoo::as.yearmon( time(x.m1) ), "%Y-%m"), "-01") ) # Checking whether 'x.m2' is complete or not isComplete(x.m2) # Removing two values and testing it again x.m22 <- x.m2[-c(3,5)] isComplete(x.m22) ########### # EXAMPLE 6: Annual zoo object, with a Date time attribute ########### # Creating a dummy annual object with Date time attribute x.a1 <- x.m1[1:12] time(x.a1) <- hydroTSM::yip("2001-01-01", "2012-01-01") # Checking whether 'x.a1' is complete or not isComplete(x.a1) # Removing two values and testing it again x.a12 <- x.a1[-c(3,5)] isComplete(x.a12) ########### # EXAMPLE 7: 3-hourly zoo object, with a POSIXct time attribute ########### # Creating a dummy 3-hourly object with a POSIXct time attribute x.3h <- x.m1[1:12] time(x.3h) <- seq(from=as.POSIXct("2001-01-01 00:00:00", tz="UTC"), to=as.POSIXct("2001-01-02 09:00:00", tz="UTC"), by="3 hours") # Checking whether 'x.3h' is complete or not isComplete(x.3h) # Removing two values and testing it again x.3h2 <- x.3h[-c(3,5)] isComplete(x.3h2) ############ # EXAMPLE 8: 8-day zoo object, with a Date time attribute ############ # Creating a dummy 8-day object with a Date time attribute x.8d <- x.m1[1:12] time(x.8d) <- seq(from=as.Date("2001-01-01"), to=as.Date("2001-03-31"), by="8 days") # Checking whether 'x.8d' is complete or not isComplete(x.8d) # Removing two values and testing it again x.8d2 <- x.8d[-c(3,5)] isComplete(x.8d2) ############ # EXAMPLE 9: 3-monthly zoo object, with a Date time attribute ############ # Creating a dummy 3-monthly object with a Date time attribute x.3m <- x.m1[1:12] time(x.3m) <- seq(from=as.Date("2001-01-01"), to=as.Date("2003-12-01"), by="3 months") # Checking whether 'x.3m' is complete or not isComplete(x.3m) # Removing two values and testing it again x.3m2 <- x.3m[-c(3,5)] isComplete(x.3m2)########### # EXAMPLE 1: Hourly zoo object, with a POSIXct time attribute ########### # Loading the HOURLY streamflow data for Karamea at Gorge data(KarameaAtGorgeQts) x.h <- KarameaAtGorgeQts # Checking whether 'x' is complete or not isComplete(x.h) ########### ## EXAMPLE 2: Daily object, with a Date time attribute ########### # Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x.d <- SanMartinoPPts # Checking whether 'x' is complete or not isComplete(x.d) # Removing two values and testing it again x.d <-x.d[-c(3,5)] isComplete(x.d) ########### # EXAMPLE 3: Weekly zoo object, with a Date time attribute ########### # Creating a dummy weekly object with a Date time attribute x.w <- x.d[1:12] time(x.w) <- seq(from=as.Date("2001-01-01"), to=as.Date("2001-03-19"), by="1 week") # Checking whether 'x.w' is complete or not isComplete(x.w) # Removing two values and testing it again x.w2 <- x.w[-c(3,5)] isComplete(x.w2) ########### # EXAMPLE 4: Monthly zoo object, with a yearmon time attribute ########### # Transforming the daily object into a monthly one x.m1 <- daily2monthly(x.d, FUN=sum) # Checking whether 'x.m1' is complete or not isComplete(x.m1) # Removing two values and testing it again x.m12 <- x.m1[-c(3,5)] isComplete(x.m12) ########### # EXAMPLE 5: Monthly zoo object, with a Date time attribute ########### # Creating a monthly object with a Date time attribute x.m2 <- x.m1 time(x.m2) <- as.Date( paste0( format(zoo::as.yearmon( time(x.m1) ), "%Y-%m"), "-01") ) # Checking whether 'x.m2' is complete or not isComplete(x.m2) # Removing two values and testing it again x.m22 <- x.m2[-c(3,5)] isComplete(x.m22) ########### # EXAMPLE 6: Annual zoo object, with a Date time attribute ########### # Creating a dummy annual object with Date time attribute x.a1 <- x.m1[1:12] time(x.a1) <- hydroTSM::yip("2001-01-01", "2012-01-01") # Checking whether 'x.a1' is complete or not isComplete(x.a1) # Removing two values and testing it again x.a12 <- x.a1[-c(3,5)] isComplete(x.a12) ########### # EXAMPLE 7: 3-hourly zoo object, with a POSIXct time attribute ########### # Creating a dummy 3-hourly object with a POSIXct time attribute x.3h <- x.m1[1:12] time(x.3h) <- seq(from=as.POSIXct("2001-01-01 00:00:00", tz="UTC"), to=as.POSIXct("2001-01-02 09:00:00", tz="UTC"), by="3 hours") # Checking whether 'x.3h' is complete or not isComplete(x.3h) # Removing two values and testing it again x.3h2 <- x.3h[-c(3,5)] isComplete(x.3h2) ############ # EXAMPLE 8: 8-day zoo object, with a Date time attribute ############ # Creating a dummy 8-day object with a Date time attribute x.8d <- x.m1[1:12] time(x.8d) <- seq(from=as.Date("2001-01-01"), to=as.Date("2001-03-31"), by="8 days") # Checking whether 'x.8d' is complete or not isComplete(x.8d) # Removing two values and testing it again x.8d2 <- x.8d[-c(3,5)] isComplete(x.8d2) ############ # EXAMPLE 9: 3-monthly zoo object, with a Date time attribute ############ # Creating a dummy 3-monthly object with a Date time attribute x.3m <- x.m1[1:12] time(x.3m) <- seq(from=as.Date("2001-01-01"), to=as.Date("2003-12-01"), by="3 months") # Checking whether 'x.3m' is complete or not isComplete(x.3m) # Removing two values and testing it again x.3m2 <- x.3m[-c(3,5)] isComplete(x.3m2)
This function back transforms a standarized vector/matrix z into their original values, i.e., re-scales all the values in the [0,1] interval to the original range of values z = re-scale(x) = x*[ xmax - xmin ] + xmin.
istdx(x, ...) ## Default S3 method: istdx(x, xmin, xrange, ...)istdx(x, ...) ## Default S3 method: istdx(x, xmin, xrange, ...)
x |
standarized vector or matrix to be re-scaled, all the values have to be in the range [0,1] |
xmin |
numeric with the minimum value(s) in the original |
xrange |
numeric with the range of value(s) in the original |
... |
further arguments passed to or from other methods |
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) ## data(OcaEnOnaQts) x <- OcaEnOnaQts ## Computing xmin and the range of 'x' xmin <- min(x, na.rm=TRUE) r <- diff(range(x, na.rm=TRUE)) ## Standarized variable s <- stdx(x) ## Inverse of the standarized variable si <- istdx(s, xmin, xrange=r) ## 'si' and 'x' should be the same summary(x-si) ########### ### Standarizing a subset of the stations 9 to 12 in 'EbroPPtsMonthly' ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) pp <- EbroPPtsMonthly[1:70,10:13] xmin <- apply(pp, 2, min, na.rm=TRUE) xrange <- apply(pp, 2, range, na.rm=TRUE) xrange <- apply(xrange, 2, diff, na.rm=TRUE) ## Standarized variable s <- stdx(as.matrix(pp)) ## Inverse of the standarized variable si <- istdx(s, xmin, xrange) ## 'si' and 'pp' should be the same summary(pp - si)## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) ## data(OcaEnOnaQts) x <- OcaEnOnaQts ## Computing xmin and the range of 'x' xmin <- min(x, na.rm=TRUE) r <- diff(range(x, na.rm=TRUE)) ## Standarized variable s <- stdx(x) ## Inverse of the standarized variable si <- istdx(s, xmin, xrange=r) ## 'si' and 'x' should be the same summary(x-si) ########### ### Standarizing a subset of the stations 9 to 12 in 'EbroPPtsMonthly' ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) pp <- EbroPPtsMonthly[1:70,10:13] xmin <- apply(pp, 2, min, na.rm=TRUE) xrange <- apply(pp, 2, range, na.rm=TRUE) xrange <- apply(xrange, 2, diff, na.rm=TRUE) ## Standarized variable s <- stdx(as.matrix(pp)) ## Inverse of the standarized variable si <- istdx(s, xmin, xrange) ## 'si' and 'pp' should be the same summary(pp - si)
It takes an irregular zoo object (with non-existing values for some dates/times) and converts it into a regularly spaced zoo object within the time period defined by from and to, by filling the missing dates with ‘NA’
izoo2rzoo(x, ...) ## Default S3 method: izoo2rzoo(x, from= start(x), to= end(x), date.fmt, tstep, tz, na.action=c("keep", "linear", "spline"), ... ) ## S3 method for class 'zoo' izoo2rzoo(x, from= start(x), to= end(x), date.fmt, tstep, tz, na.action=c("keep", "linear", "spline"), ... )izoo2rzoo(x, ...) ## Default S3 method: izoo2rzoo(x, from= start(x), to= end(x), date.fmt, tstep, tz, na.action=c("keep", "linear", "spline"), ... ) ## S3 method for class 'zoo' izoo2rzoo(x, from= start(x), to= end(x), date.fmt, tstep, tz, na.action=c("keep", "linear", "spline"), ... )
x |
irregular zoo object (vector or matrix) representing a time series (very likely read with some user-defined procedure, and with some missing values for particular days/months/years) |
from |
Character indicating the starting date for creating the regularly spaced zoo object. The default value corresponds to the date of the first element of |
to |
Character indicating the ending date for creating the regularly spaced zoo object. The default value corresponds to the date of the last element of |
date.fmt |
character indicating the format in which the dates are stored in |
tstep |
character, indicating the time step used for creating the time sequence going from |
tz |
character, with the specification of the time zone used for If If A list of valid time zones can be obtained by calling the base function This argument can be used when working with sub-daily zoo objects to force using time zones other than the local time zone for |
na.action |
character indicating whether to keep 'NA' values in |
... |
further arguments passed to or from other methods |
If the full time period of x is a subset of the time period defined by from and to, the time period of the resulting zoo is the one defined by from and to, assigning 'NA' to all the dates in which x does not have a value.
a regularly spaced zoo object, with values given by x and time stamps going from from to to at intervals defined by tsteps.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
zoo, vector2zoo, as.POSIXct, Sys.timezone
## ## Example 1: Adding NA for February 29th to an existing zoo object # dummy values and dates (February 29th is not present !) x <- 1:9 dates <- c("1964-02-25", "1964-02-26", "1964-02-27", "1964-02-28", "1964-03-01", "1964-03-02", "1964-03-03", "1964-03-04", "1964-03-05") # From 'character' to 'Date' class dates <- as.Date(dates) ## From 'numeric' to 'zoo' class ( x <- zoo(x, dates) ) # Feb 29th is still not present in 'x' ## checking the length of 'x' length(x) # 9 elements (there is no data for Feb 29th) ## Adding a missing value (NA in this case) for Feb 29th ( y <- izoo2rzoo(x) ) ## checking the new length length(y) # 1 element more than the original 'x' (thre is an NA value in Feb 29th) ## ## Example 2: Extending the original 'x' object from February 1st to the end of March, # assigning 'NA' to the days in which 'x' do not have a value. ( y <- izoo2rzoo(x, from="1964-02-01", to="1964-03-31") ) ## ## Example 3: Working with a zoo matrix with two identical 'x' time series, ## from 1964-02-25 to 1964-03-05 ( Y <- cbind(x,x) ) # Adding a missing value (NA in this case) for Feb 29th in all the columns of Y ( rY <- izoo2rzoo(Y) ) ## ## Example 4: Working with hourly data, from 01:00 to 10:00 UTC on 12th December 2000 dates <- ISOdatetime(year=2000, month=12, day=12, hour=1:10, min=0, sec=0, tz="UTC") values <- 1:10 x <- zoo(values, dates) # removing four values in 'x', from 02:00 to 05:00, i.e., they will not be present # anymore in 'x' at all, not even NA !) x <- x[-c(2:5)] time(x) length(x) # Adding missing values (NA in this case) from 02:00 to 05:00 y <- izoo2rzoo(x) time(y) length(y) ## ## Example 5: Extending hourly data to a DateTime before 'start(x)', ## specifying only the date. ## Time of 'x' is in local time zone (tz="") instead of UTC dt <- hip("2021-01-01 00:00:00", "2021-01-01 20:00:00", tz="") x <- zoo(0:20, dt) (y <- izoo2rzoo(x, from="2020-12-31") )# 00:00:00 is ommited (time(y)) ## ## Example 6: Extending hourly data to a DateTime before 'start(x)', ## specifying date and time. ## Time of 'x' is in local time zone (tz="") instead of UTC dt <- hip("2021-01-01 00:00:00", "2021-01-01 20:00:00", tz="") x <- zoo(0:20, dt) ( y <- izoo2rzoo(x, from="2020-12-31 20:00:00") ) ## ## Example 7: Extending hourly data to a DateTime before 'start(x)', ## specifying date and time, and forcing UTC to be the time zone. ## Time of 'x' is in local time zone (tz="") instead of UTC, but ## it will be treated as UTC by using the 'tz' argument dt <- hip("2021-01-01 00:00:00", "2021-01-01 20:00:00", tz="") x <- zoo(0:20, dt) (time(x)) (y <- izoo2rzoo(x, from="2020-12-31 20:00:00", tz="UTC") )# 00:00:00 is ommited (time(y)) ## ## Example 8: Extending hourly data to a DateTime after 'end(x)', ## specifying date and time. ## Time of 'x' is in local time zone (tz="") instead of UTC dt <- hip("2021-01-01 00:00:00", "2021-01-01 20:00:00", tz="") x <- zoo(0:20, dt) ( y <- izoo2rzoo(x, to="2021-01-02 12:00:00") ) ## ## Example 9: Extending hourly data to a DateTime before 'start(x)'. ## Note that the 'tz' argument can be ommited in the 'hip' function, ## because by default it assumes UTC as time zone dt <- hip("2021-01-01 00:00:00", "2021-01-01 20:00:00", tz="UTC") x <- zoo(0:20, dt) ( y <- izoo2rzoo(x, from="2020-12-31 20:00:00", tz="UTC") ) ## ## Example 10: Extending hourly data to a date before 'start(x)'. However, hourly 'x' ## values are given at HH:15:00 hours instead of HH:00:00 hours. ## Loading the time series of hourly streamflows for the station Karamea at Gorge ## Time Zone for 'KarameaAtGorgeQts' data is 'UTC' (see ?KarameaAtGorgeQts), but it will ## be tr4ated as 'Pacific/Auckland' (Zealand Standard Time) for this example data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Subsetting 'x' to its first day only # (01/Jan/1980 08:15:00 - 01/Jan/1980 23:15:00) x <- window(x, end="1980-01-01 23:59:00") # Adding NA hourly data since 1979-12-31 21:15:00 izoo2rzoo(x, from="1979-12-31 21:15:00", tz="Pacific/Auckland")## ## Example 1: Adding NA for February 29th to an existing zoo object # dummy values and dates (February 29th is not present !) x <- 1:9 dates <- c("1964-02-25", "1964-02-26", "1964-02-27", "1964-02-28", "1964-03-01", "1964-03-02", "1964-03-03", "1964-03-04", "1964-03-05") # From 'character' to 'Date' class dates <- as.Date(dates) ## From 'numeric' to 'zoo' class ( x <- zoo(x, dates) ) # Feb 29th is still not present in 'x' ## checking the length of 'x' length(x) # 9 elements (there is no data for Feb 29th) ## Adding a missing value (NA in this case) for Feb 29th ( y <- izoo2rzoo(x) ) ## checking the new length length(y) # 1 element more than the original 'x' (thre is an NA value in Feb 29th) ## ## Example 2: Extending the original 'x' object from February 1st to the end of March, # assigning 'NA' to the days in which 'x' do not have a value. ( y <- izoo2rzoo(x, from="1964-02-01", to="1964-03-31") ) ## ## Example 3: Working with a zoo matrix with two identical 'x' time series, ## from 1964-02-25 to 1964-03-05 ( Y <- cbind(x,x) ) # Adding a missing value (NA in this case) for Feb 29th in all the columns of Y ( rY <- izoo2rzoo(Y) ) ## ## Example 4: Working with hourly data, from 01:00 to 10:00 UTC on 12th December 2000 dates <- ISOdatetime(year=2000, month=12, day=12, hour=1:10, min=0, sec=0, tz="UTC") values <- 1:10 x <- zoo(values, dates) # removing four values in 'x', from 02:00 to 05:00, i.e., they will not be present # anymore in 'x' at all, not even NA !) x <- x[-c(2:5)] time(x) length(x) # Adding missing values (NA in this case) from 02:00 to 05:00 y <- izoo2rzoo(x) time(y) length(y) ## ## Example 5: Extending hourly data to a DateTime before 'start(x)', ## specifying only the date. ## Time of 'x' is in local time zone (tz="") instead of UTC dt <- hip("2021-01-01 00:00:00", "2021-01-01 20:00:00", tz="") x <- zoo(0:20, dt) (y <- izoo2rzoo(x, from="2020-12-31") )# 00:00:00 is ommited (time(y)) ## ## Example 6: Extending hourly data to a DateTime before 'start(x)', ## specifying date and time. ## Time of 'x' is in local time zone (tz="") instead of UTC dt <- hip("2021-01-01 00:00:00", "2021-01-01 20:00:00", tz="") x <- zoo(0:20, dt) ( y <- izoo2rzoo(x, from="2020-12-31 20:00:00") ) ## ## Example 7: Extending hourly data to a DateTime before 'start(x)', ## specifying date and time, and forcing UTC to be the time zone. ## Time of 'x' is in local time zone (tz="") instead of UTC, but ## it will be treated as UTC by using the 'tz' argument dt <- hip("2021-01-01 00:00:00", "2021-01-01 20:00:00", tz="") x <- zoo(0:20, dt) (time(x)) (y <- izoo2rzoo(x, from="2020-12-31 20:00:00", tz="UTC") )# 00:00:00 is ommited (time(y)) ## ## Example 8: Extending hourly data to a DateTime after 'end(x)', ## specifying date and time. ## Time of 'x' is in local time zone (tz="") instead of UTC dt <- hip("2021-01-01 00:00:00", "2021-01-01 20:00:00", tz="") x <- zoo(0:20, dt) ( y <- izoo2rzoo(x, to="2021-01-02 12:00:00") ) ## ## Example 9: Extending hourly data to a DateTime before 'start(x)'. ## Note that the 'tz' argument can be ommited in the 'hip' function, ## because by default it assumes UTC as time zone dt <- hip("2021-01-01 00:00:00", "2021-01-01 20:00:00", tz="UTC") x <- zoo(0:20, dt) ( y <- izoo2rzoo(x, from="2020-12-31 20:00:00", tz="UTC") ) ## ## Example 10: Extending hourly data to a date before 'start(x)'. However, hourly 'x' ## values are given at HH:15:00 hours instead of HH:00:00 hours. ## Loading the time series of hourly streamflows for the station Karamea at Gorge ## Time Zone for 'KarameaAtGorgeQts' data is 'UTC' (see ?KarameaAtGorgeQts), but it will ## be tr4ated as 'Pacific/Auckland' (Zealand Standard Time) for this example data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Subsetting 'x' to its first day only # (01/Jan/1980 08:15:00 - 01/Jan/1980 23:15:00) x <- window(x, end="1980-01-01 23:59:00") # Adding NA hourly data since 1979-12-31 21:15:00 izoo2rzoo(x, from="1979-12-31 21:15:00", tz="Pacific/Auckland")
Time series with hourly streamflows for the Karamea River(New Zealand) measured at the gauging station "Gorge", for the period 01/Jan/1980 to 31/Dec/1985.
Station Number: 95102, Easting Coordinate (NZMG): 2444629.0, Northing Coordinate (NZMG): 5994427.0, Catchment Area (km2): 1160.0.
In November 25th, 2023 (for hydroTSM v0.7-0), the time zone of this data sete was changed from "none" (i.e., your local time zone was used every time you loaded this dataset) to GMT+12, in order to avoid missing datetimes at times where daylight saving time ocurred. However, due to CRAN requirements, in January 2024 (for hydroTSM v0.7-1), the time zone of this data sete was changed from "GMT+12" to UTM, in order to avoid missing datetimes at times where daylight saving time ocurred. After the previous change, the initial DateTime of this dataset changed from "1980-01-01 08:15:00 -03" (in my local computer) to "1979-12-31 20:15:00 UTC" (everywhere).
Only two NA elements were removed from the original dataset: the first one and the last one.
data(KarameaAtGorgeQts)data(KarameaAtGorgeQts)
zoo object.
Provided by the National Institute of Water and Atmospheric Research https://niwa.co.nz/, thanks to the gentle collaboration of Shailesh Singh
These data are intended to be used for research purposes only, being distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.
Generic function for computing a moving (sliding) average of ts.
ma(x, ...) ## Default S3 method: ma(x, win.len, FUN = mean, ...) ## S3 method for class 'zoo' ma(x, win.len, FUN = mean, ...)ma(x, ...) ## Default S3 method: ma(x, win.len, FUN = mean, ...) ## S3 method for class 'zoo' ma(x, win.len, FUN = mean, ...)
x |
ts or zoo object. |
win.len |
number of terms that will be considered in the mean. It have to be odd |
FUN |
Function that have to be applied for computing the moving average. Usually, |
... |
further arguments passed to or from other methods. |
a vector with the moving average termns. The length of the resulting vector is the same of x, but the first and last (win.len-1)/2 elements will be NA.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) ## data(OcaEnOnaQts) x <- OcaEnOnaQts ## Daily to Monthly ts m <- daily2monthly(x, FUN=mean, na.rm=FALSE) # Plotting the monthly values plot(m, xlab="Time") ## Plotting the annual moving average in station 'x' lines(ma(m, win.len=12), col="blue")## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) ## data(OcaEnOnaQts) x <- OcaEnOnaQts ## Daily to Monthly ts m <- daily2monthly(x, FUN=mean, na.rm=FALSE) # Plotting the monthly values plot(m, xlab="Time") ## Plotting the annual moving average in station 'x' lines(ma(m, win.len=12), col="blue")
Daily time series of precipitation, maximum and minimun air temperature at station Maquehue Temuco Ad. (DMC_ID:380013), Araucania Region, Chile (Lat:-38.770, Lon:-72.637), with data from 01/Jan/1950 to 31/Dec/2015 (including some gaps).
data(MaquehueTemuco)data(MaquehueTemuco)
zoo matrix with 3 columns:
-) pcp: daily precipitation, [mm/day].
-) tmx: daily maximum air temperature, [degree Celsius].
-) tmn: daily minimum air temperature, [degree Celsius].
Provided by Center for Climate and Resilience Research, Universidad de Chile, Santiago, Chile (CR2, https://dataclima.cr2.cl/bases_de_datos?database_db_type_id=5. Original data available at the Chilean Meteorological Organization (DMC, https://climatologia.meteochile.gob.cl/application/diariob/visorDeDatosEma/380013). Last accessed [May 2025]).
These data are intended to be used for research purposes only, being distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.
Plots a color matrix, representing the values stored in x.
Originally, it was thought to represent the amount of days with information per year in a set of gauging stations, but it can be used for plotting the information stored in any two dimensional matrix.
matrixplot(x, ColorRamp="Days", ncolors = 10, main = "", cuts, cuts.dec=2, cuts.labels, cuts.style=c("equal", "pretty", "fixed", "sd", "quantile", "kmeans", "bclust", "fisher"), legend.cex=0.8, legend.title="", legend.title.cex=1.5, legend.fontsize=15, ...)matrixplot(x, ColorRamp="Days", ncolors = 10, main = "", cuts, cuts.dec=2, cuts.labels, cuts.style=c("equal", "pretty", "fixed", "sd", "quantile", "kmeans", "bclust", "fisher"), legend.cex=0.8, legend.title="", legend.title.cex=1.5, legend.fontsize=15, ...)
x |
matrix to be plotted. Originally: |
ColorRamp |
Character or function defining a personalized color ramp for plotting the maps. |
ncolors |
numeric, indicating the number of color intervals that will be used for representing the information content of |
main |
Main title for the plot |
cuts |
Numeric, indicating the values used to divide the range of 'x' in the legend of colours. If not provided, it is automatically selected as a function of 'lenght(ColorRamp)'. |
cuts.dec |
Number of decimal places used to present the numbers that divide the range of 'x' in the legend of colours. |
cuts.labels |
Character indicating the label to be used in the ccolour legend for each one of the values defined by 'cuts'. If not provided, as.character(cuts)' is used. |
cuts.style |
character, indicating how to finding class intervals for continuous numerical variables for choosing colours to be used in the figure. See |
legend.cex |
character expansion factor *relative* to current |
legend.title |
text to be displayed above the legned of colours (e.g., showing the measurement units of the raster being displayed). |
legend.title.cex |
expansion factor(s) for the legend title. Currently it is not used. See |
legend.fontsize |
size of text (in points) used in the legend title (e.g., showing the measurement units of the raster being displayed). |
... |
further arguments passed to |
The default levelplot panel draws dotted grey lines along
cell boundaries, making individual matrix values easier to distinguish.
Adapted from a not available web page (http://www2.warwick.ac.uk/fac/sci/moac/currentstudents/peter_cock/r/matrix_contour/)
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Loading the SanMartino precipitation data data(SanMartinoPPts) # Selecting only the values up to Dec/1960 x <- window(SanMartinoPPts, end=as.Date("1960-12-31")) ## Daily zoo to monthly zoo m <- daily2monthly(x, FUN=sum, na.rm=TRUE) # Creating a data.frame with monthly values per year in each column M <- matrix(m, ncol=12, byrow=TRUE) colnames(M) <- month.abb rownames(M) <- unique(format(time(m), "%Y")) # Plotting the monthly precipitation values from 1921 to 1960. # Useful for identifying dry/wet months matrixplot(M, ColorRamp="Precipitation", main="Monthly precipitation at San Martino st., [mm/month]")## Loading the SanMartino precipitation data data(SanMartinoPPts) # Selecting only the values up to Dec/1960 x <- window(SanMartinoPPts, end=as.Date("1960-12-31")) ## Daily zoo to monthly zoo m <- daily2monthly(x, FUN=sum, na.rm=TRUE) # Creating a data.frame with monthly values per year in each column M <- matrix(m, ncol=12, byrow=TRUE) colnames(M) <- month.abb rownames(M) <- unique(format(time(m), "%Y")) # Plotting the monthly precipitation values from 1921 to 1960. # Useful for identifying dry/wet months matrixplot(M, ColorRamp="Precipitation", main="Monthly precipitation at San Martino st., [mm/month]")
Given any starting and ending dates, it generates:
1) a vector of class 'Date' with all the months between the two dates (both of them included), OR
2) the amount of months between the two dates
mip(from, to, date.fmt = "%Y-%m-%d", out.type = "seq")mip(from, to, date.fmt = "%Y-%m-%d", out.type = "seq")
from |
Character indicating the starting date for creating the sequence. It has to be in the format indicated by |
to |
Character indicating the ending date for creating the sequence. It has to be in the format indicated by |
date.fmt |
Character indicating the format in which the dates are stored in |
out.type |
character indicating the type of result that is given by this function. Valid values are: |
Depending on the value of out.type, it returns:
1) a vector of class Date with all the months between from and to (both of them included), OR
2) a single numeric value with the amount of months between the two dates.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
# Sequence of monthly dates between "1961-01-01" and "1961-12-31" ## mip("1961-01-01", "1961-12-31") ## Computing the number of months between "1961-01-01" and "1965-06-30", ## with the date format "%d-%m-%Y" ## mip("01-01-1961", "30-06-1965", date.fmt= "%d-%m-%Y", out.type = "nmbr")# Sequence of monthly dates between "1961-01-01" and "1961-12-31" ## mip("1961-01-01", "1961-12-31") ## Computing the number of months between "1961-01-01" and "1965-06-30", ## with the date format "%d-%m-%Y" ## mip("01-01-1961", "30-06-1965", date.fmt= "%d-%m-%Y", out.type = "nmbr")
Generic function for obtaining 12 monthly values of a zoo object, by applying any R function to ALL the values in the object belonging to each one of the 12 calendar months (Jan...Dec).
monthlyfunction(x, ...) ## Default S3 method: monthlyfunction(x, FUN, na.rm = TRUE, ...) ## S3 method for class 'zoo' monthlyfunction(x, FUN, na.rm=TRUE,...) ## S3 method for class 'data.frame' monthlyfunction(x, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...) ## S3 method for class 'matrix' monthlyfunction(x, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...)monthlyfunction(x, ...) ## Default S3 method: monthlyfunction(x, FUN, na.rm = TRUE, ...) ## S3 method for class 'zoo' monthlyfunction(x, FUN, na.rm=TRUE,...) ## S3 method for class 'data.frame' monthlyfunction(x, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...) ## S3 method for class 'matrix' monthlyfunction(x, FUN, na.rm = TRUE, dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...)
x |
zoo, xts, data.frame or matrix object, with daily or monthly time series. |
FUN |
Function that will be applied to ALL the values in |
na.rm |
Logical. Should missing values be removed? |
dates |
It is only used when |
date.fmt |
It is only used when |
out.type |
It is only used when |
verbose |
Logical; if TRUE, progress messages are printed |
... |
further arguments passed to or from other methods |
When x is a zoo object, a numeric vector with 12 elements representing the computed monthly value for each month.
When x is a data.frame which columns represent measurements at different gauging stations, the resulting object is a data.frame with 12 columns and as many rows as gauging stations are in x, each row storing the computed 12 monthly value for each gauging station.
Due to the fact that FUN is applied over all the elements in x belonging to a given calendar month, its result will depend on the sampling frequency of x and the type of function provided by FUN (special attention have to be put when FUN=sum)
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
annualfunction, seasonalfunction, dm2seasonal, daily2monthly, daily2annual
## Loading daily streamflows (3 years) at the station ## Oca en Ona (Ebro River basin, Spain) data(OcaEnOnaQts) x <- OcaEnOnaQts ## Mean monthly streamflows at station 'x' monthlyfunction(x, FUN=mean, na.rm=TRUE) ############################ ## Boxplot of monthly values ## Daily to Monthly m <- daily2monthly(x, FUN=mean, na.rm=TRUE) ## Median of the monthly values at the station monthlyfunction(m, FUN=median, na.rm=TRUE) ## Vector with the three-letter abbreviations of the month names cmonth <- format(time(m), "%b") ## Creating ordered monthly factors months <- factor(cmonth, levels=unique(cmonth), ordered=TRUE) ## Boxplot of the monthly values boxplot( coredata(m) ~ months, col="lightblue", main="Monthly streamflows, [m3/s]") ############################## ############################## ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) x <- EbroPPtsMonthly ## Dates of 'x' dates <- as.Date(x[,1]) ## Monthly precipitation of all the stations in 'x' ## Not run: ## Sum of the monthly values in each station of 'x' z <- zoo( x[, 2:ncol(x)], dates) # Amount of years in 'x' (needed for computing the average) nyears <- yip(from=start(z), to=end(z), out.type="nmbr" ) m <- monthlyfunction(z, FUN=sum) ## Another way of computing the sum of the monthly values in each station of 'x' ## This way is usefult for posteriori boxplots m2 <- monthlyfunction(x, FUN=sum, dates=1, out.type="db") ## Average monthly precipitation in each station of 'x' m2$Value <- m2$Value / nyears ## Creating monthly factors m2$Month <- factor(m2$Month, levels=month.abb) ## boxplot of the monthly values in all stations boxplot(Value ~ Month, m2, col="lightyellow", main="Monthly Precipitation, [mm/month]") ## End(Not run)## Loading daily streamflows (3 years) at the station ## Oca en Ona (Ebro River basin, Spain) data(OcaEnOnaQts) x <- OcaEnOnaQts ## Mean monthly streamflows at station 'x' monthlyfunction(x, FUN=mean, na.rm=TRUE) ############################ ## Boxplot of monthly values ## Daily to Monthly m <- daily2monthly(x, FUN=mean, na.rm=TRUE) ## Median of the monthly values at the station monthlyfunction(m, FUN=median, na.rm=TRUE) ## Vector with the three-letter abbreviations of the month names cmonth <- format(time(m), "%b") ## Creating ordered monthly factors months <- factor(cmonth, levels=unique(cmonth), ordered=TRUE) ## Boxplot of the monthly values boxplot( coredata(m) ~ months, col="lightblue", main="Monthly streamflows, [m3/s]") ############################## ############################## ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) x <- EbroPPtsMonthly ## Dates of 'x' dates <- as.Date(x[,1]) ## Monthly precipitation of all the stations in 'x' ## Not run: ## Sum of the monthly values in each station of 'x' z <- zoo( x[, 2:ncol(x)], dates) # Amount of years in 'x' (needed for computing the average) nyears <- yip(from=start(z), to=end(z), out.type="nmbr" ) m <- monthlyfunction(z, FUN=sum) ## Another way of computing the sum of the monthly values in each station of 'x' ## This way is usefult for posteriori boxplots m2 <- monthlyfunction(x, FUN=sum, dates=1, out.type="db") ## Average monthly precipitation in each station of 'x' m2$Value <- m2$Value / nyears ## Creating monthly factors m2$Month <- factor(m2$Month, levels=month.abb) ## boxplot of the monthly values in all stations boxplot(Value ~ Month, m2, col="lightyellow", main="Monthly Precipitation, [mm/month]") ## End(Not run)
Generic functions for computing the temporal span covered by a
zoo object, expressed as years, months, weeks, days, or
hours.
nyears(x, ...) nmonths(x, ...) nweeks(x, ...) ndays(x, ...) nhours(x, ...) ## S3 method for class 'zoo' nyears(x, only.integer.output=FALSE, tz, verbose=TRUE, ...) ## S3 method for class 'zoo' nmonths(x, only.integer.output=FALSE, tz, verbose=TRUE, ...) ## S3 method for class 'zoo' nweeks(x, week.grouping="calendar", verbose=TRUE, ...) ## S3 method for class 'zoo' ndays(x, only.integer.output=FALSE, tz, verbose=TRUE, ...) ## S3 method for class 'zoo' nhours(x, only.integer.output=FALSE, tz, verbose=TRUE, ...)nyears(x, ...) nmonths(x, ...) nweeks(x, ...) ndays(x, ...) nhours(x, ...) ## S3 method for class 'zoo' nyears(x, only.integer.output=FALSE, tz, verbose=TRUE, ...) ## S3 method for class 'zoo' nmonths(x, only.integer.output=FALSE, tz, verbose=TRUE, ...) ## S3 method for class 'zoo' nweeks(x, week.grouping="calendar", verbose=TRUE, ...) ## S3 method for class 'zoo' ndays(x, only.integer.output=FALSE, tz, verbose=TRUE, ...) ## S3 method for class 'zoo' nhours(x, only.integer.output=FALSE, tz, verbose=TRUE, ...)
x |
A zoo object with a regular time index. |
only.integer.output |
logical; if |
week.grouping |
character indicating how weeks are counted by |
tz |
character, indicating the time zone in which the time index of |
verbose |
logical; if |
... |
further arguments passed to or from other methods. |
The returned value is computed from the first date/time to the inferred end of
the last observation. The end of the last observation is inferred from the
regular time step of x. For example, a daily object from
2020-01-01 to 2020-01-31 returns 1 month and 31
days.
Before computing the temporal span, the functions call
isComplete(x, out.type="all"). Therefore, incomplete objects are still
accepted when their time index has a regular frequency, but missing date/time
values are reported when verbose=TRUE.
For nweeks, the result is the number of weekly groups that
daily2weekly would produce with the same week.grouping.
A numeric value with the temporal span of x expressed in the requested
unit. nweeks returns the integer number of weekly groups. For the other
functions, an integer value is returned when only.integer.output=TRUE.
Mauricio Zambrano-Bigiarini, [email protected]
dates <- as.Date("2020-01-01") + 0:30 x <- zoo::zoo(seq_along(dates), dates) nyears(x, verbose=FALSE) nmonths(x, verbose=FALSE) nweeks(x, verbose=FALSE) ndays(x, verbose=FALSE) nhours(x, verbose=FALSE) y <- x[1:15] ndays(y, verbose=FALSE) ndays(y, only.integer.output=TRUE, verbose=FALSE)dates <- as.Date("2020-01-01") + 0:30 x <- zoo::zoo(seq_along(dates), dates) nyears(x, verbose=FALSE) nmonths(x, verbose=FALSE) nweeks(x, verbose=FALSE) ndays(x, verbose=FALSE) nhours(x, verbose=FALSE) y <- x[1:15] ndays(y, verbose=FALSE) ndays(y, only.integer.output=TRUE, verbose=FALSE)
Time series with daily streamflows of the Oca River (subcatchment of the Ebro River basin, Spain) measured at the gauging station "Ona" (Q093), for the period 01/Jan/1961 to 31/Dic/1963
data(OcaEnOnaQts)data(OcaEnOnaQts)
zoo object.
Downloaded from the web site of the Confederacion Hidrografica del Ebro (CHE) http://www.chebro.es/ (original link http://oph.chebro.es/documentacion/CaudalEA/CaudalEA.htm, last accessed [March 2010]).
These data are intended to be used for research purposes only, being distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.
Given a time series of precipitation and streamflow, this function plots the two time series in the same figure, streamflows as a normal time series and precipitation as bars coming from the upper part of the plotting window.
plot_pq(p, ...) ## S3 method for class 'zoo' plot_pq(p, q, ptype=c("original", "monthly"), na.fill=c("remove", "linear", "spline"), from=start(p), to=end(p), date.fmt=NULL, tz=NULL, main=ifelse(ptype=="original", "Precipitation and Streamflows", "Monthly Precipitation and Streamflows"), xlab=ifelse(ptype=="original", "Time", "Month"), ylab=c("P, [mm]", "Q, [m3/s]"), p.col=ifelse(ptype=="original", "blue", "lightblue"), q.col=ifelse(ptype=="original", "black", "blue"), leg.title="", leg.text=c("P", "Q"), q.pch=16, q.cex=0.3, start.month=1, plot.p.probs=TRUE, p.probs=c(0.25, 0.75), p.alpha=0.8, plot.q.probs=TRUE, q.probs=c(0.25, 0.75), q.probs.col="lightskyblue1", q.probs.alpha=0.8, labels=TRUE, labels.cex=0.8, labels.p.dy=NULL, labels.q.dx=c(rep(-0.2,6), rep(0.2,6)), labels.q.dy=rep(median(q, na.rm=TRUE)*1.3, 12), ...)plot_pq(p, ...) ## S3 method for class 'zoo' plot_pq(p, q, ptype=c("original", "monthly"), na.fill=c("remove", "linear", "spline"), from=start(p), to=end(p), date.fmt=NULL, tz=NULL, main=ifelse(ptype=="original", "Precipitation and Streamflows", "Monthly Precipitation and Streamflows"), xlab=ifelse(ptype=="original", "Time", "Month"), ylab=c("P, [mm]", "Q, [m3/s]"), p.col=ifelse(ptype=="original", "blue", "lightblue"), q.col=ifelse(ptype=="original", "black", "blue"), leg.title="", leg.text=c("P", "Q"), q.pch=16, q.cex=0.3, start.month=1, plot.p.probs=TRUE, p.probs=c(0.25, 0.75), p.alpha=0.8, plot.q.probs=TRUE, q.probs=c(0.25, 0.75), q.probs.col="lightskyblue1", q.probs.alpha=0.8, labels=TRUE, labels.cex=0.8, labels.p.dy=NULL, labels.q.dx=c(rep(-0.2,6), rep(0.2,6)), labels.q.dy=rep(median(q, na.rm=TRUE)*1.3, 12), ...)
p |
zoo object with precipitation time series, with any time frequency. |
q |
zoo object with streamflow time series, with any time frequency. |
ptype |
Character indicating the type of plot to be produced. Valid values are: |
na.fill |
Character indicating how to fill any NA present in |
from |
Character indicating the starting date for subsetting |
to |
Character indicating the ending date for subsetting |
date.fmt |
character indicating the format in which the dates are stored in |
tz |
character, with the specification of the time zone used for If This argument can be used when working with sub-daily zoo objects to force using time zones other than the local time zone for |
main |
The main title (on top) of the figure. |
xlab |
a title for the |
ylab |
a two-element title for the |
p.col |
character, representing the colors to be used for plotting the precipitation time series. |
q.col |
character, representing the colors to be used for plotting the streamflow time series. |
leg.title |
a character string or length-one expression giving a title to be placed at the top of the legend. |
leg.text |
a two-element character to appear in the legend placed at the bottom of the figure. |
q.pch |
numeric, representing the symbols used for plotting the streamflow time series. |
q.cex |
a numerical vector giving the amount by which plotting characters and symbols should be scaled relative to the default. This works as a multiple of |
start.month |
numeric in [1:12] indicating the starting month for the monthlycurve. Numeric values in [1, 12] represents months in [January, December]. By default |
plot.p.probs |
logical used to decide whether to show lower and upper uncertainty bounds for each one of the 12 monthly precipitation values. By default |
p.probs |
numeric of length 2. It defines the quantile values used to compute the lower and upper uncertainty bounds for each one of the 12 monthly precipitation values. This uncertainty bounds are drawn as vertical lines over the bars used to plot the 12 monthly precipitation values. |
p.alpha |
numeric of length 1, with the factor used to modify the opacity of |
plot.q.probs |
logical used to decide whether to show uncertainty bands around each one of the 12 monthly average or median streamflow values. By default |
q.probs |
numeric of length 2. It is used to define quantile values used to compute the lower and upper uncertainty bands around each one of the 12 monthly average or median streamflow. |
q.probs.col |
character with the color used to plot the uncertainty bands around the average or median streamflow values. |
q.probs.alpha |
numeric of length 1, with the factor used to modify the opacity of |
labels |
logical. Should monthly streamflow values to be shown above the lines?. By default |
labels.cex |
numeric giving the amount by which plotting characters used to show the numeric values of monthly streamflow values are scaled relative to the default. |
labels.p.dy |
numeric of length 12 giving the amount of vertical coordinate positions that have to be used to vertically shift the labels of monthly precipitation values. |
labels.q.dx |
numeric of length 12 giving the amount of horizontal coordinate positions that have to be used to horizontally shift the labels of monthly streamflow values. |
labels.q.dy |
numeric of length 12 giving the amount of vertical coordinate positions that have to be used to vertically shift the labels of monthly streamflow values. |
... |
further arguments passed to or from other methods. Not used yet. |
Given a time series of precipitation and streamflow, this function plots the two time series in the same figure, streamflows as a normal time series and precipitation as bars coming from the upper part of the plotting window.
A figure with the two time series in the same graphical area, streamflows as a normal time series and precipitation as bars coming from the upper part of the plotting window.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
hydroplot, climograph, fdc, fdcu, monthlyfunction
###################### ## Ex1: Plotting precipitation and streamflows for the full time period of both ## time series. ## First, we load the daily P and Q time series for the Cauquenes en ## El Arrayan catchment. P, [mm] is the first column and Q, [mm] is the ## fifth column. data(Cauquenes7336001) # Subsetting to only the 1981-1990 temporal period Cauquenes7336001 <- window(Cauquenes7336001, start="1981-01-01", end="1990-12-31") p <- Cauquenes7336001[, 1] q <- Cauquenes7336001[, 5] ## Plotting P and Q for the full time period of both time series plot_pq(p=p, q=q) ## Not run: ###################### ## Ex2: Plotting precipitation and streamflows only for a specific time period, ## from April to December 2000. plot_pq(p, q, from="1985-04-01", to="1985-12-31") ###################### ## Ex3: Plotting monthly values of precipitation and streamflows for the ## full time period of both time series. plot_pq(p, q, ptype="monthly") ###################### ## Ex4: Plotting monthly values of precipitation and streamflows for the ## full time period of both time series, but using a hydrologic year ## starting on April plot_pq(p, q, ptype="monthly", start.month=4) ## End(Not run)###################### ## Ex1: Plotting precipitation and streamflows for the full time period of both ## time series. ## First, we load the daily P and Q time series for the Cauquenes en ## El Arrayan catchment. P, [mm] is the first column and Q, [mm] is the ## fifth column. data(Cauquenes7336001) # Subsetting to only the 1981-1990 temporal period Cauquenes7336001 <- window(Cauquenes7336001, start="1981-01-01", end="1990-12-31") p <- Cauquenes7336001[, 1] q <- Cauquenes7336001[, 5] ## Plotting P and Q for the full time period of both time series plot_pq(p=p, q=q) ## Not run: ###################### ## Ex2: Plotting precipitation and streamflows only for a specific time period, ## from April to December 2000. plot_pq(p, q, from="1985-04-01", to="1985-12-31") ###################### ## Ex3: Plotting monthly values of precipitation and streamflows for the ## full time period of both time series. plot_pq(p, q, ptype="monthly") ###################### ## Ex4: Plotting monthly values of precipitation and streamflows for the ## full time period of both time series, but using a hydrologic year ## starting on April plot_pq(p, q, ptype="monthly", start.month=4) ## End(Not run)
Detects the sampling frequency of a precipitation zoo object with
sfreq and dispatches to precipQC_daily or
precipQC_subdaily. No files are written.
precipQC( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), ..., elevation=NULL, elevation.scale=500 )precipQC( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), ..., elevation=NULL, elevation.scale=500 )
x |
A univariate or multivariate numeric |
metadata, station.id, coords, elevation, elevation.scale
|
Optional station metadata, field-name selectors, and elevation-decay control
passed to the selected workflow. See |
... |
Arguments passed unchanged to the selected QC function. Because the daily and sub-daily functions have resolution-specific arguments, only arguments accepted by the detected workflow should be supplied. |
sfreq(x) returning "daily" selects
precipQC_daily(x, ...). Values "minute" and "hourly"
select precipQC_subdaily(x, ...). Weekly, monthly, quarterly, annual,
or other frequencies are rejected with an informative error because the
implemented thresholds and tests are not valid at those resolutions.
An object of class "precipQC"; see precipQC-class.
Mauricio Zambrano-Bigiarini, [email protected]
sfreq, precipQC_daily,
precipQC_subdaily, plot.precipQC
dates <- seq(as.Date("2020-01-01"), by="day", length.out=40) x <- zoo(cbind(A=rep(0, 40), B=rep(0, 40)), dates) qc <- precipQC( x, min.years=0, checks=c(climatology=FALSE, spatial=FALSE, dryspell=FALSE, breakpoint=FALSE) ) qc$settings$resolutiondates <- seq(as.Date("2020-01-01"), by="day", length.out=40) x <- zoo(cbind(A=rep(0, 40), B=rep(0, 40)), dates) qc <- precipQC( x, min.years=0, checks=c(climatology=FALSE, spatial=FALSE, dryspell=FALSE, breakpoint=FALSE) ) qc$settings$resolution
Applies a conservative, multi-test quality-control workflow to one or more
daily precipitation series in a zoo object. Individual observations are
flagged for review or rejection, stations are recommended for acceptance or
discarding, and no files are written.
precipQC_daily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, duplicate=TRUE, frequency=TRUE, gap=TRUE, climatology=TRUE, persistence=TRUE, accumulation=TRUE, weekday=TRUE, spatial=TRUE, dryspell=TRUE, breakpoint=TRUE), lower=0, upper=1825, wet.threshold=0.1, duplicate.min.month=20L, duplicate.min.year=300L, duplicate.min.nonzero=3L, frequency.window=10L, frequency.min.samples=20L, gap.threshold=300, gap.min.samples=30L, climatology.window=15L, climatology.prob=0.999, climatology.z=8, climatology.min.samples=30L, persistence.threshold=10, persistence.run=5L, weekday.min.wet=20L, weekday.alpha=0.001, weekday.ratio=0.5, spatial.days=c(1L, 3L, 7L), spatial.cr=3, n.neighbours=10L, max.distance=400, min.neighbours=2L, min.overlap=30L, min.correlation=0, dryspell.days=15L, neighbour.wet.days=3L, neighbour.fraction=1, correction=c("none", "set_na", "spatial"), min.evidence=2L, max.missing=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, elevation=NULL, elevation.scale=500 )precipQC_daily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, duplicate=TRUE, frequency=TRUE, gap=TRUE, climatology=TRUE, persistence=TRUE, accumulation=TRUE, weekday=TRUE, spatial=TRUE, dryspell=TRUE, breakpoint=TRUE), lower=0, upper=1825, wet.threshold=0.1, duplicate.min.month=20L, duplicate.min.year=300L, duplicate.min.nonzero=3L, frequency.window=10L, frequency.min.samples=20L, gap.threshold=300, gap.min.samples=30L, climatology.window=15L, climatology.prob=0.999, climatology.z=8, climatology.min.samples=30L, persistence.threshold=10, persistence.run=5L, weekday.min.wet=20L, weekday.alpha=0.001, weekday.ratio=0.5, spatial.days=c(1L, 3L, 7L), spatial.cr=3, n.neighbours=10L, max.distance=400, min.neighbours=2L, min.overlap=30L, min.correlation=0, dryspell.days=15L, neighbour.wet.days=3L, neighbour.fraction=1, correction=c("none", "set_na", "spatial"), min.evidence=2L, max.missing=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, elevation=NULL, elevation.scale=500 )
x |
A |
metadata |
|
station.id |
Character string naming the metadata column that contains the column names of
|
coords |
Two character strings naming longitude and latitude columns in
|
elevation |
|
elevation.scale |
Positive elevation-decay scale in metres. With elevation metadata, candidate
neighbours and their spatial weights are penalized by
|
checks |
Named logical vector. Any subset of |
duplicate.min.month, duplicate.min.year, duplicate.min.nonzero
|
Minimum complete paired month positions, complete paired year positions, and non-zero totals in both blocks for copied-block detection. |
frequency.window, frequency.min.samples
|
Number of consecutive non-zero reports examined for clustered identical values and minimum calendar-month wet sample used for their percentile screen. |
gap.threshold, gap.min.samples
|
Minimum adjacent separation in a sorted calendar-month wet distribution and minimum wet sample required for that check. |
lower, upper
|
Physical lower and upper limits, in mm/day. The default upper limit is the historical 24-hour world record used by Hamada et al. (2011). Regional limits should be supplied when authoritative values are available. |
wet.threshold |
Depth in mm separating dry and wet observations. |
climatology.window |
Odd or even positive integer giving the width, in calendar days, of the moving day-of-year climatological window. |
climatology.prob |
Upper empirical probability used by the climatological test. |
climatology.z |
Number of robust standard deviations above the median on the
|
climatology.min.samples |
Minimum number of observations needed to estimate a climatological limit. |
persistence.threshold |
Minimum repeated non-zero value, in mm/day, to which
|
persistence.run |
Minimum run length for repeated values at or above
|
weekday.min.wet |
Minimum number of wet days required in a station-year before the weekday false-zero test is attempted. |
weekday.alpha |
Significance level for the exposure-adjusted chi-squared comparison of wet-day occurrence among the seven weekdays. |
weekday.ratio |
Maximum ratio of observed to expected wet days used to identify an
under-recorded weekday after the overall weekday test is significant. It must
be in |
spatial.days |
Positive integers giving the rolling accumulation durations, in days, at which spatial consistency is tested. A flag at an accumulated endpoint is expanded to every contributing daily value. |
spatial.cr |
Critical ratio for transformed observed-minus-neighbour-estimate residuals. The default follows the initial value used by El Hachem et al. (2022). |
n.neighbours |
Maximum number of neighbours used for each target station. |
max.distance |
Maximum station-neighbour distance in km when coordinates are available. |
min.neighbours |
Minimum number of simultaneous valid neighbours needed for a spatial estimate. |
min.overlap |
Minimum number of paired observations required when selecting neighbours. |
min.correlation |
Minimum Spearman correlation preferred when selecting neighbours. When too few preferred neighbours remain, the best eligible neighbours are used. |
dryspell.days |
Length of a target-station dry window to compare with neighbours. |
neighbour.wet.days |
Number of wet days a neighbour must have during a target-station dry window. |
neighbour.fraction |
Fraction of available neighbours that must corroborate a suspicious dry
window. It must be in |
correction |
Correction policy. |
min.evidence |
Number of independent non-hard flags required to reject an observation.
Range, copied-block, clustered frequent-value, distribution-gap, persistence,
accumulated-total, and spatially corroborated dry-spell flags are treated as
hard evidence. A value with less evidence remains in the
|
max.missing |
Maximum missing fraction allowed for a station recommendation of
|
max.suspicious |
Maximum fraction of confirmed suspicious observations allowed for a station
recommendation of |
min.years |
Minimum record length in years required for a station recommendation of
|
discard.breakpoint |
Logical. If |
The workflow combines tests that address different error mechanisms instead of treating one statistical anomaly as proof of error.
Physical range: negative depths and values above a defensible record limit are impossible or require review. Record limits are screening limits, not estimates of local return levels. This is the gross-error stage used by Hamada et al. (2011) and Estevez et al. (2022).
Climatological plausibility: precipitation is transformed with
log1p to reduce positive skew. Within a moving 15-day calendar
window, an upper limit combines an empirical quantile with a robust
median/MAD limit. The largest exceedance is removed iteratively before the
limit is recomputed. This is a robust adaptation of the calendar-window
outlier test of Hamada et al. (2011), consistent with the robust and
month-aware limits discussed by Stepanek et al. (2009), Estevez et al.
(2022), and Golkhatmi and Farzandi (2024).
Persistence: identical non-zero values repeated for several days may indicate a stuck sensor, copied record, or truncated measurement. The defaults reproduce the daily criterion in Hamada et al. (2011), while Vicente-Serrano et al. (2010) and Estevez et al. (2022) independently use repeated-value screening in daily databases.
Copied blocks, clustered identical values, and distribution gaps: complete identical years or months, tiered frequent identical values among ten non-zero reports, and a wet-distribution tail separated by at least 300 mm are flagged as hard recording-integrity evidence. These tests reproduce the daily precipitation duplicate, frequent-value, and gap checks of Durre et al. (2010), with explicit minimum samples to avoid declaring sparse blocks identical.
Accumulated totals: a large value immediately after missing days is flagged as a possible multi-day accumulation. Automatic redistribution is not attempted because the period and total must be known reliably. Scherrer et al. (2011) redistributed known accumulated totals proportionally to spatial estimates.
Systematic weekday false zeros: within each station-year, the distribution of wet days is compared with the weekday exposure. If the distribution is highly inconsistent and a weekday records at most the requested fraction of its expected wet days, dry values on that weekday are flagged for review. This operationalizes the weekday-zero quality component of Estevez et al. (2022), with exposure adjustment to avoid mistaking uneven missingness for under-recording.
Multi-scale spatial consistency: each station is removed in
turn, its transformed precipitation is estimated from up to ten nearby
stations, and the residual is standardized by local and historical robust
dispersion. The test is repeated for 1-, 3-, and 7-day rolling totals by
default. Geographic distance limits the candidate set. If elevation is
supplied, height similarity also affects neighbour ranking and the
inverse-distance weights, which avoids treating a nearby station across a
large orographic contrast as equally representative. A station missing
either coordinate remains testable: its neighbours are selected by temporal
correlation. For a located target, eligible located neighbours are preferred
and unlocated neighbours are conservative fallbacks that are not subjected
to max.distance because their distance is unknown. This combines the
neighbour logic of Scherrer et al. (2011) with
the multi-aggregation critical-ratio idea of El Hachem et al. (2022).
Relative candidate/reference comparisons are also supported by Stepanek et
al. (2009) and Vicente-Serrano et al. (2010).
Spatially corroborated dry spells: a long target-station dry period is flagged only when the selected neighbours repeatedly record wet days, adapting the GSDR-QC dry-neighbour rule of Lewis et al. (2021) and the suspect-zero comparisons of Vicente-Serrano et al. (2010) and Golkhatmi and Farzandi (2024).
Homogeneity: Pettitt rank tests are applied to sufficiently complete annual precipitation totals, wet-day counts, maxima, and counts above the station's wet-day 99th percentile. P-values are Holm-adjusted and the strongest diagnostic is reported. The multi-indicator design follows Vicente-Serrano et al. (2010); the cautious interpretation and use of multiple evidence follows Stepanek et al. (2009). The breakpoint is diagnostic by default because station moves, equipment changes, and true climatic changes can produce similar signals.
Convective precipitation can be genuinely local. Therefore a spatial flag by
itself is labelled for review, and default correction is disabled. Confirmed
rejection requires either a hard physical/recording test or at least
min.evidence coincident flags. Correlation-only results for stations
without coordinates should be interpreted more cautiously because geographic
proximity cannot be verified.
An object of class "precipQC", which is a list containing:
accepted.metadata and discarded.metadata: station
metadata plus QC diagnostics and the recommendation reason;
accepted.data: unmodified daily series for accepted stations;
accepted.corrected: accepted-station series after the requested
correction policy;
suspicious: one row per flagged station-time value, including
the tests, evidence count, action, spatial estimate, and correction;
corrections: an audit table of changed values;
flags: named logical zoo objects returned by the
individual tests;
flag.count, rejected, station.summary,
breakpoint, spatial diagnostics, neighbours, and settings.
Mauricio Zambrano-Bigiarini, [email protected]
Durre, I., Menne, M. J., Gleason, B. E., Houston, T. G. and Vose, R. S. (2010). Comprehensive automated quality assurance of daily surface observations. Journal of Applied Meteorology and Climatology, 49, 1615–1633.
Hamada, A., Arakawa, O. and Yatagai, A. (2011). An automated quality control method for daily rain-gauge data. Global Environmental Research, 15, 183–192.
Scherrer, S. C., Begert, M., Croci-Maspoli, M. and Appenzeller, C. (2011). Operational quality control of daily precipitation using spatio-climatological plausibility testing. Meteorologische Zeitschrift, 20, 397–407.
El Hachem, A. et al. (2022). Space-time statistical quality control of extreme precipitation observations. Hydrology and Earth System Sciences, 26, 6137–6146.
Lewis, E. et al. (2021). Quality control of a global hourly rainfall dataset. Environmental Modelling and Software, 144, 105169.
Stepanek, P., Zahradnicek, P. and Skalak, P. (2009). Data quality control and homogenization of air temperature and precipitation series in the area of the Czech Republic in the period 1961–2007. Advances in Science and Research, 3, 23–26.
Vicente-Serrano, S. M., Begueria, S., Lopez-Moreno, J. I., Garcia-Vera, M. A. and Stepanek, P. (2010). A complete daily precipitation database for northeast Spain: reconstruction, quality control, and homogeneity. International Journal of Climatology, 30, 1146–1163.
Estevez, J., Llabres-Brustenga, A., Casas-Castillo, M. C., Garcia-Marin, A. P., Kirchner, R. and Rodriguez-Sola, R. (2022). A quality control procedure for long-term series of daily precipitation data in a semiarid environment. Theoretical and Applied Climatology, 149, 1029–1041.
Golkhatmi, N. S. N. and Farzandi, M. (2024). Enhancing rainfall data consistency and completeness: a spatiotemporal quality control approach and missing data reconstruction using MICE on large precipitation datasets. Water Resources Management, 38, 815–833.
Serrano-Notivoli, R. and Tejedor, E. (2021). From rain to data: a review of the creation of monthly and daily station-based gridded precipitation datasets. WIREs Water, 8, e1555.
precipQC, precipQC_subdaily,
precipQC_range, precipQC_weekday,
precipQC_spatial, plot.precipQC,
zoo
set.seed(1) dates <- seq(as.Date("2018-01-01"), by="day", length.out=400) values <- matrix(stats::rgamma(length(dates) * 3, 0.4, 1), ncol=3) values[values < 1] <- 0 values[20, 1] <- -1 colnames(values) <- c("A", "B", "C") pcp <- zoo(values, dates) meta <- data.frame(code=colnames(pcp), longitude=c(-71.2, -71.1, -71.0), latitude=c(-33.2, -33.1, -33.0), altitude_m=c(100, 250, 400)) qc <- precipQC_daily(pcp, metadata=meta, station.id="code", coords=c("longitude", "latitude"), elevation="altitude_m", min.years=0, checks=c(breakpoint=FALSE)) qc$station.summary head(qc$suspicious) plot(qc)set.seed(1) dates <- seq(as.Date("2018-01-01"), by="day", length.out=400) values <- matrix(stats::rgamma(length(dates) * 3, 0.4, 1), ncol=3) values[values < 1] <- 0 values[20, 1] <- -1 colnames(values) <- c("A", "B", "C") pcp <- zoo(values, dates) meta <- data.frame(code=colnames(pcp), longitude=c(-71.2, -71.1, -71.0), latitude=c(-33.2, -33.1, -33.0), altitude_m=c(100, 250, 400)) qc <- precipQC_daily(pcp, metadata=meta, station.id="code", coords=c("longitude", "latitude"), elevation="altitude_m", min.years=0, checks=c(breakpoint=FALSE)) qc$station.summary head(qc$suspicious) plot(qc)
Applies physical, climatological, temporal, accumulation, spatial, dry-spell,
and homogeneity checks to one or more sub-daily precipitation series in a
zoo object. It returns auditable point flags, optional corrections, and
station acceptance recommendations without writing files.
precipQC_subdaily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, climatology=TRUE, persistence=TRUE, daily.accumulation=TRUE, monthly.accumulation=TRUE, weekday=TRUE, spatial=TRUE, dryspell=TRUE, breakpoint=TRUE), lower=0, max.rate=401, wet.threshold=0.1, climatology.prob=0.999, climatology.z=8, climatology.min.samples=100L, persistence.threshold=NULL, persistence.high.run=2L, persistence.long.hours=24, accumulation.factor=2, weekday.min.wet=20L, weekday.alpha=0.001, weekday.ratio=0.5, weekday.min.coverage=0.9, spatial.hours=c(0, 1, 3, 6, 24), spatial.cr=3, n.neighbours=10L, max.distance=50, min.neighbours=2L, min.overlap=100L, min.correlation=0, dryspell.days=15L, neighbour.wet.days=3L, neighbour.fraction=1, correction=c("none", "set_na", "spatial"), min.evidence=2L, max.missing=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, elevation=NULL, elevation.scale=500 )precipQC_subdaily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, climatology=TRUE, persistence=TRUE, daily.accumulation=TRUE, monthly.accumulation=TRUE, weekday=TRUE, spatial=TRUE, dryspell=TRUE, breakpoint=TRUE), lower=0, max.rate=401, wet.threshold=0.1, climatology.prob=0.999, climatology.z=8, climatology.min.samples=100L, persistence.threshold=NULL, persistence.high.run=2L, persistence.long.hours=24, accumulation.factor=2, weekday.min.wet=20L, weekday.alpha=0.001, weekday.ratio=0.5, weekday.min.coverage=0.9, spatial.hours=c(0, 1, 3, 6, 24), spatial.cr=3, n.neighbours=10L, max.distance=50, min.neighbours=2L, min.overlap=100L, min.correlation=0, dryspell.days=15L, neighbour.wet.days=3L, neighbour.fraction=1, correction=c("none", "set_na", "spatial"), min.evidence=2L, max.missing=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, elevation=NULL, elevation.scale=500 )
x |
A |
metadata, station.id, coords, elevation, elevation.scale
|
Station metadata and its identifier/coordinate column names. See
|
checks |
Named logical vector. Any subset of |
lower |
Physical lower limit in mm per interval. |
max.rate |
Upper screening rate in mm/hour. It is multiplied by the detected interval length, so the range test uses a depth appropriate to the native time step. The default is the conservative world-record hourly value used by Lewis et al. (2021), not a local design-rainfall estimate. |
wet.threshold |
Depth in mm separating dry and wet intervals. |
climatology.prob, climatology.z, climatology.min.samples
|
Empirical probability, robust transformed-scale multiplier, and minimum sample size used to estimate month-specific upper climatological limits. |
persistence.threshold |
Minimum high value to test for short repeated runs. If |
persistence.high.run |
Minimum number of consecutive identical high values. |
persistence.long.hours |
Duration at which any repeated wet value is suspicious. It is converted to a number of native intervals. |
accumulation.factor |
Multiplier of the station mean wet-day depth used to screen possible daily and monthly totals recorded in one sub-daily interval. |
weekday.min.wet, weekday.alpha, weekday.ratio
|
Minimum annual wet-day count, significance level, and maximum
observed-to-expected wet-day ratio for the weekday false-zero test. These have
the same interpretation as the corresponding arguments of
|
weekday.min.coverage |
Minimum fraction of expected native intervals that must be observed before a
sub-daily calendar day is included in the weekday test. It must be in
|
spatial.hours |
Accumulation durations in hours for spatial tests. Zero denotes the native interval. Positive values must be integer multiples of the detected interval. Flags on accumulated windows are expanded to their contributing native observations. |
spatial.cr |
Critical ratio for the transformed observation-neighbour residual. |
n.neighbours, max.distance, min.neighbours, min.overlap, min.correlation
|
Controls for selecting up to |
dryspell.days, neighbour.wet.days, neighbour.fraction
|
Controls for flagging target-station dry windows that selected neighbours do not corroborate. |
correction |
|
min.evidence |
Number of coincident non-hard flags required to reject an observation. Physical range, persistence, accumulation, and corroborated dry-spell flags are hard evidence. The weekday test is non-hard evidence and therefore remains for review unless another active test corroborates it. |
max.missing, max.suspicious, min.years
|
Maximum missing fraction, maximum confirmed-suspicious fraction, and minimum record length used for station acceptance recommendations. |
discard.breakpoint |
Logical. Whether a large significant homogeneity breakpoint should by itself
cause a discard recommendation. The conservative default is |
The sub-daily workflow follows a layered rule base:
Range and temporal-resolution validation. Negative depths and depths exceeding a duration-adjusted screening record are flagged. The time index is checked for strict ordering and a consistent modal interval. This addresses impossible values, duplicated timestamps, and mixed frequencies discussed by Fileni et al. (2023) and Villalobos-Herrera et al. (2022), and implements the gross-error and range stages of Jurczyk et al. (2020).
Month-specific climatological plausibility. A
log1p-scale empirical/robust upper limit is estimated iteratively for
each calendar month. The transformation reduces the strong positive skew of
sub-daily rainfall, following the motivation for Box–Cox transformation and
month-specific plausibility limits in El Hachem et al. (2022).
Repeated values. Two or more identical values above a high threshold, or any identical wet value repeated for at least 24 hours, are flagged. These rules adapt the streak checks of Lewis et al. (2021) and the blocked-sensor consistency check of Jurczyk et al. (2020).
Daily and monthly accumulations. A large isolated interval preceded and followed by dry intervals is tested as a possible longer-period total placed at one timestamp. The daily test uses 23-hour flanks; the monthly test uses a preceding 28-day dry period and a 23-hour following flank. Blenkinsop et al. (2017) and Lewis et al. (2021) show why surrounding dryness is important for avoiding false flags.
Systematic weekday false zeros. Native observations are
aggregated in memory to daily totals only when at least
weekday.min.coverage of the expected intervals is present. The daily
wet-day occurrence test of precipQC_weekday is then applied,
and suspicious dry days are expanded back to their finite dry native
intervals. This adapts the weekday-zero quality component of Estevez et al.
(2022) without treating partially observed days as zero-rainfall days.
Multi-scale spatial consistency. Leave-one-station-out robust neighbour estimates and critical ratios are calculated at the native, 1-, 3-, 6-, and 24-hour scales by default. Multi-scale testing follows El Hachem et al. (2022), who showed that an error may be visible at one accumulation but hidden at another; station-neighbour corroboration also follows the spatial consistency stage of Jurczyk et al. (2020). When elevation is supplied, neighbour ranking and inverse-distance weights also favour stations with similar height. Missing target coordinates trigger correlation-based selection; a located target uses unlocated neighbours only after eligible located neighbours.
Spatial dry-spell consistency. Fifteen-day dry windows are flagged only when neighbours record at least three wet days, adapting the GSDR-QC rule described by Lewis et al. (2021) and the regional suspect-zero logic of Golkhatmi and Farzandi (2024).
Homogeneity. Sub-daily values are first aggregated to daily totals. Pettitt tests are then applied to annual totals, wet-day counts, maxima, and extreme-day counts, with Holm-adjusted p-values. This is a diagnostic rather than a default discard rule, consistent with the multi-test caution of Stepanek et al. (2009).
Sub-hourly tip-time tests cannot be reconstructed from already accumulated
zoo values. In particular, the inter-tip statistic and 1-minute
thresholds of Villalobos-Herrera et al. (2022) require raw tip timestamps.
The present function instead checks the finest interval actually supplied and
then aggregates it to multiple durations.
Spatial disagreement is evidence for review, not proof of error, because short-duration convective rainfall can be highly localized. By default an observation is rejected only by a hard test or by agreement of at least two non-hard tests.
An object of class "precipQC". It contains accepted and discarded
metadata data.frames, unmodified and optionally corrected zoo series
for accepted stations, a long-form suspicious table, a
corrections audit table, logical flag series for every active test,
station diagnostics, spatial diagnostics, neighbours, and settings. See
precipQC-class for the complete structure.
Mauricio Zambrano-Bigiarini, [email protected]
Blenkinsop, S., Lewis, E., Chan, S. C. and Fowler, H. J. (2017). Quality-control of an hourly rainfall dataset and climatology of extremes for the UK. International Journal of Climatology, 37, 722–740.
Lewis, E. et al. (2021). Quality control of a global hourly rainfall dataset. Environmental Modelling and Software, 144, 105169.
El Hachem, A. et al. (2022). Space-time statistical quality control of extreme precipitation observations. Hydrology and Earth System Sciences, 26, 6137–6146.
Villalobos-Herrera, R. et al. (2022). Sub-hourly resolution quality control of rain-gauge data significantly improves regional sub-daily return level estimates. Quarterly Journal of the Royal Meteorological Society, 148, 3252–3271.
Pritchard, D. et al. (2023). An observation-based dataset of global sub-daily precipitation indices (GSDR-I). Scientific Data, 10, 393.
Fileni, F., Fowler, H. J., Lewis, E., McLay, F. and Yang, L. (2023). A quality-control framework for sub-daily flow and level data for hydrological modelling in Great Britain. Hydrology Research, 54, 1357–1367.
Jurczyk, A., Szturc, J., Otop, I., Osrodka, K. and Struzik, P. (2020). Quality-based combination of multi-source precipitation data. Remote Sensing, 12, 1709.
Stepanek, P., Zahradnicek, P. and Skalak, P. (2009). Data quality control and homogenization of air temperature and precipitation series in the area of the Czech Republic in the period 1961–2007. Advances in Science and Research, 3, 23–26.
Golkhatmi, N. S. N. and Farzandi, M. (2024). Enhancing rainfall data consistency and completeness: a spatiotemporal quality control approach and missing data reconstruction using MICE on large precipitation datasets. Water Resources Management, 38, 815–833.
Estevez, J., Llabres-Brustenga, A., Casas-Castillo, M. C., Garcia-Marin, A. P., Kirchner, R. and Rodriguez-Sola, R. (2022). A quality control procedure for long-term series of daily precipitation data in a semiarid environment. Theoretical and Applied Climatology, 149, 1029–1041.
precipQC, precipQC_daily,
precipQC_persistence,
precipQC_accumulation, precipQC_weekday,
precipQC_spatial,
plot.precipQC, subhourly2nhourly
set.seed(2) times <- seq(as.POSIXct("2020-01-01 00:00:00", tz="UTC"), by="hour", length.out=24 * 40) values <- matrix(stats::rexp(length(times) * 3), ncol=3) values[values < 2] <- 0 values[10, 1] <- -1 colnames(values) <- c("A", "B", "C") pcp <- zoo(values, times) meta <- data.frame(station=colnames(pcp), lon=c(-71.2, -71.1, -71.0), lat=c(-33.2, -33.1, -33.0)) qc <- precipQC_subdaily( pcp, metadata=meta, min.years=0, spatial.hours=c(0, 1, 3), checks=c(monthly.accumulation=FALSE, breakpoint=FALSE) ) qc$station.summary head(qc$suspicious) plot(qc)set.seed(2) times <- seq(as.POSIXct("2020-01-01 00:00:00", tz="UTC"), by="hour", length.out=24 * 40) values <- matrix(stats::rexp(length(times) * 3), ncol=3) values[values < 2] <- 0 values[10, 1] <- -1 colnames(values) <- c("A", "B", "C") pcp <- zoo(values, times) meta <- data.frame(station=colnames(pcp), lon=c(-71.2, -71.1, -71.0), lat=c(-33.2, -33.1, -33.0)) qc <- precipQC_subdaily( pcp, metadata=meta, min.years=0, spatial.hours=c(0, 1, 3), checks=c(monthly.accumulation=FALSE, breakpoint=FALSE) ) qc$station.summary head(qc$suspicious) plot(qc)
Individual tests used by precipQC_daily and
precipQC_subdaily. They are exported so that each source of QC
evidence can be inspected or tuned independently.
precipQC_range(x, lower=0, upper=Inf) precipQC_persistence( x, high.threshold=10, high.run=5L, long.run=Inf, wet.threshold=0.1 ) precipQC_duplicate( x, min.month.values=20L, min.year.values=300L, min.nonzero=3L, wet.threshold=0.1 ) precipQC_frequency( x, window=10L, counts=c(9L, 8L, 7L, 5L), probs=c(0.3, 0.5, 0.7, 0.9), min.samples=20L, wet.threshold=0.1 ) precipQC_gap(x, gap=300, min.samples=30L, wet.threshold=0.1) precipQC_weekday( x, wet.threshold=0.1, min.wet.days=20L, alpha=0.001, underreporting.ratio=0.5 ) precipQC_climatology( x, group=c("dayofyear", "month"), window=15L, prob=0.999, z=8, min.samples=30L, wet.threshold=0.1 ) precipQC_accumulation( x, interval.hours, preceding.hours=23, following.hours=23, threshold.factor=2, wet.threshold=0.1, missing.only=FALSE ) precipQC_spatial( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), n.neighbours=10L, max.distance=Inf, min.neighbours=2L, min.overlap=30L, min.correlation=0, cr.threshold=3, wet.threshold=0.1, elevation=NULL, elevation.scale=500 ) precipQC_dryspell( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), n.neighbours=10L, max.distance=Inf, window.days=15L, neighbour.wet.days=3L, neighbour.fraction=1, wet.threshold=0.1, elevation=NULL, elevation.scale=500 ) precipQC_breakpoint( x, wet.threshold=0.1, min.years=5L, alpha=0.05, min.relative.change=0.5, min.completeness=0.8, indicators=c("total", "wet.days", "maximum", "extreme.days") )precipQC_range(x, lower=0, upper=Inf) precipQC_persistence( x, high.threshold=10, high.run=5L, long.run=Inf, wet.threshold=0.1 ) precipQC_duplicate( x, min.month.values=20L, min.year.values=300L, min.nonzero=3L, wet.threshold=0.1 ) precipQC_frequency( x, window=10L, counts=c(9L, 8L, 7L, 5L), probs=c(0.3, 0.5, 0.7, 0.9), min.samples=20L, wet.threshold=0.1 ) precipQC_gap(x, gap=300, min.samples=30L, wet.threshold=0.1) precipQC_weekday( x, wet.threshold=0.1, min.wet.days=20L, alpha=0.001, underreporting.ratio=0.5 ) precipQC_climatology( x, group=c("dayofyear", "month"), window=15L, prob=0.999, z=8, min.samples=30L, wet.threshold=0.1 ) precipQC_accumulation( x, interval.hours, preceding.hours=23, following.hours=23, threshold.factor=2, wet.threshold=0.1, missing.only=FALSE ) precipQC_spatial( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), n.neighbours=10L, max.distance=Inf, min.neighbours=2L, min.overlap=30L, min.correlation=0, cr.threshold=3, wet.threshold=0.1, elevation=NULL, elevation.scale=500 ) precipQC_dryspell( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), n.neighbours=10L, max.distance=Inf, window.days=15L, neighbour.wet.days=3L, neighbour.fraction=1, wet.threshold=0.1, elevation=NULL, elevation.scale=500 ) precipQC_breakpoint( x, wet.threshold=0.1, min.years=5L, alpha=0.05, min.relative.change=0.5, min.completeness=0.8, indicators=c("total", "wet.days", "maximum", "extreme.days") )
x |
A numeric |
lower, upper
|
Physical lower and upper precipitation limits. Each may be scalar or contain one value per station. |
high.threshold |
Scalar or station-specific lower bound for repeated high values. |
high.run |
Minimum number of consecutive identical high values. |
long.run |
Minimum run length for any repeated wet value, or |
min.month.values, min.year.values
|
Minimum number of complete corresponding calendar positions for copied-month and copied-year comparisons. |
min.nonzero |
Minimum non-zero values required in both blocks before precipitation duplication is flagged. |
counts, probs
|
Paired repeated-value counts and minimum climatological probabilities for the clustered frequent-value rules. |
gap |
Minimum separation in mm between adjacent sorted wet values in one calendar month distribution. |
min.wet.days |
Minimum annual number of wet days required for the weekday test. |
underreporting.ratio |
Maximum observed-to-expected wet-day ratio used to identify an under-recorded weekday after the overall weekday occurrence test is significant. |
wet.threshold |
Precipitation depth that separates dry and wet observations. |
group |
Climatological grouping: a moving calendar-day window or calendar months. |
window |
Calendar-day window width. It is ignored for monthly grouping. |
prob, z, min.samples
|
Empirical upper probability, robust standard-deviation multiplier on the
|
interval.hours |
Native time-step length in hours for the accumulation test. |
preceding.hours, following.hours
|
Durations on either side of a possible accumulated total that must be dry or missing. |
threshold.factor |
Multiplier of station mean wet-day precipitation used as the lower screen for an accumulated total. |
missing.only |
Logical. If |
metadata |
|
station.id |
Name of the metadata station-identifier column. |
coords |
Names of numeric longitude and latitude columns in decimal degrees, in that
order. Individual entries may be |
elevation |
|
elevation.scale |
Positive elevation-decay scale in metres. Height similarity is
|
n.neighbours |
Maximum number of neighbours. |
max.distance |
Maximum great-circle distance in km when coordinates are available. Pairs for which either station lacks a coordinate are not distance-filtered. |
min.neighbours |
Minimum simultaneous valid neighbours for a spatial estimate. |
min.overlap |
Minimum paired observations for neighbour selection. |
min.correlation |
Preferred minimum Spearman correlation between target and neighbour. |
cr.threshold |
Critical ratio for the absolute transformed residual divided by robust local and historical dispersion. |
window.days |
Length of target-station dry windows. |
neighbour.wet.days |
Minimum number of wet days during the same window at a neighbour. |
neighbour.fraction |
Fraction of selected neighbours that must meet
|
min.years |
Minimum number of annual wet-period medians for the Pettitt test. |
alpha |
Significance level for the weekday test or the Holm-adjusted Pettitt p-value. |
min.relative.change |
Minimum absolute relative difference between pre- and post-break medians. |
min.completeness |
Minimum fraction of expected daily observations required to retain an annual indicator in breakpoint testing. |
indicators |
Unique subset of |
precipQC_range flags values outside physical limits.
precipQC_persistence run-length encodes each series. Repeated high
values and exceptionally long runs of any wet value are flagged. Exact
repetition is intentional because this test targets copied, stuck, or
artificially disaggregated records.
precipQC_duplicate compares corresponding positions in entire years,
different months of the same year, and the same calendar month in different
years. Both blocks must be complete over the comparison and contain at least
min.nonzero wet values. This implements the precipitation duplicate
checks of Durre et al. (2010).
precipQC_frequency scans consecutive non-zero reports, skipping dry and
missing observations, for the tiered 9/10, 8/10, 7/10, and 5/10 identical-value
rules of Durre et al. (2010). The repeated amount must also exceed its
calendar-month climatological percentile, which reduces false positives from
measurement resolution.
precipQC_gap sorts wet observations separately by calendar month. When
an adjacent gap is at least gap, it flags the upper tail. The 300-mm
default follows the daily precipitation distribution-gap test of Durre et al.
(2010).
precipQC_weekday requires at most one observation per calendar day and
compares station-year wet-day counts among weekdays,
after adjusting the expected counts for the number of available observations
on each weekday. Only when the overall chi-squared test is highly significant
does it flag dry values on strongly under-recorded weekdays. It is intended to
detect false zeros caused by systematic missed manual observations.
precipQC_subdaily applies it after coverage-screened daily aggregation
and expands the resulting flags back to native intervals.
precipQC_climatology works on log1p precipitation. For each
calendar group, it takes the more conservative of an upper empirical quantile
and a robust median-plus-MAD threshold. A largest value above the limit is
temporarily removed and the threshold recomputed until stable. This protects
the reference distribution from gross errors while retaining a low false
positive rate.
precipQC_accumulation first calculates the mean wet-day total of each
station. A candidate must exceed threshold.factor times that mean and
have the requested dry/missing flanks. It identifies candidates only; it
cannot prove that a reported depth is a longer-period accumulation.
precipQC_spatial applies a leave-one-station-out test after
log1p transformation. Coordinates, overlap, and correspondence select
up to ten neighbours. If elevation is selected, its exponential similarity
factor penalizes neighbours separated by large height differences. The
estimate is a distance- and elevation-weighted median when usable metadata
weights exist and an ordinary median otherwise. A located target ranks eligible located
neighbours first and uses correlation-qualified unlocated neighbours only as
fallbacks. A target missing either coordinate uses correlation-based selection
and remains fully testable. The critical ratio uses
the larger of the simultaneous neighbour dispersion, historical target
residual dispersion, and a small numerical floor. Only positive residuals are
flagged here; isolated dryness is handled separately.
precipQC_dryspell aggregates native observations to wet/dry calendar
days, locates long dry runs, and flags target values only where the requested
fraction of neighbours records enough wet days in the same window.
precipQC_breakpoint first aggregates sub-daily input to daily totals.
It applies the rank-based Pettitt statistic separately to sufficiently
complete annual precipitation totals, wet-day counts, maxima, and counts above
the station wet-day 99th percentile. P-values are Holm-adjusted across the
selected indicators. The strongest breakpoint, its adjusted p-value,
pre/post relative change, and number of significant indicators are returned
because a statistically significant change is not necessarily a measurement
error.
precipQC_range, precipQC_persistence,
precipQC_duplicate, precipQC_frequency, precipQC_gap,
precipQC_weekday, precipQC_climatology, precipQC_accumulation, and
precipQC_dryspell return logical zoo objects matching
x.
precipQC_spatial returns a list with logical flags, numeric
scores, neighbour estimate series, and selected
neighbours.
precipQC_breakpoint returns one data.frame row per station with the
breakpoint year, selected indicator, adjusted p-value, relative change,
number of significant indicators, and logical flag.
Mauricio Zambrano-Bigiarini, [email protected]
Hamada, A., Arakawa, O. and Yatagai, A. (2011). An automated quality control method for daily rain-gauge data. Global Environmental Research, 15, 183–192.
Scherrer, S. C. et al. (2011). Operational quality control of daily precipitation using spatio-climatological plausibility testing. Meteorologische Zeitschrift, 20, 397–407.
El Hachem, A. et al. (2022). Space-time statistical quality control of extreme precipitation observations. Hydrology and Earth System Sciences, 26, 6137–6146.
Durre, I., Menne, M. J., Gleason, B. E., Houston, T. G. and Vose, R. S. (2010). Comprehensive automated quality assurance of daily surface observations. Journal of Applied Meteorology and Climatology, 49, 1615–1633.
Lewis, E. et al. (2021). Quality control of a global hourly rainfall dataset. Environmental Modelling and Software, 144, 105169.
Stepanek, P., Zahradnicek, P. and Skalak, P. (2009). Data quality control and homogenization of air temperature and precipitation series in the area of the Czech Republic in the period 1961–2007. Advances in Science and Research, 3, 23–26.
Vicente-Serrano, S. M., Begueria, S., Lopez-Moreno, J. I., Garcia-Vera, M. A. and Stepanek, P. (2010). A complete daily precipitation database for northeast Spain: reconstruction, quality control, and homogeneity. International Journal of Climatology, 30, 1146–1163.
Estevez, J. et al. (2022). A quality control procedure for long-term series of daily precipitation data in a semiarid environment. Theoretical and Applied Climatology, 149, 1029–1041.
Golkhatmi, N. S. N. and Farzandi, M. (2024). Enhancing rainfall data consistency and completeness: a spatiotemporal quality control approach and missing data reconstruction using MICE on large precipitation datasets. Water Resources Management, 38, 815–833.
precipQC_daily, precipQC_subdaily,
plot.precipQC
dates <- seq(as.Date("2020-01-01"), by="day", length.out=60) x <- zoo(cbind(A=rep(0, 60), B=rep(0, 60), C=rep(0, 60)), dates) x[10, "A"] <- -1 x[20:24, "B"] <- 15 precipQC_range(x) precipQC_persistence(x) precipQC_weekday(x) precipQC_breakpoint(x)dates <- seq(as.Date("2020-01-01"), by="day", length.out=60) x <- zoo(cbind(A=rep(0, 60), B=rep(0, 60), C=rep(0, 60)), dates) x[10, "A"] <- -1 x[20:24, "B"] <- 15 precipQC_range(x) precipQC_persistence(x) precipQC_weekday(x) precipQC_breakpoint(x)
Print and plot methods for objects returned by precipQC,
precipQC_daily, and precipQC_subdaily.
## S3 method for class 'precipQC' print(x, ...) ## S3 method for class 'precipQC' plot( x, max.stations=20L, col=c("#2878B5", "#D55E00", "#E69F00"), ... )## S3 method for class 'precipQC' print(x, ...) ## S3 method for class 'precipQC' plot( x, max.stations=20L, col=c("#2878B5", "#D55E00", "#E69F00"), ... )
x |
An object of class |
max.stations |
Maximum number of stations displayed in the missing/suspicious percentage panel. Stations with the largest suspicious and missing fractions are shown. |
col |
At least three colours for accepted stations, discarded/rejected values, and missing/review flags. |
... |
For |
The plot contains four panels: numbers of accepted and discarded stations; missing and confirmed-suspicious percentages for the most affected stations; flag counts by individual test; and the number of confirmed suspicious values through time.
Both methods return x invisibly. The print method writes a compact
summary to the console and the plot method draws on the active graphics
device.
Mauricio Zambrano-Bigiarini, [email protected]
precipQC, precipQC_daily,
precipQC_subdaily,
precipQC_range
Deletes the first n character(s) of a character object.
rm1stchar(x, n = 1)rm1stchar(x, n = 1)
x |
Character, e.g, each element may represent the name of a single gauging station. |
n |
numeric, indicating the number of characters that have to be removed from the beginning of |
character object of the same length as x.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) # Getting the name of each gauging station. names <- colnames(EbroPPtsMonthly) # Removing the initial letter 'P' of the name of each gauging station. rm1stchar(names)## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) # Getting the name of each gauging station. names <- colnames(EbroPPtsMonthly) # Removing the initial letter 'P' of the name of each gauging station. rm1stchar(names)
Daily time series of precipitation, at station San Martino di Castrozza, Trento Province, Italy, with data from 01/Jan/1921 to 31/Dec/1990.
data(SanMartinoPPts)data(SanMartinoPPts)
zoo object.
Provided by MeteoTrentino, Trento, Italy (via prof. Riccardo Rigon).
These data are intended to be used for research purposes only, being distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.
Generic function for applying any R function to a zoo object, in order to obtain 4 representative seasonal values.
seasonalfunction(x, ...) ## Default S3 method: seasonalfunction(x, FUN, na.rm = TRUE, type="default", ...) ## S3 method for class 'zoo' seasonalfunction(x, FUN, na.rm = TRUE, type="default", ...) ## S3 method for class 'data.frame' seasonalfunction(x, FUN, na.rm = TRUE, type="default", dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...) ## S3 method for class 'matrix' seasonalfunction(x, FUN, na.rm = TRUE, type="default", dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...)seasonalfunction(x, ...) ## Default S3 method: seasonalfunction(x, FUN, na.rm = TRUE, type="default", ...) ## S3 method for class 'zoo' seasonalfunction(x, FUN, na.rm = TRUE, type="default", ...) ## S3 method for class 'data.frame' seasonalfunction(x, FUN, na.rm = TRUE, type="default", dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...) ## S3 method for class 'matrix' seasonalfunction(x, FUN, na.rm = TRUE, type="default", dates=1, date.fmt = "%Y-%m-%d", out.type = "data.frame", verbose = TRUE, ...)
x |
zoo, data.frame or matrix object, with daily or monthly time series. |
FUN |
Function that will be applied to ALL the values in |
na.rm |
Logical. Should missing values be removed before the computations? |
type |
character, indicating which weather seasons will be used for computing the output. Possible values are: |
dates |
numeric, factor, Date indicating how to obtain the dates. |
date.fmt |
Character indicating the format in which the dates are stored in |
out.type |
Character defining the desired type of output. Valid values are: |
verbose |
Logical; if TRUE, progress messages are printed |
... |
further arguments passed to or from other methods |
The FUN value for the winter season (DJF) is computed considering the consecutive months of December, January and February. Therefore, if x starts in January and ends in December of any year, the winter value of the first year is computed considering only the January and February value of that year, whereas the December value of the first year is used to compute the winter value of the next year.
FUN is applied to all the values of x belonging to each one of the four weather seasons, so the results of this function depends on the frequency sampling of x and the type of function given by FUN
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
dm2seasonal, time2season, monthlyfunction, annualfunction, extract
## Loading the SanMartino precipitation data data(SanMartinoPPts) x <- SanMartinoPPts # Amount of years nyears <- yip(from=start(x), to=end(x), out.type="nmbr") ## Mean annual precipitation. # It is necessary to divide by the amount of years to obtain the mean annual value, # otherwise it will give the total precipitation for all the 70 years seasonalfunction(x, FUN=sum, na.rm=TRUE) / nyears ##################### ### verification #### # Mean winter (DJF) value sum( extractzoo(x, trgt="DJF") ) / nyears # Mean spring (MAM) value sum( extractzoo(x, trgt="MAM") ) / nyears # Mean summer (JJA) value sum( extractzoo(x, trgt="JJA") ) / nyears # Mean autumn (SON) value sum( extractzoo(x, trgt="SON") ) / nyears## Loading the SanMartino precipitation data data(SanMartinoPPts) x <- SanMartinoPPts # Amount of years nyears <- yip(from=start(x), to=end(x), out.type="nmbr") ## Mean annual precipitation. # It is necessary to divide by the amount of years to obtain the mean annual value, # otherwise it will give the total precipitation for all the 70 years seasonalfunction(x, FUN=sum, na.rm=TRUE) / nyears ##################### ### verification #### # Mean winter (DJF) value sum( extractzoo(x, trgt="DJF") ) / nyears # Mean spring (MAM) value sum( extractzoo(x, trgt="MAM") ) / nyears # Mean summer (JJA) value sum( extractzoo(x, trgt="JJA") ) / nyears # Mean autumn (SON) value sum( extractzoo(x, trgt="SON") ) / nyears
This function identifies the sampling frequency of a zoo object. It is wrapper to the periodicity function of the xts package.
sfreq(x, min.year = 1800)sfreq(x, min.year = 1800)
x |
variable of type zoo, xts or ts, with AT LEAST 2 elements, AND with a (sub)hourly, hourly, daily, weekly, monthly, quarterly, or annual (yearly) sampling frequency. |
min.year |
integer used for a correct identification of the sampling frequency when |
See further details in the periodicity function of the xts package.
Character. Possible values are:
-) minute : indicating that the sampling frequency in x is sub-hourly
-) hourly : indicating that the sampling frequency in x is hourly
-) daily : indicating that the sampling frequency in x is daily
-) weekly : indicating that the sampling frequency in x is weekly
-) monthly : indicating that the sampling frequency in x is monthly
-) quarterly : indicating that the sampling frequency in x is quarterly
-) annual : indicating that the sampling frequency in x is annual
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Ex1: sub-hourly data ## Creating a dummy 15-min zoo object, with 1 as the only value in each time period dt <- seq( from=as.POSIXct("2021-06-30 00:15"), to=as.POSIXct("2021-06-30 23:45"), by="15 min" ) ndt <- length(dt) shr <- zoo( rep(1, ndt), dt) sfreq(shr) ## Ex2: hourly data ## Loading the time series of HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) hr <- KarameaAtGorgeQts sfreq(hr) ## Ex3: Daily data ## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) data(OcaEnOnaQts) d <- OcaEnOnaQts sfreq(d) ## Ex4: Monthly data m <- daily2monthly(d, FUN=mean, na.rm=TRUE) sfreq(m) ## Ex5: Annual data a <- daily2annual(d, FUN=mean, na.rm=TRUE, out.fmt="%Y-%m-%d") sfreq(a)## Ex1: sub-hourly data ## Creating a dummy 15-min zoo object, with 1 as the only value in each time period dt <- seq( from=as.POSIXct("2021-06-30 00:15"), to=as.POSIXct("2021-06-30 23:45"), by="15 min" ) ndt <- length(dt) shr <- zoo( rep(1, ndt), dt) sfreq(shr) ## Ex2: hourly data ## Loading the time series of HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) hr <- KarameaAtGorgeQts sfreq(hr) ## Ex3: Daily data ## Loading daily streamflows at the station Oca en Ona (Ebro River basin, Spain) data(OcaEnOnaQts) d <- OcaEnOnaQts sfreq(d) ## Ex4: Monthly data m <- daily2monthly(d, FUN=mean, na.rm=TRUE) sfreq(m) ## Ex5: Annual data a <- daily2annual(d, FUN=mean, na.rm=TRUE, out.fmt="%Y-%m-%d") sfreq(a)
It shifts years backwards for correct computation of annual values when the hydrological year does not start in january. Originally created only for internal usage in this pacakge.
shiftyears(ltime, lstart.month)shiftyears(ltime, lstart.month)
ltime |
vector with the date/times of each element of a zoo object. |
lstart.month |
numeric in [1,..,12], representing the starting month to be used in the computation of annual values. By default |
Integer vector with the shifted years corresponding to each elemen of x.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
# Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three months (Jan/1921 - Mar/1921) x <- window(x, end="1921-12-31") # Starting in January, it means no shift shiftyears(ltime=time(x), lstart.month=1) # Starting in April: shiftyears(ltime=time(x), lstart.month=4)# Loading the DAILY precipitation data at SanMartino data(SanMartinoPPts) x <- SanMartinoPPts # Subsetting 'x' to its first three months (Jan/1921 - Mar/1921) x <- window(x, end="1921-12-31") # Starting in January, it means no shift shiftyears(ltime=time(x), lstart.month=1) # Starting in April: shiftyears(ltime=time(x), lstart.month=4)
Function to compute the seasonality index defined by Walsh and Lawler (1981) to classify the precipitation regime.
si(x, na.rm=TRUE, from=start(x), to=end(x), date.fmt="%Y-%m-%d", start.month=1)si(x, na.rm=TRUE, from=start(x), to=end(x), date.fmt="%Y-%m-%d", start.month=1)
x |
zoo object with daily or subdaily precipitation data. |
na.rm |
Logical. Should missing values be removed? |
from |
OPTIONAL, used for extracting a subset of values. |
to |
OPTIONAL, used for extracting a subset of values. |
date.fmt |
Character indicating the format in which the dates are stored in dates, from and to. See |
start.month |
[OPTIONAL]. Only used when the (hydrological) year of interest is different from the calendar year. numeric in [1:12] indicating the starting month of the (hydrological) year. Numeric values in [1, 12] represents months in [January, December]. By default |
The seasonality index is computed as following:
si = (1/R) *sum(i=1, i=12, abs(xi - R/12) )
where:
-) xi: mean monthly precipitation for month i
-) R: mean annual precipitation
This index can theoretically vary from 0 (when all months have the same rainfall) to 1.83 (when all the rainfall ocurrs in a single month).
A qualitative classification of degrees of seasonality is the following:
——————————————————–
si values | Rainfall regime
——————————————————–
<= 0.19 | Very equable
0.20 - 0.39 | Equable but with a definite wetter season
0.40 - 0.59 | Rather seasonal with a short drier season
0.60 - 0.79 | Seasonal
0.80 - 0.99 | Markedly seasonal with a long drier season
1.00 - 1.19 | Most rain in 3 months or less
>= 1.20 | Extreme, almost all rain in 1-2 months
numeric with the seasonality index
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
Walsh, R. and Lawler, D. (1981). Rainfall seasonality: Description, spatial patterns and change through time (British Isles, Africa). Weather, 36(7), 201-208. doi:10.1002/j.1477-8696.1981.tb05400.x.
############################ ## Ex 1: Seasonality index for a rain gauge with equable precipitation , ## but with a definite wetter season ## Loading daily precipitation data at the station San Martino di Castrozza, ## Trento Province, Italy, from 01/Jan/1921 to 31/Dec/1990. data(SanMartinoPPts) x <- SanMartinoPPts ## Amount of years in 'x' (needed for computations) ( nyears <- yip(from=start(x), to=end(x), out.type="nmbr" ) ) ## Boxplot of monthly values, to look at the seasonal cycle ## Daily to Monthly m <- daily2monthly(x, FUN=sum, na.rm=TRUE) ## Mean monthly values at the station monthlyfunction(m, FUN=sum, na.rm=TRUE) / nyears ## Vector with the three-letter abbreviations of the month names cmonth <- format(time(m), "%b") ## Creating ordered monthly factors months <- factor(cmonth, levels=unique(cmonth), ordered=TRUE) ## Boxplot of the monthly values of precipitation boxplot( coredata(m) ~ months, col="lightblue", main="Monthly precipitation, [mm]", ylab="P, [mm]") # computing seasonality index ( si(x) ) ############################ ## Ex 2: Seasonality index for a rain gauge with markedly seasonal regime ## with a long dry season ## Loading daily precipitation data at the station Cauquenes en El Arrayan, ## Maule Region, Chile, from 01/Jan/1979 to 31/Dec/2020. data(Cauquenes7336001) x <- Cauquenes7336001[, 1] # P is the first column ## Boxplot of monthly values, to look at the seasonal cycle ## Daily to Monthly m <- daily2monthly(x, FUN=sum, na.rm=TRUE) ## Mean monthly values at the station monthlyfunction(m, FUN=sum, na.rm=TRUE) / nyears ## Vector with the three-letter abbreviations of the month names cmonth <- format(time(m), "%b") ## Creating ordered monthly factors months <- factor(cmonth, levels=unique(cmonth), ordered=TRUE) ## Boxplot of the monthly values of precipitation boxplot( coredata(m) ~ months, col="lightblue", main="Monthly precipitation, [mm]", ylab="P, [mm]") # computing seasonality index ( si(x) )############################ ## Ex 1: Seasonality index for a rain gauge with equable precipitation , ## but with a definite wetter season ## Loading daily precipitation data at the station San Martino di Castrozza, ## Trento Province, Italy, from 01/Jan/1921 to 31/Dec/1990. data(SanMartinoPPts) x <- SanMartinoPPts ## Amount of years in 'x' (needed for computations) ( nyears <- yip(from=start(x), to=end(x), out.type="nmbr" ) ) ## Boxplot of monthly values, to look at the seasonal cycle ## Daily to Monthly m <- daily2monthly(x, FUN=sum, na.rm=TRUE) ## Mean monthly values at the station monthlyfunction(m, FUN=sum, na.rm=TRUE) / nyears ## Vector with the three-letter abbreviations of the month names cmonth <- format(time(m), "%b") ## Creating ordered monthly factors months <- factor(cmonth, levels=unique(cmonth), ordered=TRUE) ## Boxplot of the monthly values of precipitation boxplot( coredata(m) ~ months, col="lightblue", main="Monthly precipitation, [mm]", ylab="P, [mm]") # computing seasonality index ( si(x) ) ############################ ## Ex 2: Seasonality index for a rain gauge with markedly seasonal regime ## with a long dry season ## Loading daily precipitation data at the station Cauquenes en El Arrayan, ## Maule Region, Chile, from 01/Jan/1979 to 31/Dec/2020. data(Cauquenes7336001) x <- Cauquenes7336001[, 1] # P is the first column ## Boxplot of monthly values, to look at the seasonal cycle ## Daily to Monthly m <- daily2monthly(x, FUN=sum, na.rm=TRUE) ## Mean monthly values at the station monthlyfunction(m, FUN=sum, na.rm=TRUE) / nyears ## Vector with the three-letter abbreviations of the month names cmonth <- format(time(m), "%b") ## Creating ordered monthly factors months <- factor(cmonth, levels=unique(cmonth), ordered=TRUE) ## Boxplot of the monthly values of precipitation boxplot( coredata(m) ~ months, col="lightblue", main="Monthly precipitation, [mm]", ylab="P, [mm]") # computing seasonality index ( si(x) )
Extended summary function for numeric objects, with 13 summary statistics.
smry(x, ...) ## Default S3 method: smry(x, na.rm=TRUE, digits = max(3, getOption("digits")-3), ...) ## S3 method for class 'zoo' smry(x, na.rm=TRUE, digits = max(3, getOption("digits")-3), ...) ## S3 method for class 'Date' smry(x, na.rm=TRUE, digits = max(3, getOption("digits")-3), ...) ## S3 method for class 'matrix' smry(x, na.rm=TRUE, digits = max(3, getOption("digits")-3), ...) ## S3 method for class 'data.frame' smry(x, na.rm=TRUE, digits = max(3, getOption("digits")-3), ...)smry(x, ...) ## Default S3 method: smry(x, na.rm=TRUE, digits = max(3, getOption("digits")-3), ...) ## S3 method for class 'zoo' smry(x, na.rm=TRUE, digits = max(3, getOption("digits")-3), ...) ## S3 method for class 'Date' smry(x, na.rm=TRUE, digits = max(3, getOption("digits")-3), ...) ## S3 method for class 'matrix' smry(x, na.rm=TRUE, digits = max(3, getOption("digits")-3), ...) ## S3 method for class 'data.frame' smry(x, na.rm=TRUE, digits = max(3, getOption("digits")-3), ...)
x |
a numeric object, vector, matrix or data.frame, for which a summary is desired. |
na.rm |
a logical value indicating whether 'NA' values should be stripped before the computation proceeds. |
digits |
numeric, with the amount of decimal places to be included in the result |
... |
further arguments passed to or from other methods. |
Computed summary statistics are:
Min |
Minimum |
1stQ |
First quartile (lower-hinge) |
Mean |
Mean value |
Median |
Median |
3rdQ |
Third quartile ( upper-hinge |
Max |
Maximum of the input values. |
IQR |
Interquartile Range. |
sd |
Standard deviation. It uses 'n-1' as denominator. |
cv |
Coefficient of variation ( |
skewness |
Skewness (using e1071 package) |
kurtosis |
Kurtosis (using e1071 package) |
n |
Total number of elements |
NA's |
Amount of missing values |
Skewness and Kurtosis are computed with the e1071 package
Mauricio Zambrano-Bigiarini mzb.devel@gmail
summary, fivenum, IQR, sd, skewness, kurtosis
## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) ## Summary of monthly precipitation values for the first 7 stations in 'EbroPPtsMonthly' smry(EbroPPtsMonthly[,2:8])## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) ## Summary of monthly precipitation values for the first 7 stations in 'EbroPPtsMonthly' smry(EbroPPtsMonthly[,2:8])
This function takes a data.frame whose columns contains the time series of several gauging stations, along with a character representing the name of one gauging station, and extracts the time series corresponding to that station.
sname2ts(x, sname, dates=1, date.fmt = "%Y-%m-%d", var.type, tstep.out = "daily", FUN, na.rm = TRUE, from, to)sname2ts(x, sname, dates=1, date.fmt = "%Y-%m-%d", var.type, tstep.out = "daily", FUN, na.rm = TRUE, from, to)
x |
data.frame containing the complete times series of all the stations. |
sname |
Character representing the name of a station, which have to correspond to one column name in |
dates |
numeric, factor, Date object indicating how to obtain the dates corresponding to the |
date.fmt |
character indicating the format in which the dates are stored in dates, e.g. %Y-%m-%d. See |
var.type |
character representing the type of variable being plotted. Used for determining the function used for computing the monthly or/and annual values when |
tstep.out |
character that defines the time step of the desired output time series. Valid values are: |
FUN |
ONLY required when |
na.rm |
a logical value indicating whether 'NA' values should be stripped before the computation proceeds. |
from |
OPTIONAL, used for extracting a subset of values. |
to |
OPTIONAL, used for extracting a subset of values. |
zoo object
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) ## Annual values of temperature at the station "T9105", stored in 'EbroPPtsMonthly'. sname2ts(EbroPPtsMonthly, sname="P9001", dates=1, FUN=sum, tstep.out="annual")## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) ## Annual values of temperature at the station "T9105", stored in 'EbroPPtsMonthly'. sname2ts(EbroPPtsMonthly, sname="P9001", dates=1, FUN=sum, tstep.out="annual")
Computes the Standardized Precipitation Index (SPI) or the Standardized
Precipitation-Evapotranspiration Index (SPEI) for one or more complete monthly
zoo series using base-R distribution and optimisation functions.
spi(x, scale, distribution=c("gamma", "gumbel", "logis", "llogis", "lnorm", "norm", "weibull"), fit=c("max-lik", "ub-pwm", "pp-pwm"), zero.threshold=0, kernel=list(type="rectangular", shift=0), ref.start=NULL, ref.end=NULL, params=NULL, start.fun=NULL, start.fun.fix=FALSE, p0=TRUE, p0.center.mass=FALSE, scaling=c("sd", "no", "max"), sci.limit=Inf, na.rm=FALSE, out.type=c("zoo", "numeric"), verbose=FALSE, warn=TRUE, ...) spei(x, scale, distribution=c("genlog", "gev", "norm", "pe3"), fit=c("max-lik", "ub-pwm", "pp-pwm"), kernel=list(type="rectangular", shift=0), ref.start=NULL, ref.end=NULL, params=NULL, start.fun=NULL, start.fun.fix=FALSE, p0=FALSE, p0.center.mass=FALSE, scaling=c("sd", "no", "max"), sci.limit=Inf, na.rm=FALSE, out.type=c("zoo", "numeric"), verbose=FALSE, warn=TRUE, ...)spi(x, scale, distribution=c("gamma", "gumbel", "logis", "llogis", "lnorm", "norm", "weibull"), fit=c("max-lik", "ub-pwm", "pp-pwm"), zero.threshold=0, kernel=list(type="rectangular", shift=0), ref.start=NULL, ref.end=NULL, params=NULL, start.fun=NULL, start.fun.fix=FALSE, p0=TRUE, p0.center.mass=FALSE, scaling=c("sd", "no", "max"), sci.limit=Inf, na.rm=FALSE, out.type=c("zoo", "numeric"), verbose=FALSE, warn=TRUE, ...) spei(x, scale, distribution=c("genlog", "gev", "norm", "pe3"), fit=c("max-lik", "ub-pwm", "pp-pwm"), kernel=list(type="rectangular", shift=0), ref.start=NULL, ref.end=NULL, params=NULL, start.fun=NULL, start.fun.fix=FALSE, p0=FALSE, p0.center.mass=FALSE, scaling=c("sd", "no", "max"), sci.limit=Inf, na.rm=FALSE, out.type=c("zoo", "numeric"), verbose=FALSE, warn=TRUE, ...)
x |
numeric |
scale |
positive integer indicating the number of months in the backward-looking accumulation period. This argument has no default and must be provided. |
distribution |
character string naming the distribution to fit. For |
fit |
character string specifying the parameter-estimation method:
|
zero.threshold |
non-negative numeric value. For |
kernel |
list with elements |
ref.start, ref.end
|
optional |
params |
optional numeric distribution parameters that override parameter fitting.
A vector supplies one parameter set for every month and series; a matrix
with dimensions |
start.fun |
optional function used to calculate initial parameters for maximum-likelihood
estimation, following the interface used by SCI. It is called as
|
start.fun.fix |
logical. If |
p0 |
logical. If |
p0.center.mass |
logical. If |
scaling |
character string indicating whether the accumulated precipitation is divided
by its standard deviation ( |
sci.limit |
non-negative numeric value used to truncate the absolute SPI or SPEI values.
The default |
na.rm |
logical. If |
out.type |
character string indicating whether the result is returned as a
|
verbose |
logical indicating whether informative, bracketed progress messages are
emitted with |
warn |
logical indicating whether warnings should be issued when parameter estimation or transformation fails for a calendar month. |
... |
additional maximum-likelihood fitting controls, notably
|
The functions form a backward-looking accumulation at the selected scale,
fit a separate distribution for each calendar month over the reference period,
evaluate the fitted cumulative probabilities, and transform them to
standard-normal variates. The SPI functions default to a Gamma distribution and
a mixed probability at zero. The SPEI functions default to the generalized
logistic distribution and retain negative climatic-water-balance values.
The seven SPI distributions and four SPEI distributions listed under
distribution follow Section 2.4 and Appendices B and C of Stagge et al.
(2015). Their density, cumulative-probability, L-moment conversion, and
maximum-likelihood calculations use only base R.
For fit="ub-pwm", the first three probability-weighted moments use the
unbiased order-statistic estimators. For fit="pp-pwm", non-exceedance
probabilities are , corresponding to the plotting-position
constants and used by SPEI. At least four
non-missing, non-constant calibration values are required for either PWM
method.
Accumulation is performed before the reference period is selected. Therefore,
an accumulated value at the start of the reference period can use preceding
observations from x. Kernel values are normalised and multiplied by
scale, following the magnitude-preserving convention used by the
SPEI package.
For SPI, zero.threshold is applied to individual monthly precipitation
values before accumulation. At scales larger than one, the zero probability is
therefore estimated from accumulated periods whose threshold-adjusted total is
zero.
Maximum-likelihood estimation uses optim and unbiased-PWM
starting values. Generalized-logistic, log-logistic, Pearson type III, GEV, and
Gumbel distribution functions are implemented internally. Neither SCI,
SPEI, lmomco, nor evd is required.
When params is supplied, parameter fitting is skipped and the supplied
parameters are applied to the unscaled accumulated series; consequently,
fit, scaling, start.fun, and start.fun.fix do not
affect the result. When p0=TRUE, the zero probability is still estimated
separately for each calendar month from the reference data. The parameter
orders are:
gamma=(shape, rate), gumbel=(loc, scale),
logis=(location, scale), llogis=(shape, scale),
lnorm=(meanlog, sdlog), norm=(mean, sd),
weibull=(shape, scale),
genlog=(shape, scale, location),
gev=(loc, scale, shape), and
pe3=(shape, scale, location).
start.fun is used only with fit="max-lik". Its result can be
named, in which case the names must match those listed above, or unnamed in the
documented order. Retaining initial values with start.fun.fix=TRUE can
produce a complete index when optimisation fails, but the retained values are
starting estimates rather than a converged maximum-likelihood fit.
A zoo object by default, or a numeric vector or matrix when
out.type="numeric". The result has the same time index, length, and
column names as x. The first scale - 1 values are NA when
scale > 1.
Mauricio Zambrano-Bigiarini, [email protected]
McKee, T. B., Doesken, N. J., and Kleist, J. (1993). The relationship of drought frequency and duration to time scales. Proceedings of the 8th Conference on Applied Climatology, 17–22 January, Anaheim, California, 179–184.
Stagge, J. H., Tallaksen, L. M., Gudmundsson, L., Van Loon, A. F., and Stahl, K. (2015). Candidate distributions for climatological drought indices (SPI and SPEI). International Journal of Climatology, 35, 4027–4040. doi:10.1002/joc.4267.
data(EbroPPtsMonthly) pcp <- zoo(EbroPPtsMonthly$P9001, EbroPPtsMonthly$Date) spi3 <- spi(pcp, scale=3, zero.threshold=0.1, warn=FALSE) head(spi3) spi3.pwm <- spi(pcp, scale=3, fit="ub-pwm", warn=FALSE) head(spi3.pwm) ## Artificial monthly climatic water balance for illustrating 'spei' pet <- zoo(60 + 40*sin(2*pi*(seq_along(pcp)-1)/12), time(pcp)) spei3 <- spei(pcp - pet, scale=3, warn=FALSE) head(spei3) ## A supplied vector is reused for all calendar months spei.fixed <- spei(pcp - pet, scale=1, distribution="norm", params=c(mean=0, sd=50), warn=FALSE) head(spei.fixed)data(EbroPPtsMonthly) pcp <- zoo(EbroPPtsMonthly$P9001, EbroPPtsMonthly$Date) spi3 <- spi(pcp, scale=3, zero.threshold=0.1, warn=FALSE) head(spi3) spi3.pwm <- spi(pcp, scale=3, fit="ub-pwm", warn=FALSE) head(spi3.pwm) ## Artificial monthly climatic water balance for illustrating 'spei' pet <- zoo(60 + 40*sin(2*pi*(seq_along(pcp)-1)/12), time(pcp)) spei3 <- spei(pcp - pet, scale=3, warn=FALSE) head(spei3) ## A supplied vector is reused for all calendar months spei.fixed <- spei(pcp - pet, scale=1, distribution="norm", params=c(mean=0, sd=50), warn=FALSE) head(spei.fixed)
Standarizes a vector or matrix, i.e., scales all the values in a way that the transformed values will be within the range [0, 1].
stdx(x, ...)stdx(x, ...)
x |
vector, matrix or data.frame to be scaled |
... |
further arguments passed to or from other methods |
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
############ ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) # Standarizing only some values of 'EbroPPtsMonthly' stdx(as.matrix(EbroPPtsMonthly[1:70,10:13]))############ ## Loading the monthly time series of precipitation within the Ebro River basin. data(EbroPPtsMonthly) # Standarizing only some values of 'EbroPPtsMonthly' stdx(as.matrix(EbroPPtsMonthly[1:70,10:13]))
Detects the sampling frequency of a numeric zoo object and dispatches
daily data to streamflowQC_daily or minute/hourly data to
streamflowQC_subdaily. No files are written.
streamflowQC( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), ..., area=NULL, elevation=NULL, elevation.scale=500 )streamflowQC( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), ..., area=NULL, elevation=NULL, elevation.scale=500 )
x |
A numeric |
metadata |
|
station.id |
Name of the station-identifier field in
|
coords |
Names of longitude and latitude fields in |
... |
Arguments passed unchanged to the selected workflow. |
area |
|
elevation |
|
elevation.scale |
Positive elevation-decay scale used in spatial neighbour ranking. |
The wrapper changes only the resolution-specific workflow. Test activation,
thresholds, station metadata, evidence requirements, correction policy, and
station recommendations remain explicit user controls. Daily and sub-daily
observations must be in consistent discharge units. Duplicate timestamps are
rejected because selecting among contradictory measurements would require
provenance or agency-quality information not contained in a numeric
zoo object.
The design combines the point plausibility and homogeneity principles of Gudmundsson et al. (2018), the real-time hierarchy of U.S. IOOS (2018), and the sub-daily artefact and event-corroboration framework of Fileni et al. (2026).
An object of class "streamflowQC"; see
streamflowQC-class.
Fileni, F. et al. (2026). UK-Flow15-QC: A quality control framework for better river flow data in hydrological research. EGUsphere preprint. doi:10.5194/egusphere-2026-277.
Gudmundsson, L., Do, H. X., Leonard, M. and Westra, S. (2018). The Global Streamflow Indices and Metadata Archive (GSIM) - Part 2: quality control, time-series indices and homogeneity assessment. Earth System Science Data, 10, 787–804. doi:10.5194/essd-10-787-2018.
U.S. Integrated Ocean Observing System (2018). Manual for Real-Time Quality Control of Stream Flow Data Version 1.0. doi:10.25923/gszc-ha43.
streamflowQC_daily, streamflowQC_subdaily,
streamflowQC_tests, precipQC,
tempQC
dates <- as.Date("2020-01-01") + 0:29 x <- zoo::zoo(cbind(A=10 + sin(seq_along(dates)), B=12 + sin(seq_along(dates))), dates) qc <- streamflowQC( x, checks=c(range=TRUE, duplicate=FALSE, gap=FALSE, climatology=FALSE, flatline=FALSE, spike=FALSE, rate=FALSE, highflow=FALSE, spatial=FALSE, breakpoint=FALSE), min.years=0, max.missing=1, max.review=1, max.suspicious=1 ) qc$station.summarydates <- as.Date("2020-01-01") + 0:29 x <- zoo::zoo(cbind(A=10 + sin(seq_along(dates)), B=12 + sin(seq_along(dates))), dates) qc <- streamflowQC( x, checks=c(range=TRUE, duplicate=FALSE, gap=FALSE, climatology=FALSE, flatline=FALSE, spike=FALSE, rate=FALSE, highflow=FALSE, spatial=FALSE, breakpoint=FALSE), min.years=0, max.missing=1, max.review=1, max.suspicious=1 ) qc$station.summary
Applies individually selectable physical, temporal, high-flow, spatial, and homogeneity tests to one or more daily streamflow series. It returns point flags and station acceptance recommendations without writing files.
streamflowQC_daily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, duplicate=TRUE, gap=TRUE, climatology=TRUE, flatline=TRUE, spike=TRUE, rate=TRUE, highflow=TRUE, spatial=TRUE, breakpoint=TRUE), lower=0, upper=Inf, duplicate.min.month=20L, duplicate.min.year=300L, duplicate.min.nonzero=1L, climatology.window=5L, climatology.z=6, climatology.min.samples=30L, log.offset=0.01, flatline.run=11L, flatline.tolerance=0, flag.zero=FALSE, spike.factor=5, spike.prob=0.99, rate.z=6, rate.min.samples=30L, rate.max.rise=Inf, rate.max.fall=Inf, rate.drop.factor=5, highflow.log.z=6, highflow.amax.ratio=2, highflow.return.period=1000, highflow.min.years=10L, spatial.window.days=3L, spatial.high.prob=0.99, spatial.support.prob=0.95, spatial.f=3, n.neighbours=5L, max.distance=400, min.neighbours=2L, min.support=1L, min.overlap=90L, min.correlation=0.5, breakpoint.min.years=10L, breakpoint.alpha=0.01, breakpoint.min.relative.change=0.5, breakpoint.min.completeness=0.8, correction=c("none", "set_na", "spatial"), min.evidence=3L, max.missing=0.2, max.review=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, area=NULL, elevation=NULL, elevation.scale=500 )streamflowQC_daily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, duplicate=TRUE, gap=TRUE, climatology=TRUE, flatline=TRUE, spike=TRUE, rate=TRUE, highflow=TRUE, spatial=TRUE, breakpoint=TRUE), lower=0, upper=Inf, duplicate.min.month=20L, duplicate.min.year=300L, duplicate.min.nonzero=1L, climatology.window=5L, climatology.z=6, climatology.min.samples=30L, log.offset=0.01, flatline.run=11L, flatline.tolerance=0, flag.zero=FALSE, spike.factor=5, spike.prob=0.99, rate.z=6, rate.min.samples=30L, rate.max.rise=Inf, rate.max.fall=Inf, rate.drop.factor=5, highflow.log.z=6, highflow.amax.ratio=2, highflow.return.period=1000, highflow.min.years=10L, spatial.window.days=3L, spatial.high.prob=0.99, spatial.support.prob=0.95, spatial.f=3, n.neighbours=5L, max.distance=400, min.neighbours=2L, min.support=1L, min.overlap=90L, min.correlation=0.5, breakpoint.min.years=10L, breakpoint.alpha=0.01, breakpoint.min.relative.change=0.5, breakpoint.min.completeness=0.8, correction=c("none", "set_na", "spatial"), min.evidence=3L, max.missing=0.2, max.review=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, area=NULL, elevation=NULL, elevation.scale=500 )
x |
A numeric daily |
metadata |
|
station.id |
Name of the unique station-identifier field in
|
coords |
Names of numeric longitude and latitude fields, in that order. Missing coordinates are allowed; non-missing coordinates are range-checked. |
checks |
Named logical vector. Omitted names retain their defaults; all daily tests are enabled by default. |
lower, upper
|
Physical limits, scalar or station-specific. The default rejects negative flow but deliberately imposes no universal upper limit. |
duplicate.min.month, duplicate.min.year
|
Minimum paired calendar positions for exact copied-month and copied-year checks. |
duplicate.min.nonzero |
Minimum positive values required in each candidate copied block. |
climatology.window |
Width in calendar days of the circular seasonal reference window. |
climatology.z |
Standard-deviation multiplier for the log-flow climatology test. |
climatology.min.samples |
Minimum seasonal reference observations. |
log.offset |
Positive constant added before taking logarithms. |
flatline.run |
Minimum number of consecutive equal or near-equal daily values. The default flags runs of more than 10 days. |
flatline.tolerance |
Maximum consecutive numerical difference within a flat line. |
flag.zero |
Whether repeated zero-flow runs may be flagged. The default protects legitimate no-flow periods. |
spike.factor |
Multiplicative isolated peak/dip threshold. |
spike.prob |
Station quantile used as the absolute isolated-spike threshold. |
rate.z |
Robust standardized first-difference threshold. |
rate.min.samples |
Minimum monthly first-difference reference sample. |
rate.max.rise, rate.max.fall
|
Optional absolute consecutive rise and fall limits, scalar or station-specific. |
rate.drop.factor |
Multiplicative abrupt-fall threshold. |
highflow.log.z |
Standard-deviation multiplier for unusually high global log-flow. |
highflow.amax.ratio |
Ratio of the largest annual maximum to the second largest that generates a high-flow flag. |
highflow.return.period |
GEV return-period threshold in years. |
highflow.min.years |
Minimum annual maxima required for GEV fitting. |
spatial.window.days |
Number of days before and after a high-flow event searched for neighbouring support. |
spatial.high.prob, spatial.support.prob
|
Target and neighbour high-flow quantiles. |
spatial.f |
Minimum standardized spatial-regression residual. |
n.neighbours |
Maximum selected neighbours per station. |
max.distance |
Maximum target-neighbour distance in km. |
min.neighbours |
Minimum simultaneous spatial predictions. |
min.support |
Minimum neighbouring high-flow events needed to corroborate a target event. |
min.overlap |
Minimum paired observations for neighbour selection and pairwise regression. |
min.correlation |
Minimum Spearman correlation on log-flow for a preferred neighbour. |
breakpoint.min.years |
Minimum complete annual indicators for a Pettitt test. |
breakpoint.alpha |
Holm-adjusted breakpoint significance level. |
breakpoint.min.relative.change |
Minimum relative pre/post median change. |
breakpoint.min.completeness |
Minimum daily completeness for an annual indicator. |
correction |
|
min.evidence |
Number of independent flag families needed to confirm a point that did not fail a hard test. |
max.missing, max.review, max.suspicious
|
Maximum station fractions of missing expected values, any flagged observations, and confirmed suspicious observations. |
min.years |
Minimum record duration for station acceptance. |
discard.breakpoint |
Whether a significant large breakpoint discards a station. It is diagnostic by default because real catchment change or regulation can cause inhomogeneity. |
area |
|
elevation |
|
elevation.scale |
Positive elevation-decay scale used in neighbour ranking. |
The daily climatology test reproduces the GSIM structure: it compares
log(Q + log.offset) with a five-day calendar window using a six-standard
deviation default. Negative/non-finite non-missing values and exact copied
calendar blocks are hard failures. Other tests remain evidence for review;
the default requires three independent families before point rejection because
floods, regulation, and intermittent flow can legitimately trigger individual
statistical rules.
High-flow diagnostics combine the six-standard-deviation, largest-AMAX ratio, and GEV return-period tests into one evidence family so correlated extreme statistics are not counted as independent proof. Spatial QC fits pairwise log-flow regressions, optionally on flow divided by catchment area, and flags a rare event only when its regression residual is large and too few selected neighbours show high flow within the search window.
Station acceptance requires all user-defined completeness, review, confirmed suspicion, duration, and optional breakpoint criteria. Point and station decisions are therefore related but distinct.
An object of class "streamflowQC"; see
streamflowQC-class.
Crochemore, L. et al. (2020). Lessons learnt from checking the quality of openly accessible river flow data worldwide. Hydrological Sciences Journal, 65, 699–711. doi:10.1080/02626667.2019.1659509.
Gudmundsson, L. et al. (2018). The Global Streamflow Indices and Metadata Archive (GSIM) - Part 2: quality control, time-series indices and homogeneity assessment. Earth System Science Data, 10, 787–804. doi:10.5194/essd-10-787-2018.
U.S. Integrated Ocean Observing System (2018). Manual for Real-Time Quality Control of Stream Flow Data Version 1.0. doi:10.25923/gszc-ha43.
streamflowQC_subdaily, streamflowQC,
streamflowQC_tests
dates <- as.Date("2020-01-01") + 0:59 x <- zoo::zoo(cbind(A=10 + sin(seq_along(dates) / 5), B=12 + sin(seq_along(dates) / 5)), dates) x[20, "A"] <- -1 qc <- streamflowQC_daily( x, checks=c(duplicate=FALSE, climatology=FALSE, flatline=FALSE, spike=FALSE, rate=FALSE, highflow=FALSE, spatial=FALSE, breakpoint=FALSE), min.years=0, max.missing=1, max.review=1, max.suspicious=1 ) qc$suspiciousdates <- as.Date("2020-01-01") + 0:59 x <- zoo::zoo(cbind(A=10 + sin(seq_along(dates) / 5), B=12 + sin(seq_along(dates) / 5)), dates) x[20, "A"] <- -1 qc <- streamflowQC_daily( x, checks=c(duplicate=FALSE, climatology=FALSE, flatline=FALSE, spike=FALSE, rate=FALSE, highflow=FALSE, spatial=FALSE, breakpoint=FALSE), min.years=0, max.missing=1, max.review=1, max.suspicious=1 ) qc$suspicious
Applies individually selectable physical, temporal, high-flow, spatial, and homogeneity tests to one or more regular minute/hourly streamflow series. It returns point flags and station acceptance recommendations without writing files.
streamflowQC_subdaily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, gap=TRUE, climatology=TRUE, flatline=TRUE, spike=TRUE, rate=TRUE, fluctuation=TRUE, highflow=TRUE, spatial=TRUE, breakpoint=TRUE), lower=0, upper=Inf, climatology.z=6, climatology.min.samples=100L, log.offset=0.01, flatline.hours=168, high.flatline.hours=24, flatline.high.prob=0.99, flatline.tolerance=0, flag.zero=FALSE, spike.factor=5, spike.prob=0.99, rate.z=6, rate.min.samples=100L, rate.max.rise=Inf, rate.max.fall=Inf, rate.drop.factor=5, fluctuation.window=16L, fluctuation.minimum=8L, fluctuation.low.diff.prob=0.05, highflow.log.z=6, highflow.amax.ratio=2, highflow.return.period=1000, highflow.min.years=10L, spatial.window.hours=72, spatial.high.prob=0.99, spatial.support.prob=0.95, spatial.f=3, n.neighbours=5L, max.distance=200, min.neighbours=2L, min.support=1L, min.overlap=100L, min.correlation=0.5, breakpoint.min.years=10L, breakpoint.alpha=0.01, breakpoint.min.relative.change=0.5, breakpoint.min.completeness=0.8, correction=c("none", "set_na", "spatial"), min.evidence=3L, max.missing=0.2, max.review=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, area=NULL, elevation=NULL, elevation.scale=500 )streamflowQC_subdaily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, gap=TRUE, climatology=TRUE, flatline=TRUE, spike=TRUE, rate=TRUE, fluctuation=TRUE, highflow=TRUE, spatial=TRUE, breakpoint=TRUE), lower=0, upper=Inf, climatology.z=6, climatology.min.samples=100L, log.offset=0.01, flatline.hours=168, high.flatline.hours=24, flatline.high.prob=0.99, flatline.tolerance=0, flag.zero=FALSE, spike.factor=5, spike.prob=0.99, rate.z=6, rate.min.samples=100L, rate.max.rise=Inf, rate.max.fall=Inf, rate.drop.factor=5, fluctuation.window=16L, fluctuation.minimum=8L, fluctuation.low.diff.prob=0.05, highflow.log.z=6, highflow.amax.ratio=2, highflow.return.period=1000, highflow.min.years=10L, spatial.window.hours=72, spatial.high.prob=0.99, spatial.support.prob=0.95, spatial.f=3, n.neighbours=5L, max.distance=200, min.neighbours=2L, min.support=1L, min.overlap=100L, min.correlation=0.5, breakpoint.min.years=10L, breakpoint.alpha=0.01, breakpoint.min.relative.change=0.5, breakpoint.min.completeness=0.8, correction=c("none", "set_na", "spatial"), min.evidence=3L, max.missing=0.2, max.review=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, area=NULL, elevation=NULL, elevation.scale=500 )
x |
A numeric regular sub-daily |
metadata |
|
station.id |
Name of the unique metadata station-identifier field. |
coords |
Names of longitude and latitude fields, in that order. Individual coordinates may be missing. |
checks |
Named logical vector. Omitted names retain their defaults; all sub-daily tests are enabled by default. |
lower, upper
|
Physical limits, scalar or station-specific. The default rejects negative flow without imposing a region-specific maximum. |
climatology.z |
Standard-deviation multiplier for monthly log-flow. |
climatology.min.samples |
Minimum monthly reference observations. |
log.offset |
Positive constant added before taking logarithms. |
flatline.hours |
Duration in hours of a low/ordinary-flow flat line. |
high.flatline.hours |
Shorter flat-line duration applied above the station high-flow quantile. |
flatline.high.prob |
High-flow quantile for the shorter flat-line rule. |
flatline.tolerance |
Maximum consecutive numerical difference within a flat line. |
flag.zero |
Whether repeated zero-flow runs may be flagged. |
spike.factor |
Multiplicative isolated peak/dip threshold. |
spike.prob |
Station quantile used as the absolute isolated-spike threshold. |
rate.z |
Robust standardized first-difference threshold. |
rate.min.samples |
Minimum monthly first-difference reference sample. |
rate.max.rise, rate.max.fall
|
Optional absolute consecutive rise and fall limits, scalar or station-specific. |
rate.drop.factor |
Multiplicative abrupt-fall threshold. |
fluctuation.window |
Number of observations in the moving sign-reversal window. |
fluctuation.minimum |
Number of derivative sign reversals that the window must exceed. |
fluctuation.low.diff.prob |
Quantile of absolute changes treated as measurement noise before counting reversals. |
highflow.log.z |
Standard-deviation multiplier for unusually high global log-flow. |
highflow.amax.ratio |
Ratio of the largest annual maximum to the second largest that generates a flag. |
highflow.return.period |
GEV return-period threshold in years. |
highflow.min.years |
Minimum annual maxima required for GEV fitting. |
spatial.window.hours |
Hours before and after a rare event searched for neighbouring support. |
spatial.high.prob, spatial.support.prob
|
Target and neighbour high-flow quantiles. |
spatial.f |
Minimum standardized spatial-regression residual. |
n.neighbours |
Maximum selected neighbours per station. |
max.distance |
Maximum target-neighbour distance in km. |
min.neighbours |
Minimum simultaneous spatial predictions. |
min.support |
Minimum neighbouring high-flow events needed for corroboration. |
min.overlap |
Minimum paired observations for neighbour selection and regression. |
min.correlation |
Minimum preferred Spearman log-flow correlation. |
breakpoint.min.years |
Minimum complete annual indicators for a Pettitt test. |
breakpoint.alpha |
Holm-adjusted breakpoint significance level. |
breakpoint.min.relative.change |
Minimum relative pre/post median change. |
breakpoint.min.completeness |
Minimum daily completeness for an annual indicator. |
correction |
|
min.evidence |
Independent flag families needed to confirm a non-hard-failure point. |
max.missing, max.review, max.suspicious
|
Maximum station fractions of missing expected values, any flagged observations, and confirmed suspicious observations. |
min.years |
Minimum record duration for station acceptance. |
discard.breakpoint |
Whether a significant large breakpoint discards a station. |
area |
|
elevation |
|
elevation.scale |
Positive elevation-decay scale used in neighbour ranking. |
The defaults generalize the 15-minute UK-Flow15-QC rules to the actual modal interval. Thus, ordinary flat lines use 168 hours and high-flow flat lines use 24 hours rather than fixed counts of 672 and 96. Relative spikes and abrupt falls use a factor of five; absolute spikes use the station 0.99 quantile; and rapid fluctuations use more than eight sign reversals over 16 observations.
High-flow diagnostics include unusually large log-flow, an annual-maximum ratio, and a base-R maximum-likelihood GEV fit after at least 10 years. These correlated diagnostics contribute one evidence family. A spatial flag requires a rare target event, a large leave-one-station-out regression residual, and insufficient high-flow support among selected neighbours within the default 72-hour window. Catchment area, coordinates, and elevation are optional; correlation-based spatial comparison remains available without metadata.
Only physical range failure is hard evidence by default. The three-family default reduces the risk of rejecting genuine flash floods, reservoir operations, tidal behaviour, intermittent zeros, or high-baseflow plateaus. The review fraction can still recommend discarding a station with pervasive single-test artefacts.
An object of class "streamflowQC"; see
streamflowQC-class.
Fileni, F., Fowler, H. J., Lewis, E., McLay, F. and Yang, L. (2023). A quality-control framework for sub-daily flow and level data for hydrological modelling in Great Britain. Hydrology Research, 54, 1357–1367. doi:10.2166/nh.2023.045.
Fileni, F. et al. (2026). UK-Flow15-QC: A quality control framework for better river flow data in hydrological research. EGUsphere preprint. doi:10.5194/egusphere-2026-277.
U.S. Integrated Ocean Observing System (2018). Manual for Real-Time Quality Control of Stream Flow Data Version 1.0. doi:10.25923/gszc-ha43.
Zhao, Q. et al. (2018). Research on the Data-Driven Quality Control Method of Hydrological Time Series Data. Water, 10, 1712. doi:10.3390/w10121712.
streamflowQC_daily, streamflowQC,
streamflowQC_tests
times <- seq(as.POSIXct("2020-01-01", tz="UTC"), by="hour", length.out=72) x <- zoo::zoo(cbind(A=10 + sin(seq_along(times) / 5), B=12 + sin(seq_along(times) / 5)), times) x[20, "A"] <- -1 qc <- streamflowQC_subdaily( x, checks=c(climatology=FALSE, flatline=FALSE, spike=FALSE, rate=FALSE, fluctuation=FALSE, highflow=FALSE, spatial=FALSE, breakpoint=FALSE), min.years=0, max.missing=1, max.review=1, max.suspicious=1 ) qc$suspicioustimes <- seq(as.POSIXct("2020-01-01", tz="UTC"), by="hour", length.out=72) x <- zoo::zoo(cbind(A=10 + sin(seq_along(times) / 5), B=12 + sin(seq_along(times) / 5)), times) x[20, "A"] <- -1 qc <- streamflowQC_subdaily( x, checks=c(climatology=FALSE, flatline=FALSE, spike=FALSE, rate=FALSE, fluctuation=FALSE, highflow=FALSE, spatial=FALSE, breakpoint=FALSE), min.years=0, max.missing=1, max.review=1, max.suspicious=1 ) qc$suspicious
Individual tests called by streamflowQC_daily and
streamflowQC_subdaily. They are exported so each source of
evidence can be run, inspected, deactivated, and tuned independently.
streamflowQC_range(x, lower=0, upper=Inf) streamflowQC_duplicate( x, min.month.values=20L, min.year.values=300L, min.nonzero=1L ) streamflowQC_gap(x, interval=NULL) streamflowQC_climatology( x, group=c("dayofyear", "month", "month_slot"), window=5L, z=6, min.samples=30L, offset=0.01 ) streamflowQC_flatline( x, run=11L, high.run=Inf, high.prob=0.99, tolerance=0, flag.zero=FALSE ) streamflowQC_spike(x, factor=5, prob=0.99) streamflowQC_rate( x, group=c("month", "month_slot"), z=6, min.samples=30L, max.rise=Inf, max.fall=Inf, drop.factor=5, offset=0.01 ) streamflowQC_fluctuation( x, window=16L, minimum=8L, low.diff.prob=0.05 ) streamflowQC_highflow( x, log.z=6, amax.ratio=2, return.period=1000, min.years=10L, offset=0.01 ) streamflowQC_spatial( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), area=NULL, elevation=NULL, elevation.scale=500, n.neighbours=5L, max.distance=400, min.neighbours=2L, min.support=1L, min.overlap=90L, min.correlation=0.5, window=3L, high.prob=0.99, support.prob=0.95, f=3 ) streamflowQC_breakpoint( x, min.years=10L, alpha=0.01, min.relative.change=0.5, min.completeness=0.8, indicators=c("mean", "sd", "minimum", "maximum") )streamflowQC_range(x, lower=0, upper=Inf) streamflowQC_duplicate( x, min.month.values=20L, min.year.values=300L, min.nonzero=1L ) streamflowQC_gap(x, interval=NULL) streamflowQC_climatology( x, group=c("dayofyear", "month", "month_slot"), window=5L, z=6, min.samples=30L, offset=0.01 ) streamflowQC_flatline( x, run=11L, high.run=Inf, high.prob=0.99, tolerance=0, flag.zero=FALSE ) streamflowQC_spike(x, factor=5, prob=0.99) streamflowQC_rate( x, group=c("month", "month_slot"), z=6, min.samples=30L, max.rise=Inf, max.fall=Inf, drop.factor=5, offset=0.01 ) streamflowQC_fluctuation( x, window=16L, minimum=8L, low.diff.prob=0.05 ) streamflowQC_highflow( x, log.z=6, amax.ratio=2, return.period=1000, min.years=10L, offset=0.01 ) streamflowQC_spatial( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), area=NULL, elevation=NULL, elevation.scale=500, n.neighbours=5L, max.distance=400, min.neighbours=2L, min.support=1L, min.overlap=90L, min.correlation=0.5, window=3L, high.prob=0.99, support.prob=0.95, f=3 ) streamflowQC_breakpoint( x, min.years=10L, alpha=0.01, min.relative.change=0.5, min.completeness=0.8, indicators=c("mean", "sd", "minimum", "maximum") )
x |
A numeric |
lower, upper
|
Physical limits, scalar or station-specific. |
min.month.values, min.year.values
|
Minimum paired calendar positions for exact copied-month and copied-year comparisons. |
min.nonzero |
Minimum positive observations in a candidate copied block. |
interval |
Expected interval: days for a |
group |
Seasonal grouping. |
window |
For climatology, circular calendar-day window width; for fluctuation, number of observations; for spatial QC, observations before and after the target event. |
z |
Standardized climatology or first-difference threshold. |
min.samples |
Minimum climatology or first-difference reference sample. |
offset |
Positive constant added before taking logarithms. |
run, high.run
|
Minimum ordinary and high-flow flat-line lengths in observations. |
high.prob |
Target high-flow quantile. |
tolerance |
Maximum consecutive difference inside a flat line. |
flag.zero |
Whether repeated zero-flow runs may be flagged. |
factor |
Multiplicative isolated peak/dip threshold. |
prob |
Quantile used as the absolute spike threshold. |
max.rise, max.fall
|
Optional absolute consecutive-change limits, scalar or station-specific. |
drop.factor |
Multiplicative abrupt-fall threshold. |
minimum |
Number of sign reversals that a fluctuation window must exceed. |
low.diff.prob |
Quantile of absolute changes treated as noise. |
log.z |
Global log-flow standard-deviation threshold. |
amax.ratio |
Largest/second-largest annual-maximum ratio threshold. |
return.period |
GEV return-period threshold in years. |
min.years |
Minimum annual values required for GEV or breakpoint analysis. |
metadata |
|
station.id |
Name of the unique station identifier field. |
coords |
Names of longitude and latitude fields, in that order. |
area |
|
elevation |
|
elevation.scale |
Positive elevation-decay scale used in neighbour ranking. |
n.neighbours |
Maximum selected neighbours per station. |
max.distance |
Maximum geographic distance in km. |
min.neighbours |
Minimum simultaneous spatial predictions. |
min.support |
Minimum neighbours with a supporting high-flow event. |
min.overlap |
Minimum paired observations for selection and regression. |
min.correlation |
Minimum preferred Spearman log-flow correlation. |
support.prob |
Neighbour high-flow quantile. |
f |
Minimum standardized spatial residual. |
alpha |
Holm-adjusted Pettitt-test significance level. |
min.relative.change |
Minimum relative pre/post median change. |
min.completeness |
Minimum daily completeness of an annual indicator. |
indicators |
Unique subset of |
streamflowQC_range treats negative discharge and optional
station-specific upper violations as physical errors. Missing values are
handled by the workflow completeness calculation. Non-finite non-missing
values fail the range check.
streamflowQC_duplicate finds exactly copied calendar months or years.
It is intended for daily data; requiring a positive value prevents ordinary
all-zero intermittent-flow blocks from being flagged by default.
streamflowQC_gap marks the first finite observation after a missing
value or missing interval. It complements, rather than replaces, station
completeness. A numeric zoo cannot retain transmission syntax, so the
QARTOD syntax test is enforced structurally by the workflow validators.
streamflowQC_climatology applies the GSIM transformation
log(Q + 0.01) and mean plus/minus six standard deviations. Daily
references use a circular calendar-day window; sub-daily references may use
month or month-slot groups.
streamflowQC_flatline flags every member of an extended near-constant
run. Daily defaults implement more than 10 equal positive values from GSIM.
The sub-daily workflow converts the UK-Flow15-QC seven-day and one-day
high-flow rules from hours to input observations.
streamflowQC_spike requires an isolated centre value to change and
reverse by a factor of five or by more than the station 0.99 quantile.
streamflowQC_rate combines robust monthly log-difference screening,
optional absolute limits, and the five-fold rapid-drop rule.
streamflowQC_fluctuation flags windows with recurrent first-derivative
sign reversals after suppressing the smallest changes.
streamflowQC_highflow returns one combined flag plus separate
six-standard-deviation, AMAX-ratio, and GEV components. The GEV is fitted to
annual maxima by base-R maximum likelihood. The combined flag deliberately
counts as one evidence family because all three statistics describe the same
extreme event.
streamflowQC_spatial selects neighbours using correlation and optional
geographic/elevation proximity, fits target-on-neighbour regressions in
log-specific-discharge space when catchment area is available, and combines
predictions using inverse-error weighted medians. A rare target event is
flagged only when its residual score exceeds f and fewer than
min.support neighbours exceed their support quantile in the search
window.
streamflowQC_breakpoint aggregates sub-daily input to daily means,
calculates complete annual indicators, applies Pettitt rank tests, and
Holm-adjusts p-values. Its station flag is separate from point QC because an
inhomogeneity may represent real regulation or catchment change.
Range, duplicate, gap, climatology, flatline, spike, rate, and fluctuation
tests return a logical zoo matching x.
streamflowQC_highflow returns a list with combined flags,
component flag objects, return.period, and station fit diagnostics.
streamflowQC_spatial returns a list with flags, standardized
scores, flow estimate, neighbour-event support.count,
and selected neighbours.
streamflowQC_breakpoint returns one data.frame row per station.
Fileni, F. et al. (2026). UK-Flow15-QC: A quality control framework for better river flow data in hydrological research. EGUsphere preprint. doi:10.5194/egusphere-2026-277.
Gudmundsson, L. et al. (2018). The Global Streamflow Indices and Metadata Archive (GSIM) - Part 2: quality control, time-series indices and homogeneity assessment. Earth System Science Data, 10, 787–804. doi:10.5194/essd-10-787-2018.
U.S. Integrated Ocean Observing System (2018). Manual for Real-Time Quality Control of Stream Flow Data Version 1.0. doi:10.25923/gszc-ha43.
Zhao, Q. et al. (2018). Research on the Data-Driven Quality Control Method of Hydrological Time Series Data. Water, 10, 1712. doi:10.3390/w10121712.
streamflowQC_daily, streamflowQC_subdaily
dates <- as.Date("2020-01-01") + 0:19 x <- zoo::zoo(cbind(A=c(rep(10, 11), 11:19), B=seq(5, 24)), dates) streamflowQC_flatline(x) streamflowQC_range(x)dates <- as.Date("2020-01-01") + 0:19 x <- zoo::zoo(cbind(A=c(rep(10, 11), 11:19), B=seq(5, 24)), dates) streamflowQC_flatline(x) streamflowQC_range(x)
Structure, print method, and four-panel summary plot for objects returned by
streamflowQC_daily, streamflowQC_subdaily, and
streamflowQC.
## S3 method for class 'streamflowQC' print(x, ...) ## S3 method for class 'streamflowQC' plot( x, max.stations=20L, col=c("#2878B5", "#D55E00", "#E69F00"), ... )## S3 method for class 'streamflowQC' print(x, ...) ## S3 method for class 'streamflowQC' plot( x, max.stations=20L, col=c("#2878B5", "#D55E00", "#E69F00"), ... )
x |
An object inheriting from class |
max.stations |
Maximum number of stations in the affected-station panel. |
col |
At least three plotting colours. |
... |
Additional arguments; the plot method passes them to its final time-series panel. |
The plot summarizes station recommendations, missing/review/rejected fractions, counts by active test, and the time distribution of confirmed suspicious observations. Plotting is diagnostic and does not alter the result or write a file unless the caller explicitly opens a file device.
Both methods return x invisibly. A "streamflowQC" object is a
list with:
accepted.metadata and discarded.metadata: original
station metadata plus completeness, evidence, homogeneity, recommendation,
and reason fields;
accepted.data and discarded.data: original zoo
series split by the station recommendation;
accepted.corrected and discarded.corrected: the same
partitions after the requested correction policy;
suspicious: one row per point flagged for review or rejection,
including all contributing test names and any spatial estimate;
corrections: an audit table containing every changed value;
flags, flag.count, and rejected: individual
logical flag objects, evidence counts, and confirmed decisions;
station.summary: station completeness, review/rejected
fractions, breakpoint diagnostics, recommendation, and reason;
breakpoint: annual-indicator Pettitt-test diagnostics;
spatial.estimate, spatial.score,
spatial.support, and neighbours: spatial-test diagnostics;
highflow and return.period: component high-flow flags,
GEV parameters, and estimated return periods; and
settings: all resolved workflow controls.
Fileni, F. et al. (2026). UK-Flow15-QC: A quality control framework for better river flow data in hydrological research. EGUsphere preprint. doi:10.5194/egusphere-2026-277.
streamflowQC_daily, streamflowQC_subdaily,
streamflowQC_tests
Generic function for transforming a Sub-DAILY time series into a DAILY one
subdaily2daily(x, ...) ## Default S3 method: subdaily2daily(x, FUN, na.rm = TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'zoo' subdaily2daily(x, FUN, na.rm = TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'data.frame' subdaily2daily(x, FUN, na.rm = TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...) ## S3 method for class 'matrix' subdaily2daily(x, FUN, na.rm = TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...)subdaily2daily(x, ...) ## Default S3 method: subdaily2daily(x, FUN, na.rm = TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'zoo' subdaily2daily(x, FUN, na.rm = TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'data.frame' subdaily2daily(x, FUN, na.rm = TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...) ## S3 method for class 'matrix' subdaily2daily(x, FUN, na.rm = TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...)
x |
zoo, data.frame or matrix object, with sub-daily time series. |
FUN |
Function that have to be applied for aggregating from sub-daily into daily time step (e.g., for precipitation
|
na.rm |
Logical. Should missing values be removed? |
na.rm.max |
Numeric in [0, 1]. It is used to define the maximum percentage of missing values allowed in each day to keep the daily aggregated value in the output object of this function. In other words, if the percentage of missing values in a given day is larger than |
start |
character, indicating the starting time used for aggregating sub-daily time series into daily ones. It MUST be provided in the format specified by It is useful when the daily values start at a time different from |
start.fmt |
character indicating the format in which the time is provided in |
tz |
character, with the specification of the time zone used in both |
dates |
numeric, factor, POSIXct or POSIXt object indicating how to obtain the dates and times for each column of |
date.fmt |
character indicating the format in which the dates are stored in |
out.fmt |
OPTIONAL. Only used when |
verbose |
logical; if TRUE, progress messages are printed |
... |
arguments additional to |
This function assumes that x has a strictly regular time frequency (see is.regular) and raise a warning otherwise.
a zoo object with daily time series
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
subhourly2hourly, subdaily2monthly,
subdaily2annual, subdaily2seasonal,
as.POSIXct, dm2seasonal, monthlyfunction,
seasonalfunction, hydroplot,
vector2zoo, izoo2rzoo
## Ex1: Computation of daily values, removing any missing value in 'x' ## Loading the time series of hourly streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Plotting the hourly streamflow values plot(x) # Subsetting 'x' to its first three days (01/Jan/1980 - 03/Jan/1980) x <- window(x, end="1980-01-03 23:59:00") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Agreggating from Sub-Daily to Daily, removing any missing value in 'x' ( d1 <- subdaily2daily(x, FUN=mean, na.rm=TRUE) ) ## Ex2: Computation of daily values, removing any missing value in 'x' and ## considering that the new day starts at 08:00:00 local time ( d2 <- subdaily2daily(x, FUN=mean, na.rm=TRUE, start="08:00:00") ) ## Ex3: Computation of daily values, removing any missing value in 'x' and ## considering that the new day starts at 08:00:00, and forcing # UTC both for 'x' and 'start' ( d3 <- subdaily2daily(x, FUN=mean, na.rm=TRUE, start="08:00:00", tz="UTC") ) ###################### ## Ex4: Compuation of daily values only when the percentage of NAs in each # day is lower than a user-defined percentage (10% in this example). ( d4 <- subdaily2daily(x, FUN=mean, na.rm=TRUE, na.rm.max=0.1) )## Ex1: Computation of daily values, removing any missing value in 'x' ## Loading the time series of hourly streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Plotting the hourly streamflow values plot(x) # Subsetting 'x' to its first three days (01/Jan/1980 - 03/Jan/1980) x <- window(x, end="1980-01-03 23:59:00") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Agreggating from Sub-Daily to Daily, removing any missing value in 'x' ( d1 <- subdaily2daily(x, FUN=mean, na.rm=TRUE) ) ## Ex2: Computation of daily values, removing any missing value in 'x' and ## considering that the new day starts at 08:00:00 local time ( d2 <- subdaily2daily(x, FUN=mean, na.rm=TRUE, start="08:00:00") ) ## Ex3: Computation of daily values, removing any missing value in 'x' and ## considering that the new day starts at 08:00:00, and forcing # UTC both for 'x' and 'start' ( d3 <- subdaily2daily(x, FUN=mean, na.rm=TRUE, start="08:00:00", tz="UTC") ) ###################### ## Ex4: Compuation of daily values only when the percentage of NAs in each # day is lower than a user-defined percentage (10% in this example). ( d4 <- subdaily2daily(x, FUN=mean, na.rm=TRUE, na.rm.max=0.1) )
Generic function for transforming a DAILY (or sub-daily) regular time series into a WEEKLY one
subdaily2weekly(x, ...) ## Default S3 method: subdaily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'zoo' subdaily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'data.frame' subdaily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt = "%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose=TRUE, ...) ## S3 method for class 'matrix' subdaily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt = "%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose=TRUE, ...)subdaily2weekly(x, ...) ## Default S3 method: subdaily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'zoo' subdaily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'data.frame' subdaily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt = "%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose=TRUE, ...) ## S3 method for class 'matrix' subdaily2weekly(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt = "%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose=TRUE, ...)
x |
zoo, data.frame or matrix object, with (sub)daily time series. |
FUN |
Function that have to be applied for transforming from daily to weekly time step (e.g., for precipitation
|
na.rm |
Logical. Should missing values be removed? |
na.rm.max |
Numeric in [0, 1]. It is used to define the maximum percentage of missing values allowed in each week to keep the weekly aggregated value in the output object of this function. In other words, if the percentage of missing values in a given week is larger than |
start |
character, indicating the starting time used for aggregating sub-daily time series into daily ones. It MUST be provided in the format specified by It is useful when the daily values start at a time different from |
start.fmt |
character indicating the format in which the time is provided in |
tz |
character, with the specification of the time zone used in both |
dates |
numeric, factor or Date object indicating how to obtain the dates for each gauging station |
date.fmt |
character indicating the format in which the DateTime objects are stored in dates, e.g. %Y-%m-%d %H:%M:%S. See |
out.fmt |
OPTIONAL. Only used when |
verbose |
logical; if TRUE, progress messages are printed |
... |
arguments additional to |
a zoo object with weekly time frequency
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
cmv, subhourly2hourly, daily2monthly, daily2annual, subdaily2daily, weeklyfunction, hydroplot, vector2zoo, izoo2rzoo, as.Date
###################### ## Ex1: Computation of WEEKLY values from HOURLY ts, only when the percentage of NAs in # each week is lower than a user-defined percentage (10% in this example). ## Loading the HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Subsetting 'x' to its first three weeks # (31-December-1979 to 31-March-1980) x <- window(x, end="1980-03-31 23:59:00") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Daily to Weekly, only for weeks with less than 10% of missing values ( w2 <- subdaily2weekly(x, FUN=sum, na.rm=TRUE, na.rm.max=0.1) ) # Verifying that the second and third month of 'x' had 10% or more of missing values cmv(x, tscale="weekly") ## Not run: ###################### ## Ex2: Computation of WEEKLY values from HOURLY ts, removing any missing value in 'x' # Loading the HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Sub-daily to weekly ts subdaily2weekly(x, FUN=mean, na.rm=TRUE) ## End(Not run)###################### ## Ex1: Computation of WEEKLY values from HOURLY ts, only when the percentage of NAs in # each week is lower than a user-defined percentage (10% in this example). ## Loading the HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Subsetting 'x' to its first three weeks # (31-December-1979 to 31-March-1980) x <- window(x, end="1980-03-31 23:59:00") ## Transforming into NA the 10% of values in 'x' set.seed(10) # for reproducible results n <- length(x) n.nas <- round(0.1*n, 0) na.index <- sample(1:n, n.nas) x[na.index] <- NA ## Daily to Weekly, only for weeks with less than 10% of missing values ( w2 <- subdaily2weekly(x, FUN=sum, na.rm=TRUE, na.rm.max=0.1) ) # Verifying that the second and third month of 'x' had 10% or more of missing values cmv(x, tscale="weekly") ## Not run: ###################### ## Ex2: Computation of WEEKLY values from HOURLY ts, removing any missing value in 'x' # Loading the HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts # Sub-daily to weekly ts subdaily2weekly(x, FUN=mean, na.rm=TRUE) ## End(Not run)
Generic function for transforming a sub-HOURLY time series into an HOURLY one
subhourly2hourly(x, ...) ## Default S3 method: subhourly2hourly(x, FUN, na.rm=TRUE, na.rm.max=0, ...) ## S3 method for class 'zoo' subhourly2hourly(x, FUN, na.rm=TRUE, na.rm.max=0, tz, ...) ## S3 method for class 'data.frame' subhourly2hourly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...) ## S3 method for class 'matrix' subhourly2hourly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...)subhourly2hourly(x, ...) ## Default S3 method: subhourly2hourly(x, FUN, na.rm=TRUE, na.rm.max=0, ...) ## S3 method for class 'zoo' subhourly2hourly(x, FUN, na.rm=TRUE, na.rm.max=0, tz, ...) ## S3 method for class 'data.frame' subhourly2hourly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...) ## S3 method for class 'matrix' subhourly2hourly(x, FUN, na.rm=TRUE, na.rm.max=0, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...)
x |
zoo, data.frame or matrix object, with sub-hourly time series. |
FUN |
Function that have to be applied for transforming from sub-hourly to hourly time step. (e.g., for precipitation |
na.rm |
Logical. Should missing values be removed? |
na.rm.max |
Numeric in [0, 1]. It is used to define the maximum percentage of missing values allowed in each hour to keep the hourly aggregated value in the output object of this function. In other words, if the percentage of missing values in a given hour is larger than |
tz |
character, with the specification of the time zone used for If If A list of valid time zones can be obtained by calling the base function This argument can be used when working with sub-daily zoo objects to force using time zones other than the local time zone for |
dates |
numeric, factor, POSIXct or POSIXt object indicating how to obtain the dates and times for each column of |
date.fmt |
character indicating the format in which the dates are stored in |
out.fmt |
OPTIONAL. Only used when |
verbose |
logical; if TRUE, progress messages are printed |
... |
further arguments passed to or from other methods. |
a zoo object with hourly time series
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
subhourly2nminutes,, subdaily2daily, subdaily2monthly, subdaily2annual, subdaily2seasonal, as.POSIXct, dm2seasonal, monthlyfunction, seasonalfunction, hydroplot, vector2zoo, izoo2rzoo
## Creating a 15-min time sequence and counting its length dt <- seq( from=as.POSIXct("2021-06-30 00:15"), to=as.POSIXct("2021-06-30 23:45"), by="15 min" ) ndt <- length(dt) ## Creating a dummy 15-min zoo object, with 1 as the only value in each time period x <- zoo( rep(1, ndt), dt) ## sub-hourly to hourly h1 <- subhourly2hourly(x, FUN=sum, na.rm=TRUE) ## Aggregation of 3 sub-hourly ts (i.e., a zoo matrix) into an hourly one X <- cbind(x, x, x) h2 <- subhourly2hourly(X, FUN=sum, na.rm=TRUE)## Creating a 15-min time sequence and counting its length dt <- seq( from=as.POSIXct("2021-06-30 00:15"), to=as.POSIXct("2021-06-30 23:45"), by="15 min" ) ndt <- length(dt) ## Creating a dummy 15-min zoo object, with 1 as the only value in each time period x <- zoo( rep(1, ndt), dt) ## sub-hourly to hourly h1 <- subhourly2hourly(x, FUN=sum, na.rm=TRUE) ## Aggregation of 3 sub-hourly ts (i.e., a zoo matrix) into an hourly one X <- cbind(x, x, x) h2 <- subhourly2hourly(X, FUN=sum, na.rm=TRUE)
Generic function for aggregating a sub-hourly or hourly time series into a user-defined n-hourly one.
subhourly2nhourly(x, ...) ## Default S3 method: subhourly2nhourly(x, FUN, n.hours, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt="%H:%M:%S", tz, ...) ## S3 method for class 'zoo' subhourly2nhourly(x, FUN, n.hours, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt="%H:%M:%S", tz, ...) ## S3 method for class 'data.frame' subhourly2nhourly(x, FUN, n.hours, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt="%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose=TRUE, ...) ## S3 method for class 'matrix' subhourly2nhourly(x, FUN, n.hours, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt="%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose=TRUE, ...)subhourly2nhourly(x, ...) ## Default S3 method: subhourly2nhourly(x, FUN, n.hours, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt="%H:%M:%S", tz, ...) ## S3 method for class 'zoo' subhourly2nhourly(x, FUN, n.hours, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt="%H:%M:%S", tz, ...) ## S3 method for class 'data.frame' subhourly2nhourly(x, FUN, n.hours, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt="%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose=TRUE, ...) ## S3 method for class 'matrix' subhourly2nhourly(x, FUN, n.hours, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt="%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose=TRUE, ...)
x |
zoo, data.frame or matrix object, with sub-hourly or hourly time series. |
FUN |
Function that have to be applied for aggregating from sub-hourly or hourly into n-hourly time step (e.g., for precipitation
|
n.hours |
positive integer indicating the length, in hours, of each output aggregation period. |
na.rm |
Logical. Should missing values be removed? |
na.rm.max |
Numeric in [0, 1]. It is used to define the maximum percentage of missing values allowed in each n-hour period to keep the aggregated value in the output object of this function. In other words, if the percentage of missing values in a given n-hour period is larger than |
start |
character, indicating the starting time used for anchoring the n-hour aggregation periods. It MUST be provided in the format specified by |
start.fmt |
character indicating the format in which the time is provided in |
tz |
character, with the specification of the time zone used in both |
dates |
numeric, factor, character, POSIXct or POSIXt object indicating how to obtain the dates and times for each column of |
date.fmt |
character indicating the format in which the dates are stored in |
out.fmt |
OPTIONAL. Only used when |
verbose |
logical; if TRUE, progress messages are printed |
... |
arguments additional to |
This function assumes that x has an hourly or sub-hourly temporal frequency. The output time index corresponds to the beginning of each n-hour aggregation period.
a zoo object with n-hourly time series
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
subhourly2hourly, subhourly2nminutes,
subdaily2daily, subdaily2monthly,
subdaily2annual, subdaily2seasonal,
as.POSIXct, hydroplot, vector2zoo,
izoo2rzoo
## Creating a 30-min time sequence and counting its length dt <- seq(from=as.POSIXct("2021-06-30 00:30", tz="UTC"), to=as.POSIXct("2021-06-30 23:30", tz="UTC"), by="30 min") ndt <- length(dt) ## Creating a dummy 30-min zoo object, with 1 as the only value in each time period x <- zoo(rep(1, ndt), dt) ## Aggregation from 30-minute single ts into 3-hourly ts h1 <- subhourly2nhourly(x, FUN=sum, n.hours=3, na.rm=TRUE) ## Aggregation of 3 ts with 30-minute time frequency (i.e., a zoo matrix) ## into a 6-hourly zoo object. X <- cbind(x, x, x) h2 <- subhourly2nhourly(X, FUN=sum, n.hours=6, na.rm=TRUE) ## Hourly input into 6-hourly output h <- subhourly2hourly(x, FUN=sum) h3 <- subhourly2nhourly(h, FUN=sum, n.hours=6, na.rm=TRUE)## Creating a 30-min time sequence and counting its length dt <- seq(from=as.POSIXct("2021-06-30 00:30", tz="UTC"), to=as.POSIXct("2021-06-30 23:30", tz="UTC"), by="30 min") ndt <- length(dt) ## Creating a dummy 30-min zoo object, with 1 as the only value in each time period x <- zoo(rep(1, ndt), dt) ## Aggregation from 30-minute single ts into 3-hourly ts h1 <- subhourly2nhourly(x, FUN=sum, n.hours=3, na.rm=TRUE) ## Aggregation of 3 ts with 30-minute time frequency (i.e., a zoo matrix) ## into a 6-hourly zoo object. X <- cbind(x, x, x) h2 <- subhourly2nhourly(X, FUN=sum, n.hours=6, na.rm=TRUE) ## Hourly input into 6-hourly output h <- subhourly2hourly(x, FUN=sum) h3 <- subhourly2nhourly(h, FUN=sum, n.hours=6, na.rm=TRUE)
Generic function for aggregating a sub-hourly time series into a "n-minutes' one.
subhourly2nminutes(x, ...) ## Default S3 method: subhourly2nminutes(x, nminutes, FUN, na.rm=TRUE, from=start(x), to=end(x), ...) ## S3 method for class 'zoo' subhourly2nminutes(x, nminutes, FUN, na.rm=TRUE, from=start(x), to=end(x), tz, ...) ## S3 method for class 'data.frame' subhourly2nminutes(x, nminutes, FUN, na.rm=TRUE, from=start(x), to=end(x), dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...) ## S3 method for class 'matrix' subhourly2nminutes(x, nminutes, FUN, na.rm=TRUE, from=start(x), to=end(x), dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...)subhourly2nminutes(x, ...) ## Default S3 method: subhourly2nminutes(x, nminutes, FUN, na.rm=TRUE, from=start(x), to=end(x), ...) ## S3 method for class 'zoo' subhourly2nminutes(x, nminutes, FUN, na.rm=TRUE, from=start(x), to=end(x), tz, ...) ## S3 method for class 'data.frame' subhourly2nminutes(x, nminutes, FUN, na.rm=TRUE, from=start(x), to=end(x), dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...) ## S3 method for class 'matrix' subhourly2nminutes(x, nminutes, FUN, na.rm=TRUE, from=start(x), to=end(x), dates=1, date.fmt="%Y-%m-%d %H:%M:%S", out.fmt="zoo", verbose= TRUE, ...)
x |
zoo, data.frame or matrix object, with sub-hourly time series. |
nminutes |
numeric, defining the amount of minutes to be used for aggregating |
FUN |
Function that have to be applied for aggregating from sub-hourly into n-minutes time step. (e.g., for precipitation |
na.rm |
Logical. Should missing values be removed? |
from |
POSIX object indicating the starting time used to carry out the temporal aggregation. |
to |
POSIX object indicating the ending time used to carry out the temporal aggregation. |
tz |
character, with the specification of the time zone used for If If A list of valid time zones can be obtained by calling the base function This argument can be used when working with sub-daily zoo objects to force using time zones other than the local time zone for |
dates |
numeric, factor, POSIXct or POSIXt object indicating how to obtain the dates and times for each column of |
date.fmt |
character indicating the format in which the dates are stored in |
out.fmt |
OPTIONAL. Only used when |
verbose |
logical; if TRUE, progress messages are printed |
... |
further arguments passed to or from other methods. |
a zoo object with hourly time series
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
subhourly2hourly, subdaily2daily, subdaily2monthly, subdaily2annual, subdaily2seasonal, as.POSIXct, dm2seasonal, monthlyfunction, seasonalfunction, hydroplot, vector2zoo, izoo2rzoo
## Creating a 5-min time sequence and counting its length dt <- seq( from=as.POSIXct("2021-06-30 00:00"), to=as.POSIXct("2021-06-30 23:55"), by="5 min" ) ndt <- length(dt) ## Creating a dummy 5-min zoo object, with 1 as the only value in each time period x <- zoo( rep(1, ndt), dt) ## Aggregation from 5-minute single ts into 10-minute ts h1 <- subhourly2nminutes(x, nminutes= 10, FUN=sum, na.rm=TRUE) ## Aggregation of 3 ts with 5-minute time frequency (i.e., a zoo matrix) ## into a 30-minute zoo object. X <- cbind(x, x, x) h2 <- subhourly2nminutes(X, nminutes= 30, FUN=sum, na.rm=TRUE)## Creating a 5-min time sequence and counting its length dt <- seq( from=as.POSIXct("2021-06-30 00:00"), to=as.POSIXct("2021-06-30 23:55"), by="5 min" ) ndt <- length(dt) ## Creating a dummy 5-min zoo object, with 1 as the only value in each time period x <- zoo( rep(1, ndt), dt) ## Aggregation from 5-minute single ts into 10-minute ts h1 <- subhourly2nminutes(x, nminutes= 10, FUN=sum, na.rm=TRUE) ## Aggregation of 3 ts with 5-minute time frequency (i.e., a zoo matrix) ## into a 30-minute zoo object. X <- cbind(x, x, x) h2 <- subhourly2nminutes(X, nminutes= 30, FUN=sum, na.rm=TRUE)
Detects the sampling frequency of a numeric zoo object with
sfreq and dispatches it to tempQC_daily or
tempQC_subdaily. No files are written.
tempQC( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), ..., elevation=NULL, elevation.scale=500 )tempQC( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), ..., elevation=NULL, elevation.scale=500 )
x |
A numeric |
metadata, station.id, coords, elevation, elevation.scale
|
Optional
station metadata, field-name selectors, and elevation-decay control passed to
the selected workflow. See |
... |
Arguments passed unchanged to the selected workflow. |
Daily input is sent to tempQC_daily; minute or hourly input is sent to
tempQC_subdaily. Other frequencies are rejected explicitly. Automatic
dispatch changes only the workflow: test activation, thresholds, metadata,
correction policy, and station recommendation criteria remain under user
control. The staged design follows the gross-error, tolerance, temporal,
inter-variable, and inter-station QC categories described by Brunet et al.
(2020).
An object of class "tempQC"; see tempQC-class.
Brunet, M. et al. (2020). Best Practice Guidelines for Climate Data and Metadata Formatting, Quality Control and Submission. Copernicus Climate Change Service.
tempQC_daily, tempQC_subdaily,
tempQC_tests, precipQC
dates <- as.Date("2020-01-01") + 0:29 x <- zoo::zoo(cbind(A=10 + sin(seq_along(dates)), B=11 + sin(seq_along(dates))), dates) qc <- tempQC(x, checks=c(range=TRUE, duplicate=FALSE, climatology=FALSE, persistence=FALSE, step=FALSE, spike=FALSE, spatial=FALSE, breakpoint=FALSE), min.years=0) qc$station.summarydates <- as.Date("2020-01-01") + 0:29 x <- zoo::zoo(cbind(A=10 + sin(seq_along(dates)), B=11 + sin(seq_along(dates))), dates) qc <- tempQC(x, checks=c(range=TRUE, duplicate=FALSE, climatology=FALSE, persistence=FALSE, step=FALSE, spike=FALSE, spatial=FALSE, breakpoint=FALSE), min.years=0) qc$station.summary
Applies a conservative, multi-test quality-control workflow to one or more
daily air-temperature station series in a zoo object. It returns
auditable point flags, optional corrections, and station acceptance or discard
recommendations without writing to disk.
tempQC_daily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, duplicate=TRUE, climatology=TRUE, persistence=TRUE, step=TRUE, spike=TRUE, spatial=TRUE, breakpoint=TRUE), lower=-89.4, upper=57.7, duplicate.min.month=20L, duplicate.min.year=300L, climatology.window=15L, climatology.z=6, climatology.min.samples=100L, persistence.run=7L, persistence.tolerance=0, step.z=3, step.min.samples=20L, step.max.rise=Inf, step.max.fall=Inf, spike.threshold=25, n.neighbours=5L, max.distance=200, min.neighbours=2L, min.overlap=90L, min.group.overlap=20L, min.correlation=0.6, spatial.f=4, spatial.min.difference=8, breakpoint.min.years=10L, breakpoint.alpha=0.05, breakpoint.min.shift=1, breakpoint.min.completeness=0.8, correction=c("none", "set_na", "spatial"), min.evidence=2L, max.missing=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, elevation=NULL, elevation.scale=500 )tempQC_daily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, duplicate=TRUE, climatology=TRUE, persistence=TRUE, step=TRUE, spike=TRUE, spatial=TRUE, breakpoint=TRUE), lower=-89.4, upper=57.7, duplicate.min.month=20L, duplicate.min.year=300L, climatology.window=15L, climatology.z=6, climatology.min.samples=100L, persistence.run=7L, persistence.tolerance=0, step.z=3, step.min.samples=20L, step.max.rise=Inf, step.max.fall=Inf, spike.threshold=25, n.neighbours=5L, max.distance=200, min.neighbours=2L, min.overlap=90L, min.group.overlap=20L, min.correlation=0.6, spatial.f=4, spatial.min.difference=8, breakpoint.min.years=10L, breakpoint.alpha=0.05, breakpoint.min.shift=1, breakpoint.min.completeness=0.8, correction=c("none", "set_na", "spatial"), min.evidence=2L, max.missing=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, elevation=NULL, elevation.scale=500 )
x |
A numeric daily |
metadata |
|
station.id |
Name of the metadata column containing the column names
of |
coords |
Names of numeric longitude and latitude metadata columns in
decimal degrees, in that order. Entries may be |
elevation |
|
elevation.scale |
Positive elevation-decay scale in metres. It
controls how strongly height differences reduce neighbour suitability and
regression weights. It is ignored when |
checks |
Named logical vector used to activate or deactivate any of
|
lower, upper
|
Physical screening limits. Each can be scalar or contain one value per station. Regionally authoritative limits should replace the defaults when available. |
duplicate.min.month, duplicate.min.year
|
Minimum number of complete, paired calendar positions needed to declare two months or years identical. |
climatology.window |
Width in days of the circular day-of-year reference window. |
climatology.z |
Absolute robust standardized anomaly threshold. |
climatology.min.samples |
Minimum reference sample size for a calendar-window climatology. |
persistence.run |
Minimum number of consecutive values in a flat line. |
persistence.tolerance |
Maximum range within a flat-line window. |
step.z |
Robust standardized threshold for a consecutive-day change. |
step.min.samples |
Minimum monthly sample of first differences. |
step.max.rise, step.max.fall
|
Optional absolute rise and fall limits;
|
spike.threshold |
Minimum absolute difference from both adjacent days, with the two differences having the same sign, for an isolated spike or dip. |
n.neighbours |
Maximum number of spatial-regression neighbours. |
max.distance |
Maximum target-neighbour great-circle distance in km. |
min.neighbours |
Minimum number of simultaneous regression estimates. |
min.overlap |
Minimum paired observations for initial neighbour selection. |
min.group.overlap |
Minimum paired observations within a calendar month for fitting an individual regression. |
min.correlation |
Minimum Pearson correlation for an eligible neighbour. |
spatial.f |
Minimum standardized spatial-regression residual. |
spatial.min.difference |
Minimum absolute observed-estimated difference in degrees Celsius. Both spatial criteria must be exceeded. |
breakpoint.min.years |
Minimum complete annual indicators for a Pettitt test. |
breakpoint.alpha |
Holm-adjusted significance level for breakpoint evidence. |
breakpoint.min.shift |
Minimum absolute difference between median annual indicators before and after a breakpoint. |
breakpoint.min.completeness |
Minimum fraction of daily observations in an annual indicator. |
correction |
|
min.evidence |
Number of coincident non-hard flags needed to reject a point. Physical range, copied-block, flat-line, and isolated-spike flags are hard evidence. |
max.missing, max.suspicious
|
Maximum missing and confirmed-suspicious fractions for recommending a station for acceptance. |
min.years |
Minimum record length for station acceptance. |
discard.breakpoint |
Logical. If |
The tests represent independent error mechanisms and are deliberately combined as evidence instead of interpreting every statistical outlier as an error.
Physical range and copied blocks. Values beyond observed world limits and exactly duplicated months or years are gross-integrity failures. The limits and block comparisons follow Durre et al. (2010). The duplicate test requires complete paired calendar positions to limit false positives.
Climatological plausibility. For each station and calendar day, the median and MAD are calculated from a moving 15-day window. An absolute robust score of six is flagged. This is a resistant implementation of the 15-day, six-standard-deviation test in Durre et al. (2010) and the biweight calendar-window approach of Feng et al. (2004).
Persistence, steps, and spikes. Flat lines expose stuck sensors or copied reports (Feng et al., 2004; Boulanger et al., 2010). First differences are checked against month-specific robust limits, adapting the seasonal rate-of-change test of Hubbard et al. (2007). A value at least 25 degrees from both neighbours in the same direction implements the daily spike/dip criterion of Durre et al. (2010).
Spatial regression. Month-specific linear regressions predict the target from eligible correlated stations. The five regressions with the lowest proximity-adjusted errors are combined with proximity/inverse-error-variance weights. Proximity decays with horizontal distance and, when selected, absolute elevation difference. The pairwise regression intercept estimates systematic station offsets rather than imposing a universal lapse rate. A target missing either coordinate uses correlation and regression error without a distance filter. A located target ranks eligible located neighbours first; unlocated neighbours remain conservative fallbacks with reduced spatial weight. A point is flagged only if both its absolute residual and its standardized residual are large. This combines the SRT formulation of Hubbard et al. (2007) and Estevez et al. (2018) with the conservative dual threshold of Durre et al. (2010). Correlation-based selection is important in complex terrain (Xiong et al., 2022; Xiong et al., 2024).
Homogeneity. Pettitt tests are applied to sufficiently complete annual mean and variability series and adjusted by Holm's method. The result is diagnostic by default, reflecting the distinction between QC and homogenization emphasized by Boulanger et al. (2010) and Brunet et al. (2020).
The paired logical constraints and lagged minimum-
maximum checks cannot be inferred from a single univariate station matrix. Use
tempQC_internal when paired Tmin and Tmax zoo objects are
available.
An object of class "tempQC"; see tempQC-class.
Boulanger, J.-P., Aizpuru, J., Leggieri, L. and Marino, M. (2010). A procedure for automated quality control and homogenization of historical daily temperature and precipitation data (APACH): part 1. Climatic Change, 98, 471–491.
Brunet, M. et al. (2020). Best Practice Guidelines for Climate Data and Metadata Formatting, Quality Control and Submission. Copernicus Climate Change Service.
Durre, I., Menne, M. J., Gleason, B. E., Houston, T. G. and Vose, R. S. (2010). Comprehensive automated quality assurance of daily surface observations. Journal of Applied Meteorology and Climatology, 49, 1615–1633.
Estevez, J., Gavilan, P. and Garcia-Marin, A. P. (2018). Spatial regression test for ensuring temperature data quality in southern Spain. Theoretical and Applied Climatology, 131, 309–318.
Feng, S., Hu, Q. and Qian, W. (2004). Quality control of daily meteorological data in China, 1951–2000. International Journal of Climatology, 24, 853–870.
Hubbard, K. G., Guttman, N. B., You, J. and Chen, Z. (2007). An improved QC process for temperature in the daily cooperative weather observations. Journal of Atmospheric and Oceanic Technology, 24, 206–213.
Xiong, X. et al. (2022). Research on quality control methods for surface temperature observations via spatial correlation analysis. International Journal of Climatology. doi:10.1002/joc.7897.
Xiong, X. et al. (2024). Research on quality control method of surface temperature observations for complex physical geography. Journal of Atmospheric and Oceanic Technology, 41, 803–815.
tempQC, tempQC_subdaily,
tempQC_tests, plot.tempQC
dates <- as.Date("2020-01-01") + 0:89 v <- 12 + 8 * sin(2 * pi * seq_along(dates) / 365) x <- zoo::zoo(cbind(A=v, B=v + 0.3), dates) qc <- tempQC_daily( x, checks=c(range=TRUE, duplicate=FALSE, climatology=FALSE, persistence=TRUE, step=FALSE, spike=TRUE, spatial=FALSE, breakpoint=FALSE), min.years=0, max.missing=1 ) qc$station.summarydates <- as.Date("2020-01-01") + 0:89 v <- 12 + 8 * sin(2 * pi * seq_along(dates) / 365) x <- zoo::zoo(cbind(A=v, B=v + 0.3), dates) qc <- tempQC_daily( x, checks=c(range=TRUE, duplicate=FALSE, climatology=FALSE, persistence=TRUE, step=FALSE, spike=TRUE, spatial=FALSE, breakpoint=FALSE), min.years=0, max.missing=1 ) qc$station.summary
Applies physical, climatological, temporal, spatial, and homogeneity checks to
minute or hourly air-temperature station series in a zoo object. The
method preserves the native time index and writes no files.
tempQC_subdaily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, climatology=TRUE, persistence=TRUE, step=TRUE, spike=TRUE, spatial=TRUE, breakpoint=TRUE), lower=-89.4, upper=57.7, climatology.z=6, climatology.min.samples=30L, persistence.hours=3, persistence.tolerance=0.05, step.z=5, step.min.samples=30L, step.max.rise=Inf, step.max.fall=Inf, spike.threshold=12, n.neighbours=5L, max.distance=50, min.neighbours=2L, min.overlap=100L, min.group.overlap=20L, min.correlation=0.7, spatial.f=4, spatial.min.difference=5, breakpoint.min.years=10L, breakpoint.alpha=0.05, breakpoint.min.shift=1, breakpoint.min.completeness=0.8, correction=c("none", "set_na", "spatial"), min.evidence=2L, max.missing=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, elevation=NULL, elevation.scale=500 )tempQC_subdaily( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), checks=c(range=TRUE, climatology=TRUE, persistence=TRUE, step=TRUE, spike=TRUE, spatial=TRUE, breakpoint=TRUE), lower=-89.4, upper=57.7, climatology.z=6, climatology.min.samples=30L, persistence.hours=3, persistence.tolerance=0.05, step.z=5, step.min.samples=30L, step.max.rise=Inf, step.max.fall=Inf, spike.threshold=12, n.neighbours=5L, max.distance=50, min.neighbours=2L, min.overlap=100L, min.group.overlap=20L, min.correlation=0.7, spatial.f=4, spatial.min.difference=5, breakpoint.min.years=10L, breakpoint.alpha=0.05, breakpoint.min.shift=1, breakpoint.min.completeness=0.8, correction=c("none", "set_na", "spatial"), min.evidence=2L, max.missing=0.2, max.suspicious=0.05, min.years=1, discard.breakpoint=FALSE, elevation=NULL, elevation.scale=500 )
x |
A numeric |
metadata |
|
station.id |
Name of the station identifier column in |
coords |
Names of longitude and latitude metadata columns in decimal
degrees, in that order. Individual entries may be |
elevation |
|
elevation.scale |
Positive height-decay scale in metres used in
neighbour selection and weighting when |
checks |
Named logical vector that overrides any of |
lower, upper
|
Physical screening limits, scalar or station-specific. |
climatology.z |
Absolute robust anomaly threshold within each calendar-month and hour-of-day group. |
climatology.min.samples |
Minimum group sample size. |
persistence.hours |
Duration of an almost-flat period. The corresponding number of observations is derived from the modal sampling interval. |
persistence.tolerance |
Maximum temperature range within that period. |
step.z |
Robust standardized threshold for consecutive changes within each month and hour. |
step.min.samples |
Minimum first-difference sample per group. |
step.max.rise, step.max.fall
|
Optional absolute consecutive rise and fall limits; use regional, interval-specific values when available. |
spike.threshold |
Minimum difference from both adjacent observations for an isolated spike or dip. |
n.neighbours, max.distance, min.neighbours
|
Maximum neighbour count, maximum distance in km, and minimum simultaneous estimates. |
min.overlap, min.group.overlap
|
Minimum overall and month-hour paired samples for neighbour selection and regression fitting. |
min.correlation |
Minimum eligible target-neighbour Pearson correlation. |
spatial.f |
Minimum standardized spatial residual. |
spatial.min.difference |
Minimum absolute spatial residual in degrees Celsius. Both spatial thresholds must be exceeded. |
breakpoint.min.years, breakpoint.alpha, breakpoint.min.shift, breakpoint.min.completeness
|
Minimum annual sample size, Holm-adjusted significance level, minimum absolute median shift, and annual completeness for the homogeneity diagnostic. |
correction |
|
min.evidence |
Number of coincident non-hard tests needed to reject a point. Range, persistence, and isolated-spike flags are hard evidence. |
max.missing, max.suspicious, min.years
|
Station acceptance limits. |
discard.breakpoint |
Whether a flagged breakpoint should cause a station discard recommendation. |
The sub-daily workflow uses the same evidence and audit model as
tempQC_daily, but its climatological, first-difference, and
spatial-regression reference groups are conditioned jointly on calendar month
and hour of day. Cheng et al. (2016) showed that hourly reference-station
relations can change sharply by hour and season, especially across complex
terrain.
Range: global physical limits screen gross coding and unit errors. Local limits may be supplied; elevation-adjusted regional limits are preferable where established (Cheng et al., 2016).
Climatology: robust median/MAD limits within month-hour groups preserve the diurnal and seasonal cycle (Cheng et al., 2016; Brunet et al., 2020).
Persistence: the default identifies a temperature range no greater than 0.05 degrees across three hours, adapting the 10-minute flat-line test of Beele et al. (2022) to the detected sampling interval.
Steps and isolated spikes: month-hour first differences are standardized robustly. Optional absolute rise and fall limits support local real-time criteria. Cheng et al. (2016) demonstrate why weather- and hour-dependent limits are safer than a universal hourly threshold; Beele et al. (2022) provide an operational 10-minute example.
Spatial regression: correlated neighbours are chosen by proximity-adjusted regression error and combined with proximity and inverse-error-variance weights. Geographic distance and, when supplied, elevation difference define proximity. A target missing either coordinate uses the correlation/regression fallback, while a located target prefers eligible located neighbours. Models are fitted separately by month and hour. This implements the SRT family evaluated by Hubbard et al. (2007), Cheng et al. (2016), and Estevez et al. (2018), while the correlation screen addresses the terrain sensitivity discussed by Xiong et al. (2022, 2024).
Homogeneity: native values are converted to daily means before annual mean and variability breakpoint diagnostics. The result is not a point flag and does not cause discard unless explicitly requested.
An object of class "tempQC"; see tempQC-class.
Beele, E., Reyniers, M., Aerts, R. and Somers, B. (2022). Quality control and correction method for air temperature data from a citizen science weather station network in Leuven, Belgium. Earth System Science Data, 14, 4681–4717.
Brunet, M. et al. (2020). Best Practice Guidelines for Climate Data and Metadata Formatting, Quality Control and Submission. Copernicus Climate Change Service.
Cheng, A. R., Lee, T. H., Ku, H. I. and Chen, Y. W. (2016). Quality control program for real-time hourly temperature observation in Taiwan. Journal of Atmospheric and Oceanic Technology, 33, 953–965.
Estevez, J., Gavilan, P. and Garcia-Marin, A. P. (2018). Spatial regression test for ensuring temperature data quality in southern Spain. Theoretical and Applied Climatology, 131, 309–318.
Hubbard, K. G., Guttman, N. B., You, J. and Chen, Z. (2007). An improved QC process for temperature in the daily cooperative weather observations. Journal of Atmospheric and Oceanic Technology, 24, 206–213.
Xiong, X. et al. (2022). Research on quality control methods for surface temperature observations via spatial correlation analysis. International Journal of Climatology. doi:10.1002/joc.7897.
Xiong, X. et al. (2024). Research on quality control method of surface temperature observations for complex physical geography. Journal of Atmospheric and Oceanic Technology, 41, 803–815.
tempQC, tempQC_daily,
tempQC_tests, plot.tempQC
times <- seq(as.POSIXct("2020-01-01", tz="UTC"), by="hour", length.out=72) h <- as.integer(format(times, "%H")) v <- 12 + 5 * sin(2 * pi * h / 24) x <- zoo::zoo(cbind(A=v, B=v + 0.2), times) qc <- tempQC_subdaily( x, checks=c(range=TRUE, climatology=FALSE, persistence=TRUE, step=FALSE, spike=TRUE, spatial=FALSE, breakpoint=FALSE), min.years=0, max.missing=1 ) qc$station.summarytimes <- seq(as.POSIXct("2020-01-01", tz="UTC"), by="hour", length.out=72) h <- as.integer(format(times, "%H")) v <- 12 + 5 * sin(2 * pi * h / 24) x <- zoo::zoo(cbind(A=v, B=v + 0.2), times) qc <- tempQC_subdaily( x, checks=c(range=TRUE, climatology=FALSE, persistence=TRUE, step=FALSE, spike=TRUE, spatial=FALSE, breakpoint=FALSE), min.years=0, max.missing=1 ) qc$station.summary
Individual tests called by tempQC_daily and
tempQC_subdaily. They are exported so each source of evidence
can be run, inspected, and tuned independently.
tempQC_range(x, lower=-89.4, upper=57.7) tempQC_duplicate(x, min.month.values=20L, min.year.values=300L) tempQC_persistence(x, run=7L, tolerance=0) tempQC_climatology( x, group=c("dayofyear", "month", "month_hour"), window=15L, z=6, min.samples=30L ) tempQC_step( x, group=c("month", "month_hour"), z=3, min.samples=20L, max.rise=Inf, max.fall=Inf ) tempQC_spike(x, threshold=25) tempQC_spatial( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), group=c("month", "month_hour"), n.neighbours=5L, max.distance=200, min.neighbours=2L, min.overlap=90L, min.group.overlap=20L, min.correlation=0.6, f=4, min.difference=8, min.se=0.1, elevation=NULL, elevation.scale=500 ) tempQC_internal(tmin, tmax, lagged=TRUE, max.range=40) tempQC_breakpoint( x, min.years=10L, alpha=0.05, min.shift=1, min.completeness=0.8, indicators=c("mean", "sd") )tempQC_range(x, lower=-89.4, upper=57.7) tempQC_duplicate(x, min.month.values=20L, min.year.values=300L) tempQC_persistence(x, run=7L, tolerance=0) tempQC_climatology( x, group=c("dayofyear", "month", "month_hour"), window=15L, z=6, min.samples=30L ) tempQC_step( x, group=c("month", "month_hour"), z=3, min.samples=20L, max.rise=Inf, max.fall=Inf ) tempQC_spike(x, threshold=25) tempQC_spatial( x, metadata=NULL, station.id="station", coords=c("lon", "lat"), group=c("month", "month_hour"), n.neighbours=5L, max.distance=200, min.neighbours=2L, min.overlap=90L, min.group.overlap=20L, min.correlation=0.6, f=4, min.difference=8, min.se=0.1, elevation=NULL, elevation.scale=500 ) tempQC_internal(tmin, tmax, lagged=TRUE, max.range=40) tempQC_breakpoint( x, min.years=10L, alpha=0.05, min.shift=1, min.completeness=0.8, indicators=c("mean", "sd") )
x |
A numeric |
lower, upper
|
Physical limits, scalar or station-specific. |
min.month.values, min.year.values
|
Minimum complete paired positions for copied-month and copied-year comparisons. |
run |
Minimum flat-line window length in observations. |
tolerance |
Maximum within-window temperature range. |
group |
Calendar grouping. |
window |
Circular calendar-day window width. |
z |
Absolute robust standardized climatology or first-difference threshold. |
min.samples |
Minimum climatological or first-difference reference sample. |
max.rise, max.fall
|
Optional absolute consecutive-change limits. |
threshold |
Absolute difference from both adjacent values required by the isolated spike/dip test. |
metadata |
|
station.id |
Name of the metadata station identifier column. |
coords |
Names of numeric longitude and latitude metadata columns in
decimal degrees, in that order. Individual entries may be |
elevation |
|
elevation.scale |
Positive elevation-decay scale in metres used to penalize neighbours with large height differences. |
n.neighbours |
Maximum selected spatial-regression neighbours. |
max.distance |
Maximum target-neighbour distance in km. |
min.neighbours |
Minimum simultaneous valid regression estimates. |
min.overlap |
Minimum overall paired observations for neighbour selection. |
min.group.overlap |
Minimum paired observations in a model group. |
min.correlation |
Minimum target-neighbour Pearson correlation. |
f |
Standardized residual threshold for spatial regression. |
min.difference |
Absolute spatial residual threshold. |
min.se |
Positive lower bound on each regression standard error. |
tmin, tmax
|
Numeric |
lagged |
Whether to apply previous/current/following-day logical tests. |
max.range |
Maximum allowed lagged Tmin–Tmax separation. |
min.years |
Minimum complete annual indicators for breakpoint testing. |
alpha |
Holm-adjusted breakpoint significance level. |
min.shift |
Minimum absolute pre/post median change in degrees Celsius. |
min.completeness |
Minimum daily completeness of an annual indicator. |
indicators |
Unique subset of |
tempQC_range is a gross-error test using the world-record screening
limits compiled by Durre et al. (2010). Limits are intentionally configurable.
tempQC_duplicate compares corresponding calendar positions and flags
complete months or years that are copied exactly. Durre et al. (2010) identify
such duplication as a keying, transmission, or processing failure.
tempQC_persistence moves a window through each station and flags every
observation in windows whose range does not exceed tolerance. Exact
seven-day flat lines follow Feng et al. (2004); the adjustable tolerance and
duration support sub-daily sensor tests such as Beele et al. (2022).
tempQC_climatology calculates a resistant median and MAD reference.
Daily tests use a circular day-of-year window; sub-daily tests can preserve the
seasonal and diurnal cycles with month-hour groups. The six-score default is
based on Durre et al. (2010), with the resistant formulation motivated by Feng
et al. (2004).
tempQC_step robustly standardizes consecutive changes within calendar
groups and can also apply absolute rise/fall limits. This is the seasonal
rate-of-change structure of Hubbard et al. (2007), extended to hour-specific
groups following Cheng et al. (2016).
tempQC_spike requires the centre value to differ from both neighbours
by at least threshold in the same direction. Its daily default is the
25-degree spike/dip rule of Durre et al. (2010).
tempQC_spatial fits target-on-neighbour linear regressions separately
by calendar group, retains the lowest proximity-adjusted-error eligible
neighbours, and combines their predictions with geographic/elevation
proximity and inverse-error-variance weights. The pairwise regression
intercept estimates systematic station offsets, including persistent height
effects, without imposing a fixed lapse rate. Missing target coordinates
trigger correlation/error-based selection; for a located target, eligible
located neighbours rank ahead of unlocated fallbacks. A flag requires both
an absolute and a standardized residual. The equations follow the spatial
regression test of Hubbard et al. (2007) and Estevez et al. (2018); grouping
and correlation screening incorporate findings of Cheng et al. (2016) and
Xiong et al. (2022, 2024).
tempQC_internal flags Tmin above Tmax, possible interchange relative to
the adjacent three-day window, and the 40-degree lagged range conditions in
Durre et al. (2010). It returns separate flags because the erroneous member of
an inconsistent pair is not identifiable automatically.
tempQC_breakpoint aggregates sub-daily data to daily means, calculates
complete annual indicators, applies Pettitt rank tests, and adjusts p-values
across indicators. Boulanger et al. (2010) and Brunet et al. (2020) motivate
reporting homogeneity separately from point QC.
The range, duplicate, persistence, climatology, step, and spike tests return a
logical zoo object matching x. tempQC_spatial returns a
list with logical flags, numeric scores, numeric
estimate, and selected neighbours. tempQC_internal
returns a list of Tmin and Tmax flag objects. tempQC_breakpoint returns
one data.frame row per station.
Beele, E. et al. (2022). Quality control and correction method for air temperature data from a citizen science weather station network. Earth System Science Data, 14, 4681–4717.
Boulanger, J.-P. et al. (2010). A procedure for automated quality control and homogenization of historical daily temperature and precipitation data. Climatic Change, 98, 471–491.
Brunet, M. et al. (2020). Best Practice Guidelines for Climate Data and Metadata Formatting, Quality Control and Submission. Copernicus Climate Change Service.
Cheng, A. R. et al. (2016). Quality control program for real-time hourly temperature observation in Taiwan. Journal of Atmospheric and Oceanic Technology, 33, 953–965.
Durre, I. et al. (2010). Comprehensive automated quality assurance of daily surface observations. Journal of Applied Meteorology and Climatology, 49, 1615–1633.
Estevez, J. et al. (2018). Spatial regression test for ensuring temperature data quality in southern Spain. Theoretical and Applied Climatology, 131, 309–318.
Feng, S., Hu, Q. and Qian, W. (2004). Quality control of daily meteorological data in China, 1951–2000. International Journal of Climatology, 24, 853–870.
Hubbard, K. G. et al. (2007). An improved QC process for temperature in the daily cooperative weather observations. Journal of Atmospheric and Oceanic Technology, 24, 206–213.
Xiong, X. et al. (2022). Research on quality control methods for surface temperature observations via spatial correlation analysis. International Journal of Climatology. doi:10.1002/joc.7897.
Xiong, X. et al. (2024). Research on quality control method of surface temperature observations for complex physical geography. Journal of Atmospheric and Oceanic Technology, 41, 803–815.
dates <- as.Date("2020-01-01") + 0:9 x <- zoo::zoo(cbind(A=c(rep(10, 7), 11, 12, 13)), dates) tempQC_persistence(x) tempQC_range(x)dates <- as.Date("2020-01-01") + 0:9 x <- zoo::zoo(cbind(A=c(rep(10, 7), 11, 12, 13)), dates) tempQC_persistence(x) tempQC_range(x)
Structure, print method, and four-panel summary plot for objects returned by
tempQC_daily, tempQC_subdaily, and
tempQC.
## S3 method for class 'tempQC' print(x, ...) ## S3 method for class 'tempQC' plot( x, max.stations=20L, col=c("#2878B5", "#D55E00", "#E69F00"), ... )## S3 method for class 'tempQC' print(x, ...) ## S3 method for class 'tempQC' plot( x, max.stations=20L, col=c("#2878B5", "#D55E00", "#E69F00"), ... )
x |
An object inheriting from class |
max.stations |
Maximum number of stations in the affected-station panel. |
col |
At least three plotting colours. |
... |
Additional arguments; the plot method passes them to its final time-series panel. |
The plot summarizes station recommendations, missing and confirmed-suspicious fractions, counts by active test, and the time distribution of rejected observations. It is diagnostic and does not alter the result.
Both methods return x invisibly. A "tempQC" object is a list
with:
accepted.metadata and discarded.metadata: station
metadata plus recommendation diagnostics;
accepted.data: original zoo series for stations
recommended for acceptance;
accepted.corrected: the same accepted stations after the
requested correction policy;
suspicious: one row per point flagged for review or rejection;
corrections: an audit table of changed values;
flags, flag.count, and rejected: individual
logical flag objects, evidence counts, and confirmed decisions;
station.summary: completeness, flag fractions, breakpoint
diagnostics, recommendation, and reason;
breakpoint: station homogeneity diagnostics;
spatial.estimate, spatial.score, and
neighbours: spatial-test diagnostics; and
settings: resolved workflow settings.
Brunet, M. et al. (2020). Best Practice Guidelines for Climate Data and Metadata Formatting, Quality Control and Submission. Copernicus Climate Change Service.
tempQC_daily, tempQC_subdaily,
tempQC_tests
This function transforms a character vector of Dates or DateTimes into a character vector of seasons (summer, winter, autumn, spring), depending on the value of type:
When type=default
-) winter = DJF: December, January, February
-) spring = MAM: March, April, May
-) summer = JJA: June, July, August
-) autumn = SON: September, October, November
When type=FrenchPolynesia
-) winter = DJFM: December, January, February, March
-) spring = AM : April, May
-) summer = JJAS: June, July, August, September
-) autumn = ON : October, November
When type=SONDJFM
-) SONDJFM: September, October, November, December, January, February, March, with January, February and March belonging to the next calendar year. Leading January, February and March values before the first September season are returned as NA. Other months are returned as NA.
time2season(x, out.fmt = "months", type="default")time2season(x, out.fmt = "months", type="default")
x |
vector with the dates that have to be transformed. class(x) must be Date |
out.fmt |
character, indicating the format of the output seasons. Possible values are: |
type |
character, indicating which weather seasons will be used for computing the output. Possible values are: |
character vector with the weather season to which each date in x belongs
Weather seasons corresponding to French Polynesia were defined following a comment from Lydie Sichoix
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
dm2seasonal, seasonalfunction, extract, dip, mip
## Sequence of daily dates between "1961-01-01" and "1961-12-31" t <- dip("1961-01-01", "1961-12-31") time2season(t) ## Sequence of monthly dates between "1961-01-01" and "1961-12-31" t <- mip("1961-01-01", "1961-12-31") time2season(t) time2season(t, out.fmt="seasons") ## September to March selector time2season(t, type="SONDJFM")## Sequence of daily dates between "1961-01-01" and "1961-12-31" t <- dip("1961-01-01", "1961-12-31") time2season(t) ## Sequence of monthly dates between "1961-01-01" and "1961-12-31" t <- mip("1961-01-01", "1961-12-31") time2season(t) time2season(t, out.fmt="seasons") ## September to March selector time2season(t, type="SONDJFM")
Transform a numeric vector and its corresponding dates into a zoo object.
vector2zoo(x, dates, date.fmt = "%Y-%m-%d")vector2zoo(x, dates, date.fmt = "%Y-%m-%d")
x |
numeric vector |
dates |
character, factor, Date or POSIXct object with the dates corresponding to each element of |
date.fmt |
character indicating the format in which the dates are stored in dates, e.g. %Y-%m-%d. See ‘Details’ section in |
a zoo object, with values given by x and time stamps given by dates
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
## ## Example1: creating daily data # Generating a numeric variable (e.g., read from the outputs of an hydrological model) x <- 1:31 # Generating the dates corresponding to the previous values dates <- dip("1961-01-01", "1961-01-31") ## Transforming from 'numeric' to 'zoo' class z <- vector2zoo(x, dates) ## ## Example2: creating hourly data # Generating a numeric variable x <- rnorm(7) # Generating hourly times since 17:00:00 up to 23:00:00 for 2012-Oct-15 dates <- ISOdatetime(2012, 10, 15, 17:23, 00, 0) ## Transforming from 'numeric' to 'zoo' class z <- vector2zoo(x, dates)## ## Example1: creating daily data # Generating a numeric variable (e.g., read from the outputs of an hydrological model) x <- 1:31 # Generating the dates corresponding to the previous values dates <- dip("1961-01-01", "1961-01-31") ## Transforming from 'numeric' to 'zoo' class z <- vector2zoo(x, dates) ## ## Example2: creating hourly data # Generating a numeric variable x <- rnorm(7) # Generating hourly times since 17:00:00 up to 23:00:00 for 2012-Oct-15 dates <- ISOdatetime(2012, 10, 15, 17:23, 00, 0) ## Transforming from 'numeric' to 'zoo' class z <- vector2zoo(x, dates)
Generic function for obtaining 52 weekly values of a zoo object, by applying any R function to ALL the values in the object belonging to each one of the 52 calendar weeks (starting on Monday).
weeklyfunction(x, ...) ## Default S3 method: weeklyfunction(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'zoo' weeklyfunction(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'data.frame' weeklyfunction(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d", out.type="data.frame", verbose=TRUE,...) ## S3 method for class 'matrix' weeklyfunction(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d", out.type="data.frame", verbose=TRUE,...)weeklyfunction(x, ...) ## Default S3 method: weeklyfunction(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'zoo' weeklyfunction(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, ...) ## S3 method for class 'data.frame' weeklyfunction(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d", out.type="data.frame", verbose=TRUE,...) ## S3 method for class 'matrix' weeklyfunction(x, FUN, na.rm=TRUE, na.rm.max=0, start="00:00:00", start.fmt= "%H:%M:%S", tz, dates=1, date.fmt="%Y-%m-%d", out.type="data.frame", verbose=TRUE,...)
x |
zoo, xts, data.frame or matrix object, with daily or monthly time series. |
FUN |
Function that will be applied to ALL the values in |
na.rm |
Logical. Should missing values be removed? |
na.rm.max |
Numeric in [0, 1]. It is used to define the maximum percentage of missing values allowed in each month to keep the weekly aggregated value in the output object of this function. In other words, if the percentage of missing values in a given month is larger or equal than |
start |
character, indicating the starting time used for aggregating sub-daily time series into daily ones. It MUST be provided in the format specified by It is useful when the daily values start at a time different from |
start.fmt |
character indicating the format in which the time is provided in |
tz |
character, with the specification of the time zone used in both |
dates |
It is only used when |
date.fmt |
It is only used when |
out.type |
It is only used when |
verbose |
Logical; if TRUE, progress messages are printed |
... |
further arguments passed to or from other methods |
When x is a zoo object, a numeric vector with 12 elements representing the computed monthly value for each month.
When x is a data.frame which columns represent measurements at different gauging stations, the resulting object is a data.frame with 12 columns and as many rows as gauging stations are in x, each row storing the computed 12 monthly value for each gauging station.
Due to the fact that FUN is applied over all the elements in x belonging to a given calendar month, its result will depend on the sampling frequency of x and the type of function provided by FUN (special attention have to be put when FUN=sum)
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
annualfunction, seasonalfunction, dm2seasonal, daily2monthly, daily2annual
## Ex1: Computation of mean WEEKLY values from DAILY ts, removing any missing value in 'x' # Loading DAILY streamflows (3 years) at the station # Oca en Ona (Ebro River basin, Spain) data(OcaEnOnaQts) x <- OcaEnOnaQts ## Mean WEEKLY streamflows at station 'x' weeklyfunction(x, FUN=mean, na.rm=TRUE) ###################### ## Ex2: Computation of mean WEEKLY values from HOURLY ts, removing any missing value in 'x' # Loading HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts ## Mean WEEKLY streamflows at station 'x'. Each day starts at 00:00:00 weeklyfunction(x, FUN=mean, na.rm=TRUE) ###################### ## Ex3: Computation of mean WEEKLY values from HOURLY ts, removing any missing value in 'x' ## and starting each day at 08:00:00 # Loading HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts ## Mean WEEKLY streamflows at station 'x'. Each day starts at 00:00:00 weeklyfunction(x, FUN=mean, na.rm=TRUE, start="00:00:00")## Ex1: Computation of mean WEEKLY values from DAILY ts, removing any missing value in 'x' # Loading DAILY streamflows (3 years) at the station # Oca en Ona (Ebro River basin, Spain) data(OcaEnOnaQts) x <- OcaEnOnaQts ## Mean WEEKLY streamflows at station 'x' weeklyfunction(x, FUN=mean, na.rm=TRUE) ###################### ## Ex2: Computation of mean WEEKLY values from HOURLY ts, removing any missing value in 'x' # Loading HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts ## Mean WEEKLY streamflows at station 'x'. Each day starts at 00:00:00 weeklyfunction(x, FUN=mean, na.rm=TRUE) ###################### ## Ex3: Computation of mean WEEKLY values from HOURLY ts, removing any missing value in 'x' ## and starting each day at 08:00:00 # Loading HOURLY streamflows for the station Karamea at Gorge data(KarameaAtGorgeQts) x <- KarameaAtGorgeQts ## Mean WEEKLY streamflows at station 'x'. Each day starts at 00:00:00 weeklyfunction(x, FUN=mean, na.rm=TRUE, start="00:00:00")
Given any starting and ending dates, it generates:
1) a vector of class Date with all the years between the two dates (both of them included), OR
2) the amount of years between the two dates
yip(from, to, date.fmt = "%Y-%m-%d", out.type = "seq")yip(from, to, date.fmt = "%Y-%m-%d", out.type = "seq")
from |
Character indicating the starting date for creating the sequence. It has to be in the format indicated by |
to |
Character indicating the ending date for creating the sequence. It has to be in the format indicated by |
date.fmt |
character indicating the format in which the dates are stored in |
out.type |
Character indicating the type of result that is given by this function. Valid values are: |
Depending on the value of out.type, it returns:
1) seq : a vector of class Date with all the years between from and to (both of them included), OR
2) nmbr: a single numeric value with the amount of years between the two dates.
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
# Sequence of monthly dates between "1961-01-01" and "1961-12-31" yip("1961-01-01", "1961-12-31") ## Computing the number of years between 1961 and 1975, ## by using "%d-%m-%Y" as date format ## yip("01-01-1961", "01-01-1975", date.fmt= "%d-%m-%Y", out.type = "nmbr")# Sequence of monthly dates between "1961-01-01" and "1961-12-31" yip("1961-01-01", "1961-12-31") ## Computing the number of years between 1961 and 1975, ## by using "%d-%m-%Y" as date format ## yip("01-01-1961", "01-01-1975", date.fmt= "%d-%m-%Y", out.type = "nmbr")
It creates the input file to the 'RHtest_dlyPrcp.r' script, used for testing the homogeneity of climatological time series (available at: https://etccdi.pacificclimate.org/software.shtml)
zoo2RHtest(x, fname="pcp.txt", tstep.out="daily", dec=".", na="-999.0")zoo2RHtest(x, fname="pcp.txt", tstep.out="daily", dec=".", na="-999.0")
x |
time series that will be written. class(x) must be a zoo object |
fname |
Character, with the filename of the precipitation time series |
tstep.out |
Character indicating the time step that have to be used for writing |
dec |
the string to use for decimal points in numeric or complex columns: must be a single character. |
na |
character to be used for representing the missing values in the data |
Mauricio Zambrano-Bigiarini, mzb.devel@gmail
https://etccdi.pacificclimate.org/software.shtml https://etccdi.pacificclimate.org/RHtest/RHtestsV4_UserManual_10Dec2014.pdf
## Loading the SanMartino precipitation data data(SanMartinoPPts) x <- SanMartinoPPts #Getting the monthly ts pcp.m <- daily2monthly(x, FUN=sum, na.rm=FALSE) ## Not run: # From zoo to the input format required by 'FindU.dlyPrcp' function zoo2RHtest(x=pcp.m, fname="pcp-monthly.txt", tstep.out="monthly", na="-999.0") # Homogeneity analysis FindU.dlyPrcp(InSeries="pcp-monthly.txt", output="pcp-monthly", MissingValueCode="-999.0", GUI=FALSE, pthr=0, Mq=10, p.lev=0.95, Iadj=10000) ## End(Not run)## Loading the SanMartino precipitation data data(SanMartinoPPts) x <- SanMartinoPPts #Getting the monthly ts pcp.m <- daily2monthly(x, FUN=sum, na.rm=FALSE) ## Not run: # From zoo to the input format required by 'FindU.dlyPrcp' function zoo2RHtest(x=pcp.m, fname="pcp-monthly.txt", tstep.out="monthly", na="-999.0") # Homogeneity analysis FindU.dlyPrcp(InSeries="pcp-monthly.txt", output="pcp-monthly", MissingValueCode="-999.0", GUI=FALSE, pthr=0, Mq=10, p.lev=0.95, Iadj=10000) ## End(Not run)