Skip to contents

The loadflex package lets you quickly fit and compare concentrations and/or fluxes of solutes in watersheds. This vignette demonstrates the application of loadflex to fit four different model types to the same data, to assess and compare those models, and to estimate average solute concentrations and fluxes at both quarter-hourly and monthly scales.

We will use the data supplied with the loadflex package. These include nitrate concentration observations from the Lamprey River in southeastern New Hampshire, where researchers in the NH Water Resources Research Center (University of New Hampshire; PI: William H. McDowell) have been monitoring water quality weekly since 1999. Discharge data are from the same location, Packers Falls, from a USGS gaging station (https://waterdata.usgs.gov/monitoring-location/USGS-01073500).

Start by loading the package.

Load the data provided in this package.

# Interpolation data: Packers Falls NO3 grab sample observations
data(lamprey_nitrate)
intdat <- lamprey_nitrate[c("DATE","DISCHARGE","NO3")]

# Calibration data: Restrict to points separated by sufficient time
regdat <- subset(lamprey_nitrate, REGR)[c("DATE","DISCHARGE","NO3")]

# Estimation data: Packers Falls discharge
data(lamprey_discharge)
estdat <- subset(lamprey_discharge, DATE < as.POSIXct("2012-10-01 00:00:00", tz="EST5EDT"))
estdat <- estdat[seq(1, nrow(estdat), by=96/4),] # pare to 4 obs/day for speed

Create a metadata description of the dataset & desired output.

meta <- metadata(constituent="NO3", flow="DISCHARGE", 
  dates="DATE", conc.units="mg L^-1", flow.units="cfs", load.units="kg", 
  load.rate.units="kg d^-1", site.name="Lamprey River, NH",
  consti.name="Nitrate", site.id='01073500', lat=43.10259, lon=-70.95256)

Fit four models: interpolation, linear, rloadest, and composite. Many variants on these models are possible. For example: loadInterp models may use any of several interp.fun options; see ?interpolations. loadLm accepts any linear model acceptable to lm(), not just the very simple formula we have used here. loadReg2 functions are also flexible as specified in the documentation for . loadComp models accept a linear model as fit by either loadLm or loadReg2 and any of the interp.fun options available to loadInterp.

no3_li <- loadInterp(interp.format="conc", interp.fun=rectangularInterpolation, 
  data=intdat, metadata=meta)
no3_lm <- loadLm(formula=log(NO3) ~ log(DISCHARGE), pred.format="conc", 
  data=regdat, metadata=meta, retrans=exp)
library(rloadest)
no3_lr <- loadReg2(loadReg(NO3 ~ model(9), data=regdat,
  flow="DISCHARGE", dates="DATE", time.step="instantaneous", 
  flow.units="cfs", conc.units="mg/L", load.units="kg",
  station='Lamprey River, NH'))
no3_lc <- loadComp(reg.model=no3_lr, interp.format="conc", 
  interp.data=intdat, store = "uncertainty")

You can inspect these models in a variety of model-specific ways. Here are some commands to try (we won’t print them here because the output can be lengthy):

Now generate point predictions from each model.

preds_li <- predictSolute(no3_li, "flux", estdat, se.pred=TRUE)
## Warning in regularize.values(x, y, ties, missing(ties), na.rm = na.rm): collapsing to unique 'x' values
preds_lm <- predictSolute(no3_lm, "flux", estdat, se.pred=TRUE, lin.or.log="linear")
preds_lr <- predictSolute(no3_lr, "flux", estdat, se.pred=TRUE)
preds_lc <- predictSolute(no3_lc, "flux", estdat, se.pred=TRUE)

A few lines from one of the resulting prediction data.frames:

head(preds_lr)
##                  date     flux  se.pred
## 1 1999-10-01 01:00:00 15.72780 4.722913
## 2 1999-10-01 07:00:00 16.68311 5.010515
## 3 1999-10-01 13:00:00 17.39594 5.225214
## 4 1999-10-01 19:00:00 16.94764 5.090053
## 5 1999-10-02 01:00:00 16.72981 5.024355
## 6 1999-10-02 07:00:00 16.51078 4.958313

Here are a few ways to inspect the models:

summary(getFittedModel(no3_lm))
ggplot2::qplot(x=Date, y=Resid, data=getResiduals(no3_li, newdata=intdat))
residDurbinWatson(no3_lr, "conc", newdata=regdat, irreg=TRUE)
residDurbinWatson(no3_lr, "conc", newdata=intdat, irreg=TRUE)
estimateRho(no3_lr, "conc", newdata=regdat, irreg=TRUE)$rho
estimateRho(no3_lr, "conc", newdata=intdat, irreg=TRUE)$rho
getCorrectionFraction(no3_lc, "flux", newdat=intdat)

The loadflex process for aggregation of point predictions (to monthly, annual, etc.) has changed since we published our 2015 manuscript. aggregateSolute from that manuscript is no longer exported as a function in loadflex. Instead, you can use the agg.by argument to predictSolute to generate predictions at the time interval of interest. You can aggregate for for months, water years, calendar years, or other time intervals, and for mean concentration (named conc in the output) or flux (flux.rate in the output, using “rate” to remind users that the time denominator does not change regardless of the time period being aggregated over). Standard errors (se.fit and se.pred) are available for loadReg2 models. The units of the aggregated output are what you passed into each model as metadata. count reports the number of observations going into the aggregated estimate in each row. Some examples:

getUnits(getMetadata(no3_lr), 'conc')
## [1] "mg L^-1"
agg_c_li <- predictSolute(no3_li, "conc", newdata=estdat, agg.by="month")
## Warning in regularize.values(x, y, ties, missing(ties), na.rm = na.rm): collapsing to unique 'x' values
agg_c_lm <- predictSolute(no3_lm, "conc", newdata=estdat, agg.by="water year")
agg_c_lr <- predictSolute(no3_lr, "conc", newdata=estdat, agg.by="unit", se.fit=TRUE, se.pred=TRUE)
agg_c_lc <- predictSolute(no3_lc, "conc", newdata=estdat, agg.by="day")

getUnits(getMetadata(no3_lr), 'flux rate')
## [1] "kg d^-1"
agg_f_li <- predictSolute(no3_li, "flux", newdata=estdat, agg.by="month")
## Warning in regularize.values(x, y, ties, missing(ties), na.rm = na.rm): collapsing to unique 'x' values
agg_f_lm <- predictSolute(no3_lm, "flux", newdata=estdat, agg.by="water year")
agg_f_lr <- predictSolute(no3_lr, "flux", newdata=estdat, agg.by="calendar year", se.fit=TRUE, se.pred=TRUE)
agg_f_lc <- predictSolute(no3_lc, "flux", newdata=estdat, agg.by="day")

A few lines from each of the resulting aggregated flux data.frames:

head(agg_c_li)
##     month       conc count
## 1 1999-10 0.08495235   124
## 2 1999-11 0.10463500   120
## 3 1999-12 0.11101811   124
## 4 2000-01 0.15563200   124
## 5 2000-02 0.19444202   116
## 6 2000-03 0.10493360   124
head(agg_c_lm)
##   water.year      conc count
## 1       2000 0.1617367  1464
## 2       2001 0.1671824  1460
## 3       2002 0.1728231  1460
## 4       2003 0.1647539  1460
## 5       2004 0.1615283  1464
## 6       2005 0.1610110  1460
head(agg_c_lr)
##                  date      conc      se.fit    se.pred
## 1 1999-10-01 01:00:00 0.1108355 0.006947463 0.03328288
## 2 1999-10-01 07:00:00 0.1099827 0.006917092 0.03303161
## 3 1999-10-01 13:00:00 0.1093890 0.006898088 0.03285714
## 4 1999-10-01 19:00:00 0.1099532 0.006918008 0.03302332
## 5 1999-10-02 01:00:00 0.1102905 0.006930643 0.03312284
## 6 1999-10-02 07:00:00 0.1106310 0.006943621 0.03322333
head(agg_c_lc)
##          day       conc count
## 1 1999-10-01 0.09380781     4
## 2 1999-10-02 0.09420547     4
## 3 1999-10-03 0.09386919     4
## 4 1999-10-04 0.09429498     4
## 5 1999-10-05 0.09147071     4
## 6 1999-10-06 0.08982873     4
head(agg_f_li)
##     month flux.rate count
## 1 1999-10  36.25767   124
## 2 1999-11  61.72640   120
## 3 1999-12  75.05153   124
## 4 2000-01 100.70306   124
## 5 2000-02 124.53199   116
## 6 2000-03 214.33387   124
head(agg_f_lm)
##   water.year flux.rate count
## 1       2000 109.80382  1464
## 2       2001  90.77553  1460
## 3       2002  53.84619  1460
## 4       2003  98.73848  1460
## 5       2004 115.79976  1464
## 6       2005 132.08674  1460
head(agg_f_lr)
##   calendar.year count.days flux.rate   se.fit  se.pred
## 1          1999         92        NA       NA       NA
## 2          2000        366  81.59340 3.874249 1.942207
## 3          2001        365  61.36536 2.507505 1.799239
## 4          2002        365  63.47885 1.626333 1.380100
## 5          2003        365 105.40671 2.806397 2.293839
## 6          2004        366 103.29017 2.723026 2.294192
head(agg_f_lc)
##          day flux.rate count
## 1 1999-10-01  14.22684     4
## 2 1999-10-02  14.23201     4
## 3 1999-10-03  14.98515     4
## 4 1999-10-04  14.99027     4
## 5 1999-10-05  18.39978     4
## 6 1999-10-06  19.22265     4