knitr::opts_chunk$set(message = FALSE, warning = FALSE)
options(cli.unicode = FALSE)
library(fpp3)
library(USgas)
library(readxl)

Exercise 2.1

Explore the following four time series: Bricks from aus_production, Lynx from pelt, Close from gafa_stock, Demand from vic_elec.

a. Use ? (or help()) to find out about the data in each series.

?aus_production
?pelt
?gafa_stock
?vic_elec
  • aus_production: Quarterly production of selected commodities in Australia. Bricks is clay brick production in millions of bricks.
  • pelt: Hudson Bay Company trading records for Snowshoe Hare and Canadian Lynx furs, 1845 to 1935. Lynx is the number of Canadian Lynx pelts traded.
  • gafa_stock: Daily stock prices for Google, Amazon, Facebook and Apple, 2014 to 2018, in USD. Close is the closing price.
  • vic_elec: Half-hourly electricity demand for Victoria, Australia, 2012 to 2014. Demand is total electricity demand in MWh.

b. What is the time interval of each series?

interval(aus_production)
## <interval[1]>
## [1] 1Q
interval(pelt)
## <interval[1]>
## [1] 1Y
interval(gafa_stock)
## <interval[1]>
## [1] !
interval(vic_elec)
## <interval[1]>
## [1] 30m
  • Bricks: quarterly.
  • Lynx: annual.
  • Close: daily, on trading days only. The interval is irregular (!) because there is no trading on weekends and holidays.
  • Demand: every 30 minutes.

c. Use autoplot() to produce a time plot of each series.

aus_production |> autoplot(Bricks)

pelt |> autoplot(Lynx)

gafa_stock |> autoplot(Close)

d. For the last plot, modify the axis labels and title.

vic_elec |>
  autoplot(Demand) +
  labs(title = "Half-hourly Electricity Demand in Victoria, Australia",
       x = "Time (30-minute intervals)",
       y = "Demand (MWh)")

Exercise 2.2

Use filter() to find what days corresponded to the peak closing price for each of the four stocks in gafa_stock.

gafa_stock |>
  group_by(Symbol) |>
  filter(Close == max(Close)) |>
  select(Symbol, Date, Close)
## # A tsibble: 4 x 3 [!]
## # Key:       Symbol [4]
## # Groups:    Symbol [4]
##   Symbol Date       Close
##   <chr>  <date>     <dbl>
## 1 AAPL   2018-10-03  232.
## 2 AMZN   2018-09-04 2040.
## 3 FB     2018-07-25  218.
## 4 GOOG   2018-07-26 1268.

All four stocks reached their peak closing price in the second half of 2018:

Exercise 2.3

a. Read the data

tute1 <- readr::read_csv("tute1.csv")
tute1
## # A tibble: 100 x 4
##    Quarter    Sales AdBudget   GDP
##    <date>     <dbl>    <dbl> <dbl>
##  1 1981-03-01 1020.     659.  252.
##  2 1981-06-01  889.     589   291.
##  3 1981-09-01  795      512.  291.
##  4 1981-12-01 1004.     614.  292.
##  5 1982-03-01 1058.     647.  279.
##  6 1982-06-01  944.     602   254 
##  7 1982-09-01  778.     531.  296.
##  8 1982-12-01  932.     608.  272.
##  9 1983-03-01  996.     638.  260.
## 10 1983-06-01  908.     582.  280.
## # i 90 more rows

The file has a Quarter column and three quarterly series from 1981 to 2005: Sales, AdBudget and GDP.

b. Convert the data to time series

mytimeseries <- tute1 |>
  mutate(Quarter = yearquarter(Quarter)) |>
  as_tsibble(index = Quarter)

c. Construct time series plots of each of the three series

mytimeseries |>
  pivot_longer(-Quarter) |>
  ggplot(aes(x = Quarter, y = value, colour = name)) +
  geom_line() +
  facet_grid(name ~ ., scales = "free_y")

Check what happens when you don’t include facet_grid():

mytimeseries |>
  pivot_longer(-Quarter) |>
  ggplot(aes(x = Quarter, y = value, colour = name)) +
  geom_line()

Without facet_grid(), all three series are drawn on the same plot with one shared y-axis. Sales is around 1,000, AdBudget around 600 and GDP around 280, so the axis has to cover a wide range. The ups and downs of each series look smaller and are harder to see, especially for GDP, which looks almost flat. With facet_grid() and scales = "free_y", each series gets its own panel and y-axis, so its pattern is much clearer.

Exercise 2.4

a. Install the USgas package.

install.packages("USgas")

b. Create a tsibble from us_total with year as the index and state as the key.

us_gas <- us_total |>
  as_tsibble(index = year, key = state)
