Created
April 3, 2025 00:29
-
-
Save farach/659aed3fb1240f50096a572b879301da to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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