The majority of studies focus on detection of linear or monotonic trends, using
typically under the assumption of uncorrelated data.
There exist two main problems:
These problems can be addressed by using tests for non-monotonic trends assuming that observations can be autocorrelated.
set.seed(777)
<- 100
n <- c(1:n)
Time <- arima.sim(list(order = c(1, 0, 0), ar = 0.5), n = n, n.start = 100, sd = 0.5)
X0 <- 2*Time/n + X0
X1 <- 2*(Time/n)^0.5 + X0
X2 <- 0.5*(Time - n/2)/n - 6*((Time - n/2)/n)^2 + X0
X3 <- as.data.frame(cbind(X0, X1, X2, X3)) X
The time series above were simulated:
A) X1
with linear trend,
B) X2
with square root – nonlinear monotonic – trend, and
C) X3
with quadratic – nonlinear non-monotonic – trend,
with stationary autocorrelated innovations X0
: \(X0_t = 0.5X0_{t-1} + e_t\), where \(e_t \sim N(0, 0.5^2)\).
Let’s test these time series using the functions from package funtimes
, using significance level \(\alpha = 0.05\).
To install and load the package, run
install.packages("funtimes")
library(funtimes)
Function notrend_test
tests the null hypothesis of no trend against different alternatives defined by the corresponding tests.
Consider the following pair of hypotheses
\(H_0\): no trend
\(H_1\): linear trend
that can be tested specifically using t-test.
Assuming the time series may be autocorrelated (which is the usual case with observational data), we apply sieve-bootstrap version of the t-test, by adapting the approach of Noguchi, Gel, and Duguay (2011):
notrend_test(X0)
#
# Sieve-bootstrap Student's t-test for a linear trend
#
# data: X0
# Student's t value = -2.6429, p-value = 0.098
# alternative hypothesis: linear trend.
# sample estimates:
# $AR_order
# [1] 1
#
# $AR_coefficients
# phi_1
# 0.4212756
The large \(p\)-value correctly indicates that there is not enough evidence to reject the hypothesis of no trend in X0
in favor of the alternative hypothesis of a linear trend.
For the other time series, \(p\)-values are reported below:
apply(X[,-1], 2, function(x) notrend_test(x)$p.value)
# X1 X2 X3
# 0.000 0.002 0.858
indicating that the null hypothesis of no trend could be rejected and hypothesis of a linear trend could be accepted for X1
and X2
. While X3
has a trend (based on the way it was simulated and the time series plot above), the alternative hypothesis of a linear trend does not fit in this case, so the test for linear trend (t-test) failed to reject the null hypothesis.
Since a linear trend is also a monotonic trend, we may expect seeing similar results when testing the following pair of hypotheses
\(H_0\): no trend
\(H_1\): monotonic trend
using Mann–Kendall test.
Apply Mann–Kendall test, also with the sieve-bootstrap enhancement for potentially autocorrelated data; \(p\)-values are shown below:
apply(X, 2, function(x) notrend_test(x, test = "MK")$p.value)
# X0 X1 X2 X3
# 0.057 0.000 0.000 0.929
indicating that the null hypothesis of no trend could be rejected and hypothesis of a monotonic trend could be accepted for X1
and X2
. For X0
and X3
, the null hypothesis could not be rejected, because X0
does not have a trend, and X3
has a trend that does not match the alternative hypothesis.
If the interest is in testing for any, potentially non-monotonic trend, consider testing the following pair of hypotheses
\(H_0\): no trend
\(H_1\): any trend
using local regression-based WAVK test (Wang, Akritas, and Van Keilegom 2008).
Apply WAVK test, also with the sieve-bootstrap enhancement for potentially autocorrelated data:
apply(X, 2, function(x) notrend_test(x, test = "WAVK",
factor.length = "adaptive.selection")$p.value)
# X0 X1 X2 X3
# 0.337 0.000 0.026 0.004
The results indicate that WAVK test was correct in non-rejecting the null hypothesis for X0
, and correctly rejected it for the time series with trends X1
, X2
, and X3
.
Lyubchich, Gel, and El-Shaarawi (2013) originally implemented hybrid bootstrap to this test statistic, available from the wavk_test
function described in the next section.
Function wavk_test
is developed for the following goodness-of-fit question (Lyubchich, Gel, and El-Shaarawi 2013):
\(H_0\): trend is of form \(f(\theta,t)\)
\(H_1\): trend is not of form \(f(\theta,t)\)
where \(f\) belongs to a known family of smooth parametric functions, and \(\theta\) are its parameters.
Note Considering \(f(\theta,t)\) being some polynomial function, non-rejection of the null hypothesis means that function \(f(\theta,t)\) or its simpler form (lower-order polynomial) is sufficient for describing the trend in the tested time series.
Note The case of \(f(\theta,t) \equiv 0\) corresponds to testing for no trend (in other words, for a constant trend, same as in the previous section), and the following code differs only in the type of bootstrap used,
notrend_test
(WAVK statistic is calculated on original time series and simulated autoregressive series) andwavk_test
(WAVK statistic is calculated on time series after the trend \(f(\theta,t)\) and autoregressive dependence are removed, and on simulated independent normal series)notrend_test(X0, test = "WAVK", factor.length = "adaptive.selection") # WAVK with sieve bootstrap
#
# Sieve-bootstrap WAVK trend test
#
# data: X0
# WAVK test statistic = 8.7024, moving window = 4, p-value = 0.37
# alternative hypothesis: (non-)monotonic trend.
# sample estimates:
# $AR_order
# [1] 1
#
# $AR_coefficients
# phi_1
# 0.4212756
wavk_test(X0 ~ 0, factor.length = "adaptive.selection") # WAVK with hybrid bootstrap
#
# Trend test by Wang, Akritas, and Van Keilegom (bootstrap p-values)
#
# data: X0
# WAVK test statistic = 0.30965, adaptively selected window = 4, p-value
# = 0.632
# alternative hypothesis: trend is not of the form X0 ~ 0.
To test a linear trend \(f(\theta,t) = \theta_0 + \theta_1 t\), use
wavk_test(X0 ~ t, factor.length = "adaptive.selection")
#
# Trend test by Wang, Akritas, and Van Keilegom (bootstrap p-values)
#
# data: X0
# WAVK test statistic = -0.085378, adaptively selected window = 4,
# p-value = 0.98
# alternative hypothesis: trend is not of the form X0 ~ t.
Note that the time sequence t
is specified automatically within the function.
For the other time series, \(p\)-values are shown below:
apply(X[,-1], 2, function(x) wavk_test(x ~ t, factor.length = "adaptive.selection")$p.value)
# X1 X2 X3
# 0.954 0.786 0.020
The function poly
could also be used, for example, test quadratic trend \(f(\theta,t) = \theta_0 + \theta_1 t + \theta_2 t^2\) and show the trend estimates using the argument out = TRUE
:
wavk_test(X3 ~ poly(t, 2), factor.length = "adaptive.selection", out = TRUE)
#
# Trend test by Wang, Akritas, and Van Keilegom (bootstrap p-values)
#
# data: X3
# WAVK test statistic = -0.097613, adaptively selected window = 4,
# p-value = 0.896
# alternative hypothesis: trend is not of the form X3 ~ poly(t, 2).
# sample estimates:
# $trend_coefficients
# (Intercept) poly(t, 2)1 poly(t, 2)2
# -0.4860421 -0.2358495 -4.7102192
#
# $AR_order
# [1] 1
#
# $AR_coefficients
# phi_1
# 0.4193298
#
# $all_considered_windows
# Window WAVK-statistic p-value
# 4 -0.09761277 0.896
# 5 -0.47737630 0.816
# 7 -0.47880434 0.860
# 10 -0.12694875 0.780
This vignette belongs to R package funtimes
. If you wish to cite this page, please cite the package:
citation("funtimes")
#
# To cite package 'funtimes' in publications use:
#
# Vyacheslav Lyubchich and Yulia R. Gel (2022). funtimes: Functions for
# Time Series Analysis. R package version 8.2.
#
# A BibTeX entry for LaTeX users is
#
# @Manual{,
# title = {funtimes: Functions for Time Series Analysis},
# author = {Vyacheslav Lyubchich and Yulia R. Gel},
# year = {2022},
# note = {R package version 8.2},
# }