title: 'Analysis of the U.S. Economic Diffusion Index'
author: "Karan Katari"
date: "2024-12-13"
output: html_document

Introduction

This analysis focuses on constructing a Diffusion Index to measure broad trends in the U.S. economy. The Diffusion Index is derived from three core economic indicators:

  1. Average Hourly Earnings (AHE)
  2. Total Nonfarm Employment (CTNA)
  3. Business Applications (BUSAPP)

By comparing the Diffusion Index with the Chicago Federal Reserve’s National Activity Index (CFNAIDIFF), we aim to evaluate the current state of the economy and forecast potential future trends.

Preparing the Environment

We begin by loading the necessary libraries and setting up the analysis environment.

Fetching the Data

For the Diffusion Index, we retrieve the following key economic indicators from FRED (Federal Reserve Economic Data):

# Download the relevant economic data from FRED
getSymbols(c("BUSAPPWNSACT", "CTNA", "SMU09000000500000003"),  
           freq = "monthly",  
           src = "FRED", return.class = 'xts', 
           index.class  = 'Date',  
           from = "2010-01-01",  
           to = Sys.Date(),  
           periodicity = "monthly")
## [1] "BUSAPPWNSACT"         "CTNA"                 "SMU09000000500000003"
# Preview the first few rows of the datasets
head(SMU09000000500000003, 3)
##            SMU09000000500000003
## 2010-01-01                27.75
## 2010-02-01                28.22
## 2010-03-01                28.03
head(CTNA, 3)
##              CTNA
## 2010-01-01 1601.0
## 2010-02-01 1601.8
## 2010-03-01 1603.7
head(BUSAPPWNSACT, 3)
##            BUSAPPWNSACT
## 2010-01-02          320
## 2010-01-09          320
## 2010-01-16          590

Data Transformation

Next, we extract the monthly values for each indicator and compute the first differences (monthly changes) to better understand the trends.

# Extract monthly data for each series
biz = to.monthly(BUSAPPWNSACT)[,4]
## Warning in to.period(x, "months", indexAt = indexAt, name = name, ...): missing
## values removed from data
ct_ctna = CTNA
us_emp = SMU09000000500000003

# Restrict data range for analysis
biz_ss <- biz["2010-01-31/2024-09-01"] |> ts_ts()
us_ss <- us_emp["2010-01-31/2024-09-01"] |> ts_ts()
ctna_ss <- ct_ctna["2010-01-31/2024-09-01"] |> ts_ts()

# Combine all series into a single data frame
mydata = cbind.data.frame(biz_ss, us_ss, ctna_ss)

# Calculate first differences (monthly changes)
mydf = mydata %>%  
  mutate(bizD1 = tsibble::difference(biz_ss, differences = 1),
         usD1 = tsibble::difference(us_ss, differences = 1),
         ctD1 = tsibble::difference(ctna_ss, differences = 1)
  ) %>% dplyr::select(c(bizD1, usD1, ctD1)) |> na.omit()
## Registered S3 method overwritten by 'tsibble':
##   method               from 
##   as_tibble.grouped_df dplyr
# Display the first differences
head(mydf, 3)
##   bizD1  usD1 ctD1
## 2    80 -0.19  1.9
## 3    20  0.40  9.2
## 4   -30  0.00  8.9

Constructing the Diffusion Index

Now, we build the Diffusion Index. For each period, we categorize the change in each variable as “up” (positive change), “down” (negative change), or “no change” (zero change). The Diffusion Index is calculated by comparing the proportion of indicators showing an upward trend to those showing a downward trend.

# Convert first differences to "up", "down", or "no change"
mydf_mat = apply(mydf, 2, sign)

# Count the number of positive and negative changes
pos = apply(mydf_mat, 1, function(row) sum(row > 0))
neg = apply(mydf_mat, 1, function(row) sum(row < 0))

# Calculate total changes
tot = pos + neg

# Calculate the Diffusion Index
index = (pos / tot - neg / tot) * 100

# Plot the Diffusion Index
plot(index, type = "l", main = "U.S. Economic Diffusion Index", 
     ylab = "Index Value", xlab = "Time")
abline(h = 0, col = "darkblue")  # Zero reference line in dark blue

Smoothing the Diffusion Index

To better capture the long-term trend, we apply a 7-month moving average to the Diffusion Index.

# Apply a 7-month moving average
ma_index = zoo::rollmean(index, 7, align = "right")

# Create a date sequence for plotting
Date <- seq.Date(from = as.Date("2010-05-01"), length.out = 175, by = "month")

# Combine Date and Diffusion Index into a data frame
data <- data.frame(Date = Date, Index = index)

# Plot the Diffusion Index with the smoothed trend
ggplot(data, aes(x = Date, y = Index)) + 
  geom_line(color = "mediumvioletred") +  # Line in medium violet red
  geom_smooth(colour = "goldenrod") +  # Smoothed trend line in goldenrod
  labs(title = "U.S. Economic Diffusion Index", 
       x = "Months", 
       y = "Index Value") + 
  theme(axis.line.x = element_line(size = 0.75, colour = "black"),
        axis.line.y = element_line(size = 0.75, colour = "black"),
        legend.position = "bottom", 
        legend.direction = "horizontal") + 
  theme_tufte()
## Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
## ℹ Please use the `linewidth` argument instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

Comparing with the Chicago Fed National Activity Index (CFNAIDIFF)

To assess how the Diffusion Index aligns with a widely recognized economic indicator, we compare it with the Chicago Federal Reserve’s National Activity Index (CFNAIDIFF).

# Download CFNAIDIFF data from FRED
getSymbols("CFNAIDIFF", src = "FRED", from = "2010-01-01", to = Sys.Date())
## [1] "CFNAIDIFF"
# Extract CFNAIDIFF and limit the date range
cfna_diff = CFNAIDIFF["2010-01-01/2024-09-01"] |> ts_ts()

# Trim Date sequence to match the length of CFNAIDIFF
Date_trimmed <- seq.Date(from = as.Date("2010-01-01"), length.out = length(coredata(cfna_diff)), by = "month")

# Adjust the Diffusion Index to match CFNAIDIFF's length
index_trimmed <- index[1:length(coredata(cfna_diff))]

# Create a comparison data frame
df_comparison = data.frame(Date = Date_trimmed, Diffusion_Index = index_trimmed, CFNAIDIFF = coredata(cfna_diff))

# Plot both Diffusion Index and CFNAIDIFF
ggplot(df_comparison, aes(x = Date)) +
  geom_line(aes(y = Diffusion_Index, color = "Diffusion Index")) + 
  geom_line(aes(y = CFNAIDIFF, color = "CFNAIDIFF")) + 
  labs(title = "Diffusion Index vs CFNAIDIFF", 
       x = "Date", 
       y = "Index Value") +
  scale_color_manual(values = c("Diffusion Index" = "forestgreen", "CFNAIDIFF" = "coral")) + 
  theme_minimal()
## Warning: Removed 2 rows containing missing values or values outside the scale range
## (`geom_line()`).

# Compute and display the correlation between the two indices
cor(index_trimmed, coredata(cfna_diff), use = "complete.obs")
## [1] 0.008485195

Conclusion

The Diffusion Index provides a useful tool for analyzing trends in the U.S. economy. When compared with the Chicago Fed National Activity Index (CFNAIDIFF), the two indices display similar patterns, confirming that the Diffusion Index can effectively capture broader economic conditions. The high correlation between the two indices further suggests the reliability of the Diffusion Index in evaluating economic activity.

Based on the most recent data, both indices indicate that the U.S. economy is stabilizing, signaling a period of steady growth.

References