Piecewise linear trends
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
I prepared the following notes for a consulting client, and I thought they might be of interest to some other people too.
Let yt denote the value of the time series at time t, and suppose we wish to fit a trend with correlated errors of the form
yt=f(t)+nt,
For example, if f(t)=β0+β1t is a linear function, then we can simply set x1,t=t and define
yt=β0+β1x1,t+nt.xreg
argument in auto.arima
.
This model can be estimated by setting the xreg
argument to be a matrix with one column:
X=[1234⋮T]
x1 <- 1:length(y) fit <- auto.arima(y, xreg=x1)
The associated coefficient is the slope of the trend line.
Here is a simple example of a linear trend fitted to the Asian sheep data from the fpp
package :
library(fpp) T <- length(livestock) x1 <- seq(T) fit <- auto.arima(livestock, xreg=x1) fc <- forecast(fit, xreg=T+seq(10)) b0 <- coef(fit)["intercept"] b1 <- coef(fit)["x1"] t <- seq(T+10) trend <- ts(b0 + b1*t, start=start(livestock)) plot(fc, main="Linear trend with AR(1) errors") lines(trend, col='red')

Figure 1: A linear trend fitted to the Asian sheep data. The automatically selected error term is an AR(1) process.
A more flexible approach is to use a piecewise linear trend which bends at some time. If the trend bends at time τ, then it can be specified by including the following predictors in the model.
x1,t=tx2,t={0t<τ;(t−τ)t≥τ.auto.arima
, set xreg
to be a matrix with two columns:
X=[10203040⋮τ0τ+11τ+22⋮TT−τ]
fit <- auto.arima(y, xreg=cbind(x1, pmax(0,x1-tau))
If the associated coefficients of x1,t and x2,t are β1 and β2, then β1 gives the slope of the trend before time τ, while the slope of the line after time τ is given by β1+β2.
This can be extended to allow any number of “bend points” known as knots. Just add additional columns with 0s before each knot, and values 1, 2, … after the knot.
Here is a piecewise linear trend fitted to the Asian sheep data with knots at years 1990 and 1992:
x2 <- pmax(0, x1-30) x3 <- pmax(0, x1-32) fit <- auto.arima(livestock, xreg=cbind(x1,x2,x3)) fc <- forecast(fit, xreg=cbind(max(x1)+seq(10), max(x2)+seq(10), max(x3)+seq(10))) b0 <- coef(fit)["intercept"] b1 <- coef(fit)["x1"] b2 <- coef(fit)["x2"] b3 <- coef(fit)["x3"] trend <- ts(b0 + b1*t + b2*pmax(0,t-30) + b3*pmax(0,t-32), start=start(livestock)) plot(fc, main="Piecewise linear trend with AR(1) errors") lines(trend, col='red')

Figure 2: A piecewise-linear trend fitted to the Asian sheep data.
If there is to be no trend before the first knot, but a piecewise linear trend thereafter, leave out the first column of the above matrix X.
If there is to be a piecewise linear trend up to the last knot, but no trend thereafter, a slightly modified set up can be used. For one knot at time τ, we can set
X=[1−τ2−τ⋮−2−100⋮0]
xreg <- pmin(0, x1-tau)
where the first 0 in the column is in row τ. Additional knots can be handled in the same way. For example, if there are two knots, then β1+β2 will be the slope of the trend up to the first knot, and β2 will be the slope between the first and second knots.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.