# Load required libraries
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(timetk)
## Warning: package 'timetk' was built under R version 4.4.3
library(tibble)
library(tidyquant)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo 
## ── Attaching core tidyquant packages ──────────────────────── tidyquant 1.0.9 ──
## ✔ PerformanceAnalytics 2.0.4      ✔ TTR                  0.24.4
## ✔ quantmod             0.4.26     ✔ xts                  0.14.0── Conflicts ────────────────────────────────────────── tidyquant_conflicts() ──
## ✖ zoo::as.Date()                 masks base::as.Date()
## ✖ zoo::as.Date.numeric()         masks base::as.Date.numeric()
## ✖ dplyr::filter()                masks stats::filter()
## ✖ xts::first()                   masks dplyr::first()
## ✖ dplyr::lag()                   masks stats::lag()
## ✖ xts::last()                    masks dplyr::last()
## ✖ PerformanceAnalytics::legend() masks graphics::legend()
## ✖ quantmod::summary()            masks base::summary()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
## Attaching package: 'tidyquant'
## 
## The following object is masked from 'package:timetk':
## 
##     FANG

Purpose

Explore unemployment initial claims across New England states using time-based visualizations and diagnostic techniques.

start_point <- "1990-01-01"

state_series <- c("CTICLAIMS", "MEICLAIMS", "MAICLAIMS", 
                  "NHICLAIMS", "RIICLAIMS", "VTICLAIMS")

data_claims <- tq_get(state_series, get = "economic.data", from = start_point) %>%
  mutate(state = case_when(
    symbol == "CTICLAIMS" ~ "Connecticut",
    symbol == "MEICLAIMS" ~ "Maine",
    symbol == "MAICLAIMS" ~ "Massachusetts",
    symbol == "NHICLAIMS" ~ "New Hampshire",
    symbol == "RIICLAIMS" ~ "Rhode Island",
    symbol == "VTICLAIMS" ~ "Vermont"
  )) %>%
  rename(initial_claims = price)

Initial Time Series Plots

data_claims %>%
  group_by(state) %>%
  plot_time_series(date, initial_claims, .facet_ncol = 3, .interactive = FALSE)

Distribution of Claims Before 1995

data_claims %>%
  filter_by_time(date, .end_date = "1995-01-01") %>%
  group_by(state) %>%
  plot_time_series_boxplot(date, initial_claims, .period = "1 year", .facet_ncol = 3)

Diagnostics and Decompositions

Auto-Correlation Function

data_claims %>%
  group_by(state) %>%
  plot_acf_diagnostics(date, initial_claims, .lags = "2 years")

Seasonal Diagnostics

data_claims %>%
  group_by(state) %>%
  plot_seasonal_diagnostics(date, initial_claims)

STL Diagnostics

data_claims %>%
  group_by(state) %>%
  plot_stl_diagnostics(date, initial_claims, .feature_set = c("observed", "trend", "season", "remainder"))
## frequency = 13 observations per 1 quarter
## trend = 53 observations per 1 year
## frequency = 13 observations per 1 quarter
## trend = 53 observations per 1 year
## frequency = 13 observations per 1 quarter
## trend = 53 observations per 1 year
## frequency = 13 observations per 1 quarter
## trend = 53 observations per 1 year
## frequency = 13 observations per 1 quarter
## trend = 53 observations per 1 year
## frequency = 13 observations per 1 quarter
## trend = 53 observations per 1 year

Time Aggregation and Rolling Models

Quarterly Averages

data_claims %>%
  group_by(state) %>%
  summarise_by_time(date, .by = "quarter", avg_claims = mean(initial_claims, na.rm = TRUE)) %>%
  plot_time_series(date, avg_claims, .facet_ncol = 3, .interactive = FALSE)

Post-2007 Financial Crisis Focus

data_claims %>%
  group_by(state) %>%
  filter_by_time(date, .start_date = "2007-01-01", .end_date = "2009-12-31") %>%
  plot_time_series(date, initial_claims, .facet_ncol = 3)

Weekly Padding and Rolling Regression

data_claims %>%
  group_by(state) %>%
  pad_by_time(date, .by = "week", .pad_value = NA) %>%
  mutate(date_numeric = as.numeric(date)) %>%
  group_by(state) %>%
  mutate(lm_roll = slidify(~ lm(..1 ~ ..2), .period = 52, .align = "right", .unlist = FALSE)(initial_claims, date_numeric)) %>%
  filter(!is.na(lm_roll))
## # A tibble: 10,740 × 6
## # Groups:   state [6]
##    symbol    date       initial_claims state       date_numeric lm_roll
##    <chr>     <date>              <int> <chr>              <dbl> <list> 
##  1 CTICLAIMS 1990-12-29           7044 Connecticut         7667 <lm>   
##  2 CTICLAIMS 1991-01-05           7397 Connecticut         7674 <lm>   
##  3 CTICLAIMS 1991-01-12          14189 Connecticut         7681 <lm>   
##  4 CTICLAIMS 1991-01-19          12890 Connecticut         7688 <lm>   
##  5 CTICLAIMS 1991-01-26          10608 Connecticut         7695 <lm>   
##  6 CTICLAIMS 1991-02-02           7823 Connecticut         7702 <lm>   
##  7 CTICLAIMS 1991-02-09           7724 Connecticut         7709 <lm>   
##  8 CTICLAIMS 1991-02-16           6633 Connecticut         7716 <lm>   
##  9 CTICLAIMS 1991-02-23           6460 Connecticut         7723 <lm>   
## 10 CTICLAIMS 1991-03-02           6558 Connecticut         7730 <lm>   
## # ℹ 10,730 more rows