3.3 Moving averages
The classical method of time series decomposition originated in the 1920s and was widely used until the 1950s. It still forms the basis of many time series decomposition methods, so it is important to understand how it works. The first step in a classical decomposition is to use a moving average method to estimate the trend-cycle, so we begin by discussing moving averages.
Moving average smoothing
A moving average of order \(m\) can be written as \[\begin{equation} \hat{T}_{t} = \frac{1}{m} \sum_{j=-k}^k y_{t+j}, \tag{3.2} \end{equation}\] where \(m=2k+1\). That is, the estimate of the trend-cycle at time \(t\) is obtained by averaging values of the time series within \(k\) periods of \(t\). Observations that are nearby in time are also likely to be close in value. Therefore, the average eliminates some of the randomness in the data, leaving a smooth trend-cycle component. We call this an \(m\)-MA, meaning a moving average of order \(m\).
For example, consider Figure 3.9 which shows exports of goods and services for Australia as a percentage of GDP from 1960 to 2017. The data are also shown in Table 3.1.
global_economy |>
filter(Country == "Australia") |>
autoplot(Exports) +
labs(y = "% of GDP", title = "Total Australian exports")

Figure 3.9: Australian exports of goods and services: 1960–2017.
Year | Exports | 5-MA |
---|---|---|
1960 | 12.99 | |
1961 | 12.40 | |
1962 | 13.94 | 13.46 |
1963 | 13.01 | 13.50 |
1964 | 14.94 | 13.61 |
1965 | 13.22 | 13.40 |
1966 | 12.93 | 13.25 |
1967 | 12.88 | 12.66 |
… | … | … |
2010 | 19.84 | 21.21 |
2011 | 21.47 | 21.17 |
2012 | 21.52 | 20.78 |
2013 | 19.99 | 20.81 |
2014 | 21.08 | 20.37 |
2015 | 20.01 | 20.32 |
2016 | 19.25 | |
2017 | 21.27 |
In the last column of this table, a moving average of order 5 is shown, providing an estimate of the trend-cycle. The first value in this column is the average of the first five observations, 1960–1964; the second value in the 5-MA column is the average of the values for 1961–1965; and so on. Each value in the 5-MA column is the average of the observations in the five year window centred on the corresponding year. In the notation of Equation (3.2), column 5-MA contains the values of \(\hat{T}_{t}\) with \(k=2\) and \(m=2k+1=5\). There are no values for either the first two years or the last two years, because we do not have two observations on either side. Later we will use more sophisticated methods of trend-cycle estimation which do allow estimates near the endpoints.
This is easily computed using slide_dbl()
from the slider
package which applies a function to “sliding” time windows. In this case, we use the mean()
function with a window of size 5.
aus_exports <- global_economy |>
filter(Country == "Australia") |>
mutate(
`5-MA` = slider::slide_dbl(Exports, mean,
.before = 2, .after = 2, .complete = TRUE)
)
To see what the trend-cycle estimate looks like, we plot it along with the original data in Figure 3.10.
aus_exports |>
autoplot(Exports) +
geom_line(aes(y = `5-MA`), colour = "#D55E00") +
labs(y = "% of GDP",
title = "Total Australian exports") +
guides(colour = guide_legend(title = "series"))

Figure 3.10: Australian exports (black) along with the 5-MA estimate of the trend-cycle (orange).
Notice that the trend-cycle (in orange) is smoother than the original data and captures the main movement of the time series without all of the minor fluctuations. The order of the moving average determines the smoothness of the trend-cycle estimate. In general, a larger order means a smoother curve. Figure 3.11 shows the effect of changing the order of the moving average for the Australian exports data.

