DATA 624 Homework 1

Author

Long Lin

library(fpp3)
── Attaching packages ──────────────────────────────────────────── fpp3 1.0.3 ──
✔ tibble      3.3.1     ✔ tsibble     1.2.0
✔ dplyr       1.2.0     ✔ tsibbledata 0.4.1
✔ tidyr       1.3.2     ✔ ggtime      1.0.0
✔ lubridate   1.9.5     ✔ feasts      0.5.0
✔ ggplot2     4.0.2     ✔ fable       0.5.0
── Conflicts ───────────────────────────────────────────────── fpp3_conflicts ──
✖ lubridate::date()    masks base::date()
✖ dplyr::filter()      masks stats::filter()
✖ tsibble::intersect() masks base::intersect()
✖ tsibble::interval()  masks lubridate::interval()
✖ dplyr::lag()         masks stats::lag()
✖ tsibble::setdiff()   masks base::setdiff()
✖ tsibble::union()     masks base::union()

Exercise 2.1

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

Use ? (or help()) to find out about the data in each series.
What is the time interval of each series?
Use autoplot() to produce a time plot of each series.
For the last plot, modify the axis labels and title.
aus_production
# A tsibble: 218 x 7 [1Q]
   Quarter  Beer Tobacco Bricks Cement Electricity   Gas
     <qtr> <dbl>   <dbl>  <dbl>  <dbl>       <dbl> <dbl>
 1 1956 Q1   284    5225    189    465        3923     5
 2 1956 Q2   213    5178    204    532        4436     6
 3 1956 Q3   227    5297    208    561        4806     7
 4 1956 Q4   308    5681    197    570        4418     6
 5 1957 Q1   262    5577    187    529        4339     5
 6 1957 Q2   228    5651    214    604        4811     7
 7 1957 Q3   236    5317    227    603        5259     7
 8 1957 Q4   320    6152    222    582        4735     6
 9 1958 Q1   272    5758    199    554        4608     5
10 1958 Q2   233    5641    229    620        5196     7
# ℹ 208 more rows

According to the help page for aus_production, the time interval for Bricks from aus_production is quarterly. Looking at the tsibble above, it goes from “1956 Q1” to “2010 Q2”.

autoplot(aus_production, Bricks)
Warning: Removed 20 rows containing missing values or values outside the scale range
(`geom_line()`).

pelt
# A tsibble: 91 x 3 [1Y]
    Year  Hare  Lynx
   <dbl> <dbl> <dbl>
 1  1845 19580 30090
 2  1846 19600 45150
 3  1847 19610 49150
 4  1848 11990 39520
 5  1849 28040 21230
 6  1850 58000  8420
 7  1851 74600  5560
 8  1852 75090  5080
 9  1853 88480 10170
10  1854 61280 19600
# ℹ 81 more rows

According to the help page for pelt and the tsibble above, the time interval for Lynx from pelt is yearly from 1845 to 1935.

autoplot(pelt, Lynx)

gafa_stock
# A tsibble: 5,032 x 8 [!]
# Key:       Symbol [4]
   Symbol Date        Open  High   Low Close Adj_Close    Volume
   <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>     <dbl>
 1 AAPL   2014-01-02  79.4  79.6  78.9  79.0      67.0  58671200
 2 AAPL   2014-01-03  79.0  79.1  77.2  77.3      65.5  98116900
 3 AAPL   2014-01-06  76.8  78.1  76.2  77.7      65.9 103152700
 4 AAPL   2014-01-07  77.8  78.0  76.8  77.1      65.4  79302300
 5 AAPL   2014-01-08  77.0  77.9  77.0  77.6      65.8  64632400
 6 AAPL   2014-01-09  78.1  78.1  76.5  76.6      65.0  69787200
 7 AAPL   2014-01-10  77.1  77.3  75.9  76.1      64.5  76244000
 8 AAPL   2014-01-13  75.7  77.5  75.7  76.5      64.9  94623200
 9 AAPL   2014-01-14  76.9  78.1  76.8  78.1      66.1  83140400
10 AAPL   2014-01-15  79.1  80.0  78.8  79.6      67.5  97909700
# ℹ 5,022 more rows

At first, the time interval was a little confusing to figure out since there are some missing dates. But after cross referencing with a calendar of 2014, it looks like the time interval for Close from gafa_stock is every day that the stock market was open from 2014 to 2018.

autoplot(gafa_stock, Close)