us_gas
## # A tsibble: 1,266 x 3 [1Y]
## # Key:       state [53]
##     year state        y
##    <int> <chr>    <int>
##  1  1997 Alabama 324158
##  2  1998 Alabama 329134
##  3  1999 Alabama 337270
##  4  2000 Alabama 353614
##  5  2001 Alabama 332693
##  6  2002 Alabama 379343
##  7  2003 Alabama 350345
##  8  2004 Alabama 382367
##  9  2005 Alabama 353156
## 10  2006 Alabama 391093
## # i 1,256 more rows

c. Plot the annual natural gas consumption by state for the New England area.

us_gas |>
  filter(state %in% c("Maine", "Vermont", "New Hampshire",
                      "Massachusetts", "Connecticut", "Rhode Island")) |>
  autoplot(y) +
  labs(title = "Annual Natural Gas Consumption in New England",
       x = "Year", y = "Million cubic feet")

  • Massachusetts uses by far the most gas, and its use has grown slowly over time.
  • Connecticut grew the most, nearly doubling from 1997 to 2019.
  • Maine jumped sharply around 2000 to 2001 and has slowly declined since then.
  • New Hampshire stepped up around 2003.
  • Rhode Island declined until about 2004 and then recovered a little.
  • Vermont uses the least and has stayed low.

Exercise 2.5

a. Download tourism.xlsx from the book website and read it into R.

tourism_xl <- read_excel("tourism.xlsx")
tourism_xl
## # A tibble: 24,320 x 5
##    Quarter    Region   State           Purpose  Trips
##    <chr>      <chr>    <chr>           <chr>    <dbl>
##  1 1998-01-01 Adelaide South Australia Business  135.
##  2 1998-04-01 Adelaide South Australia Business  110.
##  3 1998-07-01 Adelaide South Australia Business  166.
##  4 1998-10-01 Adelaide South Australia Business  127.
##  5 1999-01-01 Adelaide South Australia Business  137.
##  6 1999-04-01 Adelaide South Australia Business  200.
##  7 1999-07-01 Adelaide South Australia Business  169.
##  8 1999-10-01 Adelaide South Australia Business  134.
##  9 2000-01-01 Adelaide South Australia Business  154.
## 10 2000-04-01 Adelaide South Australia Business  169.
## # i 24,310 more rows

b. Create a tsibble which is identical to the tourism tsibble from the tsibble package.

my_tourism <- tourism_xl |>
  mutate(Quarter = yearquarter(Quarter)) |>
  as_tsibble(index = Quarter, key = c(Region, State, Purpose))
my_tourism
## # A tsibble: 24,320 x 5 [1Q]
## # Key:       Region, State, Purpose [304]
##    Quarter Region   State           Purpose  Trips
##      <qtr> <chr>    <chr>           <chr>    <dbl>
##  1 1998 Q1 Adelaide South Australia Business  135.
##  2 1998 Q2 Adelaide South Australia Business  110.
##  3 1998 Q3 Adelaide South Australia Business  166.
##  4 1998 Q4 Adelaide South Australia Business  127.
##  5 1999 Q1 Adelaide South Australia Business  137.
##  6 1999 Q2 Adelaide South Australia Business  200.
##  7 1999 Q3 Adelaide South Australia Business  169.
##  8 1999 Q4 Adelaide South Australia Business  134.
##  9 2000 Q1 Adelaide South Australia Business  154.
## 10 2000 Q2 Adelaide South Australia Business  169.
## # i 24,310 more rows
all.equal(my_tourism, tourism)
## [1] TRUE

c. Find what combination of Region and Purpose had the maximum number of overnight trips on average.

my_tourism |>
  as_tibble() |>
  group_by(Region, Purpose) |>
  summarise(Trips = mean(Trips), .groups = "drop") |>
  filter(Trips == max(Trips))
## # A tibble: 1 x 3
##   Region Purpose  Trips
##   <chr>  <chr>    <dbl>
## 1 Sydney Visiting  747.

Sydney with purpose Visiting had the highest average, about 747 thousand overnight trips per quarter.

d. Create a new tsibble which combines the Purposes and Regions, and just has total trips by State.

state_trips <- my_tourism |>
  group_by(State) |>
  summarise(Trips = sum(Trips))
state_trips
## # A tsibble: 640 x 3 [1Q]
## # Key:       State [8]
##    State Quarter Trips
##    <chr>   <qtr> <dbl>
##  1 ACT   1998 Q1  551.
##  2 ACT   1998 Q2  416.
##  3 ACT   1998 Q3  436.
##  4 ACT   1998 Q4  450.
##  5 ACT   1999 Q1  379.
##  6 ACT   1999 Q2  558.
##  7 ACT   1999 Q3  449.
##  8 ACT   1999 Q4  595.
##  9 ACT   2000 Q1  600.
## 10 ACT   2000 Q2  557.
## # i 630 more rows