Figure 3.11: Different moving averages applied to the Australian exports data.
Simple moving averages such as these are usually of an odd order (e.g., 3, 5, 7, etc.). This is so they are symmetric: in a moving average of order \(m=2k+1\), the middle observation, and \(k\) observations on either side, are averaged. But if \(m\) was even, it would no longer be symmetric.
Moving averages of moving averages
It is possible to apply a moving average to a moving average. One reason for doing this is to make an even-order moving average symmetric.
For example, we might take a moving average of order 4, and then apply another moving average of order 2 to the results. In the following table, this has been done for the first few years of the Australian quarterly beer production data.
beer <- aus_production |>
filter(year(Quarter) >= 1992) |>
select(Quarter, Beer)
beer_ma <- beer |>
mutate(
`4-MA` = slider::slide_dbl(Beer, mean,
.before = 1, .after = 2, .complete = TRUE),
`2x4-MA` = slider::slide_dbl(`4-MA`, mean,
.before = 1, .after = 0, .complete = TRUE)
)
Quarter | Beer | 4-MA | 2x4-MA |
---|---|---|---|
1992 Q1 | 443.00 | ||
1992 Q2 | 410.00 | 451.25 | |
1992 Q3 | 420.00 | 448.75 | 450.00 |
1992 Q4 | 532.00 | 451.50 | 450.12 |
1993 Q1 | 433.00 | 449.00 | 450.25 |
1993 Q2 | 421.00 | 444.00 | 446.50 |
… | … | … | … |
2009 Q1 | 415.00 | 430.00 | 428.88 |
2009 Q2 | 398.00 | 430.00 | 430.00 |
2009 Q3 | 419.00 | 429.75 | 429.88 |
2009 Q4 | 488.00 | 423.75 | 426.75 |
2010 Q1 | 414.00 | ||
2010 Q2 | 374.00 |
The notation “\(2\times4\)-MA” in the last column means a 4-MA followed by a 2-MA. The values in the last column are obtained by taking a moving average of order 2 of the values in the previous column. For example, the first two values in the 4-MA column are 451.25=(443+410+420+532)/4 and 448.75=(410+420+532+433)/4. The first value in the 2x4-MA column is the average of these two: 450.00=(451.25+448.75)/2.
When a 2-MA follows a moving average of an even order (such as 4), it is called a “centred moving average of order 4”. This is because the results are now symmetric. To see that this is the case, we can write the \(2\times4\)-MA as follows: \[\begin{align*} \hat{T}_{t} &= \frac{1}{2}\Big[ \frac{1}{4} (y_{t-2}+y_{t-1}+y_{t}+y_{t+1}) + \frac{1}{4} (y_{t-1}+y_{t}+y_{t+1}+y_{t+2})\Big] \\ &= \frac{1}{8}y_{t-2}+\frac14y_{t-1} + \frac14y_{t}+\frac14y_{t+1}+\frac18y_{t+2}. \end{align*}\] It is now a weighted average of observations that is symmetric.
Other combinations of moving averages are also possible. For example, a \(3\times3\)-MA is often used, and consists of a moving average of order 3 followed by another moving average of order 3. In general, an even order MA should be followed by an even order MA to make it symmetric. Similarly, an odd order MA should be followed by an odd order MA.
Estimating the trend-cycle with seasonal data
The most common use of centred moving averages is for estimating the trend-cycle from seasonal data. Consider the \(2\times4\)-MA: \[ \hat{T}_{t} = \frac{1}{8}y_{t-2} + \frac14y_{t-1} + \frac14y_{t} + \frac14y_{t+1} + \frac18y_{t+2}. \] When applied to quarterly data, each quarter of the year is given equal weight as the first and last terms apply to the same quarter in consecutive years. Consequently, the seasonal variation will be averaged out and the resulting values of \(\hat{T}_t\) will have little or no seasonal variation remaining. A similar effect would be obtained using a \(2\times 8\)-MA or a \(2\times 12\)-MA to quarterly data.
In general, a \(2\times m\)-MA is equivalent to a weighted moving average of order \(m+1\) where all observations take the weight \(1/m\), except for the first and last terms which take weights \(1/(2m)\). So, if the seasonal period is even and of order \(m\), we use a \(2\times m\)-MA to estimate the trend-cycle. If the seasonal period is odd and of order \(m\), we use a \(m\)-MA to estimate the trend-cycle. For example, a \(2\times 12\)-MA can be used to estimate the trend-cycle of monthly data with annual seasonality and a 7-MA can be used to estimate the trend-cycle of daily data with a weekly seasonality.
Other choices for the order of the MA will usually result in trend-cycle estimates being contaminated by the seasonality in the data.
Example: Employment in the US retail sector
us_retail_employment_ma <- us_retail_employment |>
mutate(
`12-MA` = slider::slide_dbl(Employed, mean,
.before = 5, .after = 6, .complete = TRUE),
`2x12-MA` = slider::slide_dbl(`12-MA`, mean,
.before = 1, .after = 0, .complete = TRUE)
)
us_retail_employment_ma |>
autoplot(Employed, colour = "gray") +
geom_line(aes(y = `2x12-MA`), colour = "#D55E00") +
labs(y = "Persons (thousands)",
title = "Total employment in US retail")

Figure 3.12: A 2x12-MA applied to the US retail employment series.
Figure 3.12 shows a \(2\times12\)-MA applied to the total number of persons employed in the US retail sector. Notice that the smooth line shows no seasonality; it is almost the same as the trend-cycle shown in Figure 3.6, which was estimated using a much more sophisticated method than a moving average. Any other choice for the order of the moving average (except for 24, 36, etc.) would have resulted in a smooth line that showed some seasonal fluctuations.
Weighted moving averages
Combinations of moving averages result in weighted moving averages. For example, the \(2\times4\)-MA discussed above is equivalent to a weighted 5-MA with weights given by \(\left[\frac{1}{8},\frac{1}{4},\frac{1}{4},\frac{1}{4},\frac{1}{8}\right]\). In general, a weighted \(m\)-MA can be written as \[ \hat{T}_t = \sum_{j=-k}^k a_j y_{t+j}, \] where \(k=(m-1)/2\), and the weights are given by \(\left[a_{-k},\dots,a_k\right]\). It is important that the weights all sum to one and that they are symmetric so that \(a_j = a_{-j}\). The simple \(m\)-MA is a special case where all of the weights are equal to \(1/m\).
A major advantage of weighted moving averages is that they yield a smoother estimate of the trend-cycle. Instead of observations entering and leaving the calculation at full weight, their weights slowly increase and then slowly decrease, resulting in a smoother curve.