vic_elec
# A tsibble: 52,608 x 5 [30m] <Australia/Melbourne>
   Time                Demand Temperature Date       Holiday
   <dttm>               <dbl>       <dbl> <date>     <lgl>  
 1 2012-01-01 00:00:00  4383.        21.4 2012-01-01 TRUE   
 2 2012-01-01 00:30:00  4263.        21.0 2012-01-01 TRUE   
 3 2012-01-01 01:00:00  4049.        20.7 2012-01-01 TRUE   
 4 2012-01-01 01:30:00  3878.        20.6 2012-01-01 TRUE   
 5 2012-01-01 02:00:00  4036.        20.4 2012-01-01 TRUE   
 6 2012-01-01 02:30:00  3866.        20.2 2012-01-01 TRUE   
 7 2012-01-01 03:00:00  3694.        20.1 2012-01-01 TRUE   
 8 2012-01-01 03:30:00  3562.        19.6 2012-01-01 TRUE   
 9 2012-01-01 04:00:00  3433.        19.1 2012-01-01 TRUE   
10 2012-01-01 04:30:00  3359.        19.0 2012-01-01 TRUE   
# ℹ 52,598 more rows
tail(vic_elec)
# A tsibble: 6 x 5 [30m] <Australia/Melbourne>
  Time                Demand Temperature Date       Holiday
  <dttm>               <dbl>       <dbl> <date>     <lgl>  
1 2014-12-31 21:00:00  3928.        20.3 2014-12-31 FALSE  
2 2014-12-31 21:30:00  3873.        19   2014-12-31 FALSE  
3 2014-12-31 22:00:00  3792.        18.5 2014-12-31 FALSE  
4 2014-12-31 22:30:00  3725.        17.7 2014-12-31 FALSE  
5 2014-12-31 23:00:00  3762.        17.3 2014-12-31 FALSE  
6 2014-12-31 23:30:00  3809.        17.1 2014-12-31 FALSE  

The time interval for Demand from vic_elec is half-hourly starting from 2012-01-01 00:00:00 to 2014-12-31 23:30:00. I was able to use the tail command to see the last values in order to see what the last date time was.

autoplot(vic_elec, Demand) +
  labs(x = "Time",
    y = "Total electricity demand (MWh)",
       title = "Half-hourly electricity demand for Victoria, Australia")

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 |> 
    filter(Close == max(Close))
# A tsibble: 1 x 8 [!]
# Key:       Symbol [1]
  Symbol Date        Open  High   Low Close Adj_Close  Volume
  <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>   <dbl>
1 AMZN   2018-09-04 2026. 2050.  2013 2040.     2040. 5721100
gafa_stock |> 
  group_by(Symbol) |> 
    filter(Close == max(Close))
# A tsibble: 4 x 8 [!]
# Key:       Symbol [4]
# Groups:    Symbol [4]
  Symbol Date        Open  High   Low Close Adj_Close   Volume
  <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
1 AAPL   2018-10-03  230.  233.  230.  232.      230. 28654800
2 AMZN   2018-09-04 2026. 2050. 2013  2040.     2040.  5721100
3 FB     2018-07-25  216.  219.  214.  218.      218. 58954200
4 GOOG   2018-07-26 1251  1270. 1249. 1268.     1268.  2405600

In order to do this, I first tried the filter command on its own but it only returned AMZN since that had a highest closing price. So in order to get the peak closing price for each of the four stocks from gafa_stock, I used group_by(Symbol) to get the peak for each of the different stocks from gafa_stock. For AAPL, it was 2018-10-03 with a closing value of 232.07. For AMZN, it was 2018-09-04 with a closing value of 2039.51. For FB, it was 2018-07-25 with a closing value of 217.50. For GOOG, it was 2018-07-26 with a closing value of 1268.33.

Exercise 2.3

Download the file tute1.csv from the book website, open it in Excel (or some other spreadsheet application), and review its contents. You should find four columns of information. Columns B through D each contain a quarterly series, labelled Sales, AdBudget and GDP. Sales contains the quarterly sales for a small company over the period 1981-2005. AdBudget is the advertising budget and GDP is the gross domestic product. All series have been adjusted for inflation.

# a. You can read the data into R with the following script:
tute1 <- readr::read_csv("tute1.csv")
Rows: 100 Columns: 4
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
dbl  (3): Sales, AdBudget, GDP
date (1): Quarter

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(tute1)
# 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")

# d. Check what happens when you don’t include facet_grid().
mytimeseries |>
  pivot_longer(-Quarter) |>
  ggplot(aes(x = Quarter, y = value, colour = name)) +
  geom_line()

It looks like without the facet_grid, the data is plotted all on the same plot and the values become very hard to read since the scale is very big, especially the GDP’s green plot. I can’t really tell what the values are besides just the overall shape.

