rtime-seriesforecastingdecompositiontrend

Flatten or detrend a seasonal time series


I have a repeating time series with a seasonal (weekly) pattern, and I'd like to return the same time series with no week-over-week trend, taking the first value as a starting point.

To be specific, the 1st value will still be 39.8, but the 8th value will also be 39.8 rather than 17.1. If the first seven values were just repeated then there would be a week-long negative trend repeated and I'd like to have no trend at all (so the 7th value of 6.2 would also be higher).

Is there an elegant way to do this, especially one that is robust to zero-valued entries in a time-series (I have a lot of them)?

We can assume the time series trend is linear and constant (i.e. not just piecewise linear).

demand <- ts(
  c(39.8, 33.5, 40.6, 23.6, 11.9, 12.3, 6.2, 17.1, 10.8, 18, 1, -10.7, 
-10.4, -16.5, -5.6, -11.9, -4.7, -21.7, -33.4, -33.1, -39.2, -28.2, 
-34.6, -27.4, -44.4, -56.1, -55.7, -61.8, -50.9, -57.2, -50.1),
frequency = 7
)

plot(demand)

demand trend


Solution

  • You can do something like this:

    trend = stl(demand, s.window = "periodic")$time.series[,2]
    
    detrend_ts = demand - (trend - trend[1])
    
    plot(detrend_ts)
    

    Result:

    > detrend_ts
    Time Series:
    Start = c(1, 1) 
    End = c(5, 3) 
    Frequency = 7 
     [1] 39.80000 36.72792 47.05584 33.28224 24.80864 28.43514 25.56165 39.69889 36.63614
    [10] 47.08241 33.32868 24.86478 28.40088 25.53956 39.67825 36.63383 47.08942 33.32204
    [19] 24.85466 28.38747 25.52029 39.76777 36.61526 47.05556 33.29586 24.82129 28.44673
    [28] 25.57045 39.69417 36.61948 46.94480
    

    enter image description here

    Notes:

    Basically, I used STL decomposition (Seasonal Decomposition of Time Series by Loess) to estimate the trend, then subtracted it from demand. Since you wanted the de-trended time series to start at 39.8, I also subtracted the first value of the trend from trend.