library(tidyverse) # For ggplot, dplyr, and friends
library(tidyquant) # For getting financial data from FRED, other places
library(tsibble) # For working with time-based data
library(fable) # For time series analysis
library(scales) # For fun things like comma() and percent()
library(ggtext) # For text magic in ggplot
# Get data from FRED
# https://fred.stlouisfed.org/series/RSXFSN
data_raw <- tq_get(c("RSXFSN", # Advance retail sales
"USREC"), # Recessions
get = "economic.data", # Use FRED
from = "1967-01-07") # From first day of data
# Wrangle the recession dates so that we just have start and end dates
recessions_raw <- data_raw %>%
filter(symbol == "USREC") %>%
mutate(year_month = yearmonth(date)) %>%
as_tsibble(index = year_month, key = symbol) %>%
mutate(recession_delta = price - lag(price))
recessions <- tibble(start = filter(recessions_raw, recession_delta == 1)$year_month,
end = filter(recessions_raw, recession_delta == -1)$year_month)
# Clean up retail sales data
retail_sales <- data_raw %>%
filter(symbol == "RSXFSN") %>%
filter(date > "1999-12-31") %>%
rename(sales = price) %>%
mutate(year_month = yearmonth(date)) %>%
as_tsibble(index = year_month, key = symbol)
# Decompose sales
sales_model <- retail_sales %>%
# Probably best to use multiplicative errors, but then the values are less
# easily interpretable
model(ets = ETS(sales ~ error("A") + trend("Ad") + season("A")))
# Convert decomposed data to tidy
sales_model_components <- sales_model %>%
components() %>%
select(-slope) %>%
pivot_longer(cols = c(sales, level, season, remainder),
names_to = "component", values_to = "value") %>%
filter(year_month > "1999-12-31") %>%
mutate(is_component = component != "sales") %>%
mutate(component = recode(component, sales = "Advance retail sales, raw",
level = "Trend",
season = "Seasonality",
remainder = "Remainder")) %>%
mutate(component = fct_inorder(component))
# Plot
ggplot(sales_model_components, aes(x = year_month, y = value)) +
geom_rect(data = filter(recessions, start > "1999-12-31"),
aes(xmin = start, xmax = end, ymin = -Inf, ymax = Inf),
inherit.aes = FALSE, fill = "#B10DC9", alpha = 0.1) +
geom_line(aes(color = is_component)) +
scale_x_date(expand = c(0, 0)) +
scale_y_continuous(labels = comma) +
scale_color_manual(values = c("grey60", "#111111")) +
labs(x = NULL, y = "Millions of dollars",
caption = "Source: RSXFSN from FRED. Recessions highlighted in <span style='color: #B10DC9;'>purple</span>.") +
guides(color = FALSE) +
facet_wrap(vars(component), ncol = 1, scales = "free_y") +
theme_minimal(base_family = "Halis GR") +
theme(strip.text = element_text(hjust = 0, face = "bold", size = rel(1.3)),
plot.caption = element_markdown())
Created on 2020-05-22 by the reprex package (v0.3.0)