Exercise 2.4

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

# a. Install the USgas package.
library(USgas)
# b. Create a tsibble from us_total with year as the index and state as the key.
us_total_tsibble <- 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_gas <- us_total_tsibble |>
  filter(state %in% c("Maine", "Vermont", "New Hampshire", "Massachusetts",
                      "Connecticut", "Rhode Island") )
autoplot(new_england_gas, y) +
  labs(y = "Total Natural Gas Consumption (million cubic feet)",
       title = "Annual Total Natural Gas Consumption")

Exercise 2.5

# a. Download tourism.xlsx from the book website and read it into R using readxl::read_excel().
tourism_xlsx <- readxl::read_excel("tourism.xlsx")
View(tourism_xlsx)
# b. Create a tsibble which is identical to the tourism tsibble from the tsibble package.
tsibble::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.
# ℹ 24,310 more rows
tourism_tsibble_2 <- tourism_xlsx |> 
  mutate(Quarter = yearquarter(Quarter)) |>
  as_tsibble(index = Quarter, key = c(Region, State, Purpose))

tourism_tsibble_2
# 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.
# ℹ 24,310 more rows
# c. Find what combination of Region and Purpose had the maximum number of overnight trips on average.
tourism_tsibble_2 |> 
  group_by(Region, Purpose) |> 
    filter(Trips == max(Trips)) |>
      arrange(desc(Trips))
# A tsibble: 304 x 5 [1Q]
# Key:       Region, State, Purpose [304]
# Groups:    Region, Purpose [304]
   Quarter Region          State           Purpose  Trips
     <qtr> <chr>           <chr>           <chr>    <dbl>
 1 2017 Q4 Melbourne       Victoria        Visiting  985.
 2 2001 Q4 Sydney          New South Wales Business  948.
 3 2016 Q4 Sydney          New South Wales Visiting  921.
 4 1998 Q1 South Coast     New South Wales Holiday   915.
 5 2016 Q1 North Coast NSW New South Wales Holiday   906.
 6 1998 Q1 Sydney          New South Wales Holiday   828.
 7 2017 Q4 Melbourne       Victoria        Holiday   806.
 8 2016 Q4 Brisbane        Queensland      Visiting  796.
 9 2002 Q1 Gold Coast      Queensland      Holiday   711.
10 2017 Q3 Melbourne       Victoria        Business  704.
# ℹ 294 more rows

The combination of Region and Purpose with the maximum number of overnight trips on average was “Melbourne” and “Visiting” with 985.278401 overnight trips on average.

# d. Create a new tsibble which combines the Purposes and Regions, and just has total trips by State.
tourism_tsibble_3 <- tourism_xlsx |> 
  mutate(Quarter = yearquarter(Quarter)) |>
  as_tsibble(index = Quarter, key = c(Region, State, Purpose))
tourism_tsibble_3 |>
  group_by(State) |>
    summarise("Total Trips" = sum(Trips))
