Skip to content

Instantly share code, notes, and snippets.

@farach
Created April 3, 2025 00:29
Show Gist options
  • Save farach/659aed3fb1240f50096a572b879301da to your computer and use it in GitHub Desktop.
Save farach/659aed3fb1240f50096a572b879301da to your computer and use it in GitHub Desktop.
library(tidyverse)
library(fredr)
library(lubridate)
library(scales)
# Define dynamic date filter (past 5 years)
filter_date <- Sys.Date() - years(5)
# Function to safely fetch FRED data with error handling
safe_fredr <- function(series_id) {
tryCatch(
{
fredr_series_observations(series_id = series_id) %>%
filter(date >= filter_date)
},
error = function(e) {
message(paste("Error fetching data for series:", series_id))
NULL
}
)
}
# Prepare recession shading data from FRED
usrec <- fredr_series_observations(series_id = "USREC") %>%
mutate(recession = value == 1) %>%
group_by(grp = cumsum(c(TRUE, diff(recession) != 0))) %>%
filter(recession) %>%
summarize(Start = min(date), End = max(date)) %>%
filter(Start >= filter_date)
# Helper function to generate economic indicator plots
generate_plot <- function(series_id, title, subtitle, caption, y_transform = identity, percent = FALSE, smooth = TRUE) {
df <- safe_fredr(series_id)
if (is.null(df)) {
return(NULL)
}
p <- df %>%
mutate(value = y_transform(value)) %>%
ggplot(aes(date, value)) +
geom_rect(
data = usrec,
inherit.aes = FALSE,
aes(xmin = Start, xmax = End, ymin = -Inf, ymax = +Inf),
fill = "#EBEBEB", alpha = 0.75
) +
geom_line() +
{
if (smooth) geom_smooth(method = "loess", span = 0.35, se = FALSE, color = "blue", linetype = "dashed", size = 0.5)
} +
theme_minimal() +
labs(
title = title,
subtitle = subtitle,
caption = caption,
x = "Date",
y = title
) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
coord_cartesian(expand = FALSE, clip = "off")
if (percent) {
p <- p + scale_y_continuous(labels = percent_format())
}
p
}
# Generate plots for various economic indicators impacted by tariffs
plot_federal_employment <- generate_plot("CES9091000001", "Federal & Contracting Workforce", "Tracks total federal employment.", "CES9091000001 - Government employment: Federal")
plot_auto_prices <- generate_plot("CUUR0000SETA01", "Auto Tariff Impact", "Price changes for new vehicles, impacted by tariffs.", "CUUR0000SETA01 - CPI New Vehicles")
plot_durable_goods <- generate_plot("DGORDER", "Durable Goods / Supply Chains", "New orders of durable goods.", "DGORDER - Durable Goods Orders")
plot_cpi_all <- generate_plot("CPIAUCNS", "Inflationary Signals", "Overall consumer inflation.", "CPIAUCNS - CPI All Urban Consumers")
plot_manufacturing_employment <- generate_plot("MANEMP", "Manufacturing Employment", "Proxy for tariff-exposed hiring.", "MANEMP - Manufacturing Employment")
plot_consumer_sentiment <- generate_plot("UMCSENT", "Consumer Sentiment", "Household sentiment and expectations.", "UMCSENT - U. Michigan Consumer Sentiment")
plot_trade_balance <- generate_plot("BOPGSTB", "U.S. Trade Balance", "Reflects trade dynamics impacted by tariffs.", "BOPGSTB - Trade Balance")
plot_ppi <- generate_plot("PPIACO", "Producer Price Index", "Measures production cost impacts.", "PPIACO - Producer Price Index")
plot_retail_sales <- generate_plot("RSAFS", "Retail Sales", "Consumer spending patterns.", "RSAFS - Retail Sales")
plot_import_prices <- generate_plot("IR", "Import Price Index", "Prices for imported goods.", "IR - Import Price Index")
# Combine and return all plots
list(
plot_federal_employment,
plot_auto_prices,
plot_durable_goods,
plot_cpi_all,
plot_manufacturing_employment,
plot_consumer_sentiment,
plot_trade_balance,
plot_ppi,
plot_retail_sales,
plot_import_prices
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment