Assignment 1: FPP3 Chapter 2 — Time Series Graphics Exercises (2.1, 2.2, 2.3, 2.4, 2.5, 2.8)

Author

Chanice Mckenzie

library(fpp3)
library(readr)
library(readxl)

# install.packages("ggtime")
library(ggtime)

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

(b) What is the time interval of each series?

bricks <- aus_production |> select(Quarter, Bricks)
lynx <- pelt |> select(Year, Lynx)
close_aapl <- gafa_stock |> filter(Symbol == "AAPL") |> select(Date, Close)
demand <- vic_elec |> select(Time, Demand)

interval(bricks)
<interval[1]>
[1] 1Q
interval(lynx)
<interval[1]>
[1] 1Y
interval(close_aapl)   
<interval[1]>
[1] !
interval(demand)
<interval[1]>
[1] 30m

Answers for Exercise 2.1(b)

  • Bricks is quarterly.
  • Lynx is annual.
  • AAPL Close is irregular (trading days only; weekends/holidays missing).
  • Demand is half-hourly.

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

autoplot(bricks, Bricks)

autoplot(lynx, Lynx)

autoplot(close_aapl, Close)

autoplot(demand, Demand)

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

autoplot(demand, Demand) +
  labs(title = "Victoria electricity demand", x = "Time", y = "Demand")

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) |>
  slice_max(order_by = Close, n = 1, with_ties = FALSE) |>
  select(Symbol, Date, Close)

Exercise 2.3

(a) You can read the data into R with the following script:

tute1 <- read_csv("tute1.csv")

(b) Convert the data to time series

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

mytimeseries

(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() 

Exercise 2.4: The USgas package contains data on the demand for natural gas in the US.

(a) Install the USgas package.

# install.packages("USgas")
library(USgas)

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

gas_ts <- us_total |> as_tsibble(index = year, key = state)

(c) Plot the annual natural gas consumption by state for the New England area (comprising the states of Maine, Vermont, New Hampshire, Massachusetts, Connecticut and Rhode Island).

new_england <- c(
  "Maine", "Vermont", "New Hampshire",
  "Massachusetts", "Connecticut", "Rhode Island"
)

gas_ts |>
  filter(state %in% new_england) |>
  autoplot(y) +
  labs(
    title = "Annual natural gas consumption — New England states",
    x = "Year",
    y = "Million cubic feet"
  )

Exercise 2.5

(a) Download tourism.xlsx from the book website and read it into R using readxl::read_excel()

tourism <- readxl::read_excel("tourism.xlsx")

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

tourism |>
  as_tibble() |>
  group_by(Region, Purpose) |>
  summarise(avg_trips = mean(Trips, na.rm = TRUE), .groups = "drop") |>
  filter(avg_trips == max(avg_trips))

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

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

tourism_state_total <- tourism |>
  as_tibble() |>
  mutate(Quarter = yearquarter(Quarter)) |>
  group_by(State, Quarter) |>
  summarise(Trips = sum(Trips, na.rm = TRUE), .groups = "drop") |>
  as_tsibble(index = Quarter, key = State)

autoplot(tourism_state_total, Trips) +
  labs(title = "Total overnight trips by State", x = "Quarter", y = "Trips")

Exercise 2.8

explore_ts <- function(data, yvar, title_prefix = "") {
  yvar <- rlang::ensym(yvar)

  print(autoplot(data, !!yvar) + labs(title = paste(title_prefix, "Time plot")))

  # Seasonal plots may fail for annual series (e.g., pelt), so we skip safely.
  try(print(ggtime::gg_season(data, !!yvar) +
              labs(title = paste(title_prefix, "Seasonal plot"))), silent = TRUE)
  try(print(ggtime::gg_subseries(data, !!yvar) +
              labs(title = paste(title_prefix, "Seasonal subseries plot"))), silent = TRUE)

  try(print(ggtime::gg_lag(data, !!yvar) +
              labs(title = paste(title_prefix, "Lag plot"))), silent = TRUE)

  print(ACF(data, !!yvar) |> autoplot() + labs(title = paste(title_prefix, "ACF")))
}

emp_private <- us_employment |>
  filter(Title == "Total Private") |>
  select(Month, Employed)

bricks <- aus_production |>
  select(Quarter, Bricks)

hare <- pelt |>
  select(Year, Hare)

h02 <- PBS |>
  filter(ATC2 == "H02") |>
  select(Month, Cost)

gas_barrels <- us_gasoline |>
  select(Week, Barrels)

explore_ts(emp_private, Employed, "US employment — Total Private:")

explore_ts(bricks, Bricks, "Australia production — Bricks:")

explore_ts(hare, Hare, "Pelt — Hare:")

explore_ts(h02, Cost, "PBS — H02 Cost:")

explore_ts(gas_barrels, Barrels, "US gasoline — Barrels:")

Answers for Exercise 2.8

  • US employment — Total Private: clear seasonality, strong upward trend, cyclical downturns; unusual period around 2008–2009.
  • Bricks: strong quarterly seasonality, long-term decline; later years unusually low relative to earlier decades.
  • Hare: annual data → no seasonality; strong multi-year cyclicity; unusually high peaks/low troughs but consistent with cycles.
  • PBS H02 cost: strong monthly seasonality plus upward trend; occasional sharp increases suggest structural/policy/demand shifts.
  • US gasoline: strong annual seasonality (summer peaks), relatively stable long-run level with cyclical dips; unusual deviation around 2008–2009.