Exercise 2.8

Use autoplot(), gg_season(), gg_subseries(), gg_lag() and ACF() to explore the following time series. For each one, look for seasonality, cyclicity and trend, describe what you learn about the series and its seasonal patterns, and identify any unusual years.

“Total Private” Employed from us_employment

total_private <- us_employment |>
  filter(Title == "Total Private")

total_private |> autoplot(Employed)

total_private |> gg_season(Employed)

total_private |> gg_subseries(Employed)

total_private |> gg_lag(Employed, geom = "point")

total_private |> ACF(Employed, lag_max = 48) |> autoplot()

  • Trend: A strong upward trend, from about 25 million jobs in 1939 to about 130 million in 2019. The ACF stays close to 1 and decays very slowly, and the lag plots fall almost on a straight line. Both are signs of a strong trend.
  • Cyclicity: The trend is interrupted by recessions. There are dips after World War II, in the early 1980s, around 1991, in 2001 to 2003, and a large drop in 2008 to 2010.
  • Seasonality: There is a small seasonal pattern. Employment drops in January after the holiday season and rises through spring and early summer. It is hard to see in the seasonal plot because the trend is so much bigger.
  • Unusual years: 1945 (end of the war) and 2008 to 2010 (the Great Recession), when employment fell by about 10%.

Bricks from aus_production

aus_production |> autoplot(Bricks)

aus_production |> gg_season(Bricks)

aus_production |> gg_subseries(Bricks)

aus_production |> gg_lag(Bricks, geom = "point")

aus_production |> ACF(Bricks, lag_max = 24) |> autoplot()

  • Trend: Production rose strongly from 1956 to a peak around 1980, then slowly declined and levelled off.
  • Cyclicity: There are irregular cycles with sharp drops in 1975, 1982 to 1983, the early 1990s, and 2001. These follow the ups and downs of the construction industry and the economy.
  • Seasonality: There is clear quarterly seasonality. Q1 is the lowest quarter, and production is highest in Q2 and Q3. The ACF has small bumps every 4 lags.
  • Unusual years: 1983 has the biggest drop in the series. 2001 was also very low, after the building boom before the GST was introduced in July 2000.

Hare from pelt

pelt |> autoplot(Hare)

pelt |> gg_lag(Hare, geom = "point")

pelt |> ACF(Hare, lag_max = 30) |> autoplot()

pelt is annual data, so gg_season() and gg_subseries() cannot be used because there is no seasonal period.

  • Trend: There is no clear trend.
  • Cyclicity: A strong cycle of about 10 years. The ACF is negative around lag 5 (half a cycle) and positive around lag 10 (a full cycle). This is the well-known predator-prey cycle between hares and lynx.
  • Seasonality: None, since the data is yearly.
  • Unusual years: 1863 to 1864 have the highest values (about 150,000 pelts), right after a very low value in 1862. The 1885 to 1886 peak is also very high.

“H02” Cost from PBS

h02 <- PBS |>
  filter(ATC2 == "H02") |>
  summarise(Cost = sum(Cost))

h02 |> autoplot(Cost)

h02 |> gg_season(Cost)

h02 |> gg_subseries(Cost)

h02 |> gg_lag(Cost, geom = "point")

h02 |> ACF(Cost, lag_max = 48) |> autoplot()

  • Trend: A clear upward trend. Costs roughly doubled from the early 1990s to 2008.
  • Cyclicity: There are no cycles beyond the yearly pattern.
  • Seasonality: Very strong yearly seasonality. Cost is lowest in February, rises through the year, and peaks in December and January. It then drops sharply in February, to about half of January’s value. The pattern likely comes from the PBS safety net, which resets at the start of each calendar year. The ACF has large spikes at lags 12, 24, 36 and 48.
  • Unusual years: 1991 and 2008 are partial years. 2005 is the only year where the total cost went down compared with the year before.

Barrels from us_gasoline

us_gasoline |> autoplot(Barrels)

us_gasoline |> gg_season(Barrels)

us_gasoline |> gg_subseries(Barrels)

us_gasoline |> gg_lag(Barrels, geom = "point")

us_gasoline |> ACF(Barrels, lag_max = 104) |> autoplot()

  • Trend: An upward trend from 1991 to about 2007, a decline from 2008 to 2012 during the financial crisis, and then a recovery to record levels in 2016.
  • Cyclicity: The 2008 to 2012 drop and recovery looks like a business-cycle effect rather than a regular cycle.
  • Seasonality: There is weak yearly seasonality. Demand is lowest in January and February and highest in the summer driving season (July and August). The weekly data is noisy, so the seasonal plot is messy. The ACF decays slowly because of the trend and has small bumps near lags 52 and 104 (one and two years).
  • Unusual years: 2008 to 2012 is lower than the earlier trend would suggest.