Generalisation of Nash-Sutcliffe Efficiency (R Squared) as a fit statistic for time series.
nseStat(
obs,
mod,
ref = NULL,
...,
p = 2,
trans = NULL,
negatives.ok = FALSE,
na.action = na.pass
)
observed data vector.
model-predicted data vector corresponding to obs
.
reference model predictions corresponding to obs
. If
NULL
, ref
is taken as the mean of obs
after applying
any transformation (trans
).
ignored.
power to apply to absolute residuals (abs(obs - mod)
and
abs(obs - ref)
. The default, p = 2
corresponds to the
Nash-Sutcliffe Efficiency (NSE). Setting p = 1
does not square the
residuals and is sometimes called Normalised sum of Absolute Errors (NAE).
a function to apply to each data series before calculating the fit statistic.
if FALSE
, the default case, all values in
obs
, mod
and ref
are constrained to be non-negative;
i.e. negative values are replaced with zero.
a function to apply to the time series, which is expected to fill in or remove missing values (note, this is optional).
a single numeric value.
The result is, after transformation of variables,
$$1 - sum(abs(obs-mod)^p) / sum(abs(obs-ref)^p)$$
A perfect fit gives a value of 1 and a fit equivalent to the reference model gives a value of 0. Values less than 0 are worse than the reference model.
If the arguments obs
, mod
or ref
are not plain vectors,
nseStat
will attempt to merge them together, so that corresponding
time steps are compared to each other even if the time windows are not
equal.
## generate some data -- it is autocorrelated so the use of these
## stats is somewhat problematic!
set.seed(0)
U <- ts(pmax(0, rgamma(200, shape = 0.1, scale = 20) - 5))
## simulate error as multiplicative uniform random
Ue <- U * runif(200, min = 0.5, max = 1.5)
## and resample 10 percent of time steps
ii <- sample(seq_along(U), 20)
Ue[ii] <- rev(U[ii])
## apply recursive filter
Q <- filter(U, 0.7, method = "r")
X <- filter(Ue, 0.75, method = "r")
## convert to 'zoo' objects with Date index
Q <- zoo(Q, as.Date("2000-01-01") + 1:200)
X <- zoo(X, time(Q))
xyplot(merge(Q, X), superpose = TRUE)
nseStat(Q, X)
#> [1] 0.7717829
nseStat(Q, X, trans = sqrt)
#> [1] 0.7659478
nseStat(Q, X, trans = function(x) log(x + 1))
#> [1] 0.7479644
## use absolute residuals rather than squared residuals
nseStat(Q, X, p = 1)
#> [1] 0.5564602
## use a different reference model (one-step-ahead forecast)
nseStat(Q, X, ref = lag(Q, -1))
#> [1] 0.6718251
## reference as seasonal averages rather than overall average
nseStat(Q, X, ref = ave(Q, months(time(Q))))
#> [1] 0.7534322
## see how the reference model performs in terms of R Squared
nseStat(Q, ave(Q, months(time(Q))))
#> [1] 0.0744246