Time Series and Moving Average with R

Changhyun Kim
6 min readDec 24, 2022

--

We come across a lot of time series data in our life. Stock prices, annual retail sales, rainfall measurements by hour and heart rate monitoring are some of the examples of time series. Time series data is simply a collection of observations through repeated measurements over time. In other words, we could interpret this as data that changes over time.

The graph below shows Apple stock price over time for the last three months. Plotting time series data can help us understand the trend easily. However, we cannot know much just by looking at the graph. In this article, we will try to understand the basics of time series data by focusing on its compositions and the concept of moving average.

Decomposition of Time Series

Times series data can be normally divided into three parts, as following:

  • trend variation (T) — common tendency of data
  • seasonal variation (S) — rhythmic patterns that occur repeatedly
  • random fluctuations (R)— variations that are uncontrollable and inevitable

Let’s try analyzing time-series data using the “TSA” library. If you don’t have the TSA library installed, run install.packages("TSA") to install.

Let’s load the airpass dataset which shows monthly total international airline passengers from 1960 to 1971. Using plot() and decompose() together allows us to graph each of the components of time series data. There are two types of time series components — additive and multiplicative.

Additive means that the components of time series are added.

Multiplicative means that the components of time series are multiplied.

In R, the function decompose() allows us to decompose time series data into seasonality(S), trend(T) and residuals(R) into either additive or multiplicative. The type can be set by setting type = 'additive' or type = 'multiplicative' .

library(TSA)
data(airpass)
plot(decompose(airpass, type = 'additive')) #returns additive components
plot(decompose(airpass, type = 'multiplicative')) #returns multiplicative components

The additive decomposition is useful when the seasonal variation is constant over time, while the multiplicative decomposition is useful when the seasonal variation increases over time.

Moving Average

A moving average (MA) is a term often found in stock markets where MA is used as a stock indicator. In statistics terms, a moving average is analysis of data points by creating a series of averages of different subsets of the full time series dataset. Let’s go straight to an example with R.

We will use a dataset called elecsales from fpp library. This dataset contains information on annual electricity sales for South Australia from 1989 to 2008.

Moving averages can be calculated in R using filter() . The first argument is the dataset for which you would like to calculate a moving average, and the second argument is the filter we would like to apply to the dataset. For example, in a moving average context, if we are looking for a 3 time unit(day, month, year…) moving average, the filter argument may take rep(1/3, 3) , and for a 5 time unit moving average, it may take rep(1/5, 5) . Below is the example of plotting a 3-year and 5-year moving average using the elecsales dataset.

library(fpp)
data(elecsales) #load the dataset

ma_side1 = filter(elecsales, filter = rep(1/3, 3), method = 'convolution', sides = 1)
ma_side2 = filter(elecsales, filter = rep(1/3, 3), method = 'convolution', sides = 2)
plot(elecsales, main = 'elecsales MA')
lines(ma_side1, lty = 2, lwd = 1, col = 'blue')
lines(ma_side2, lty = 2, lwd = 1, col = 'red')
legend("topleft", legend = c('side = 1', 'side = 2'), lty = c(1, 3))

The graph above shows the plotted data as well as two 3-year moving averages. Both the red and blue dotted lines show 3-year moving averages, but the key difference is that the the argument sides was set 1 for the blue line and 2 for the red line. The argument sides determines the approach to calculating the moving average.

  • Sides = 1 : take average of prior two days and current day
  • Sides = 2: take average of the day before, current day and next day

This is why the blue line was shifted slightly to the right compared to the red line.

Exponential Moving Average (EMA)

Another type of a moving average is an exponential moving average, also referred to as EMA. The exponential moving average is often called the exponentially weighted moving average as it is a weighted averaging method that weights more recent data strongly. This is different to a simple MA that we just looked at which gives equal weights to all observations.

A smoothing constant α (alpha) is involved in EMA which is also called a weighing factor. Below is the formula for exponential moving average.

F_{t+1}: forecast for the period after

D_{t}: actual demand for the present period

F_{t}: previously determined forecast for the present period

α: weighing factor / smoothing constant

This formula may sound a bit confusing, so let me explain this in the context of stock market. The current exponential moving average can be calculating as below:

Now let’s try to understand the idea of EMA with simple lines of R coding. We are going to use the library forecast, which you can download by running install.packages('forecast') if you do not have this library downloaded. The forecast library provides a function called ses that produces forecasts obtained using simple exponential smoothing.

Bring back the elecsales dataset that we used in the previous section.

library(fpp)
data(elecsales) #load the dataset

install.packages('ses') #if necessary
library(ses)
ema = ses(elecsales, alpha = 0.3, h = 10)

Some of the main arguments that the function ses takes include alpha and h. The arugment alpha takes the value of smoothing parameter, and h is the number of periods for forecasting. In a few lines of codes above, we created the forecasts using the elecsales dataset and 0.3 as the smoothing parameter and for 10 time periods.

Below we graph the original data with the exponential moving average.

plot(elecsales, main = 'EMA with elecsales data')
lines(fitted(ema), col = 'red', lty = 2, lwd = 2)
legend("topleft", legend = c('EMA'), lty = c(2))

In this article, we focused on understanding the very basics of time series data which include the compositions of time series data and the concept of moving average. Hope this helped, and more time series related stuff will follow soon! :)

--

--

Changhyun Kim

Business & Technology Management (Ph.D) - Economics, Environmental Economics, ESG, Data Science, Sports Economics