# A tsibble: 640 x 3 [1Q]
# Key:       State [8]
   State Quarter `Total 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.
# ℹ 630 more rows

Exercise 2.8

Use the following graphics functions: autoplot(), gg_season(), gg_subseries(), gg_lag(), ACF() and explore features from the following time series: “Total Private” Employed from us_employment, Bricks from aus_production, Hare from pelt, “H02” Cost from PBS, and Barrels from us_gasoline.

Can you spot any seasonality, cyclicity and trend?
What do you learn about the series?
What can you say about the seasonal patterns?
Can you identify any unusual years?

“Total Private” Employed from us_employment

us_employment |>
  filter(Title == "Total Private") |>
  autoplot(Employed)

Total private employment has a trend that goes upward. It looks to be seasonal with many rises and falls every year. There also seems to be cycles too where the dips are larger after a certain number of years before rebounding and trending upwards again. There are some unusual years like 2010 and the early 2000s due to the great recession and the dot com bubble, respectively.

us_employment |>
  filter(Title == "Total Private") |>
  gg_season(Employed)

The seasonal plot doesn’t show very strong swings through the year but it does look to trend upward from Jan to Dec.

us_employment |>
  filter(Title == "Total Private") |>
  gg_subseries(Employed)

Looking at the data, it seems that employment is slightly higher in the summer months (likely due to breaks from school) and lower during the start of the year.

us_employment |>
  filter(Title == "Total Private") |>
  gg_lag(Employed, geom = "point")

This lagplot shows a positive correlation.

us_employment |> 
  filter(Title == "Total Private") |> 
  ACF(Employed) |> autoplot()

The correlogram shows a strong positive correlation.

Bricks from aus_production

autoplot(aus_production, Bricks)
Warning: Removed 20 rows containing missing values or values outside the scale range
(`geom_line()`).

This time series looks like it is seasonal due to the regular rising and falling. There doesn’t seem to be any overall trend. It looks like it is cyclical though, with the sharp drops at 1975 and early 1980s. Besides 1975 and like 1983 being unusually low, 1996 also looks like it goes down a lot too.

gg_season(aus_production, Bricks)
Warning: Removed 20 rows containing missing values or values outside the scale range
(`geom_line()`).

Looking at this plot, it seems the demand for bricks is lower in Q1 and rises in Q2 and Q4 before falling again in Q4. This suggests that summer months are more popular to be building with bricks. The demand for bricks in 1975 to 1985 was also greater than the demand in the time periods before and after.

gg_subseries(aus_production, Bricks)
Warning: Removed 20 rows containing missing values or values outside the scale range
(`geom_line()`).

This plot also reinforces that summer time has more demand for bricks compared to winter time.

gg_lag(aus_production, Bricks, geom = "point")
Warning: Removed 20 rows containing missing values (gg_lag).

This plot also shows that Q1 is noticeably lower than everything else, especially when compared to Q3.

aus_production |> 
  ACF(Bricks) |> autoplot()

This shows a positive correlation at 0 Lag that gradually drops to around 0.5.

Hare from pelt

autoplot(pelt, Hare)

This time series doesn’t look like it has any trends, it just goes up and down. It does look cyclical though since every 10 years or so, it looks to go up and down. It’s not seasonal since its annual data so no data for different months or seasons.

gg_subseries(pelt, Hare)

It only has 1 panel since it’s yearly data, not much else to comment on this.

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

Looking at this lagplot, the first panel for lag 1 looks like there’s a positive correlation but as the lag increases, the correlation gets weaker and then by lag 9, it looks like it’s becoming a positive correlation again. This suggests that hare population routinely is good when the previous year was good until it just starts falling cyclically every 10 years or so before it goes up again.

pelt |> 
  ACF(Hare) |> autoplot()

The ACF shows that there are cycles which are positive and negative correlation. Around lag 5 is when it’s the most negative before turning it all the way around at the highest around lag 10.

H02 Cost from PBS

PBS |> 
  filter(ATC2 == "H02") |> 
  summarise(Total_Cost = sum(Cost)) |> 
  autoplot(Total_Cost)

This plot looks like it’s seasonal since there looks to be regular up and downs. It looks like it trends upwards over time. It doesn’t look cyclical or have any unusual years.

PBS |> 
  filter(ATC2 == "H02") |> 
  summarise(Total_Cost = sum(Cost)) |> 
  gg_season(Total_Cost)

The seasonal plot shows that the plot have a strong drop in February and then trends upwards to the end of the year.

PBS |> 
  filter(ATC2 == "H02") |> 
  summarise(Total_Cost = sum(Cost)) |> 
  gg_subseries(Total_Cost)

This plot also supports the seasonal drop in February and then consequent rise for the rest of the year.

PBS |> 
  filter(ATC2 == "H02") |> 
  summarise(Total_Cost = sum(Cost)) |> 
  gg_lag(Total_Cost, geom = "point")

This plot shows a positive trend with January and February to the side due to the drop in those months.

PBS |> 
  filter(ATC2 == "H02") |> 
  summarise(Total_Cost = sum(Cost)) |> 
  ACF(Total_Cost) |> autoplot()

This plot shows a peak at 12 lag and then again near the 24 lag. This suggests that the plot is seasonal every year. This is true since in Febuary it always falls only to rebound right back up.

Barrels from us_gasoline

autoplot(us_gasoline, Barrels)

This plot has an upward trend. The plot also appears to be seasonal since it regularly has dips and rises. It also appears to be cyclical since there is an unusually bigger dip after 2009 which is due to the great recession.

gg_season(us_gasoline, Barrels)

The plots looks like the summer months experience a raise probably due to the fact that school is out and people are travelling.

gg_subseries(us_gasoline, Barrels)

This plot is pretty hard to read due to everything being squished together. But it looks like as the weeks go on, it gradually raises until during the middle of the year, where the volume is the highest due to summer travel. Then it slowly tapers down again.

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

The plot shows a strong positive correlation in each of the panels.

us_gasoline |> 
  ACF(Barrels) |> autoplot()

The plot shows a pretty strong correlation throughout the plot, only dropping minimally around 30 weeks.