Introduction

This report estimates a Keynesian Consumption Function using U.S. macroeconomic data sourced from the Federal Reserve Economic Database (FRED). The model examines how personal disposable income, the federal funds rate, and unemployment jointly determine personal consumption expenditure. Following Wooldridge (2019), an empirical analysis begins with a clearly specified economic model before moving to estimation and inference.

Research Question: What are the key determinants of personal consumption expenditure in the United States from 1990 to 2023?

Hypothesis: Higher disposable income increases consumption (β₁ > 0), higher interest rates reduce consumption (β₂ < 0), and higher unemployment reduces consumption (β₃ < 0).


Data

Source and Variables

Data are obtained from FRED (Federal Reserve Bank of St. Louis) at annual frequency for the period 1990–2023.

Variable FRED Code Description Expected Sign
PCE PCE Personal Consumption Expenditure (billions $) Dependent
Income DSPIC96 Real Disposable Personal Income Positive (+)
Interest FEDFUNDS Federal Funds Rate (%) Negative (−)
Unemployment UNRATE Unemployment Rate (%) Negative (−)

Load and Prepare Data

# Load required libraries
library(tidyverse)
library(readr)
library(stargazer)
library(lmtest)
library(sandwich)
library(ggplot2)
library(corrplot)

# ── Load your 4 CSV files downloaded from FRED ──
pce   <- read_csv("C:/Users/Deki/Downloads/PCE.csv")
names(pce) <- c("date", "consumption")

inc   <- read_csv("C:/Users/Deki/Downloads/DSPIC96.csv")
names(inc) <- c("date", "income")

rate  <- read_csv("C:/Users/Deki/Downloads/FEDFUNDS.csv")
names(rate) <- c("date", "interest")

unemp <- read_csv("C:/Users/Deki/Downloads/UNRATE.csv")
names(unemp) <- c("date", "unemployment")

# Convert date column
pce$date   <- as.Date(pce$date)
inc$date   <- as.Date(inc$date)
rate$date  <- as.Date(rate$date)
unemp$date <- as.Date(unemp$date)

# Merge all datasets by date
df <- pce %>%
  inner_join(inc,   by = "date") %>%
  inner_join(rate,  by = "date") %>%
  inner_join(unemp, by = "date") %>%
  filter(date >= as.Date("1990-01-01"),
         date <= as.Date("2023-12-31"))

# Preview the data
head(df)
## # A tibble: 6 × 5
##   date       consumption income interest unemployment
##   <date>           <dbl>  <dbl>    <dbl>        <dbl>
## 1 1990-01-01       3809   7225.     8.1           5.6
## 2 1991-01-01       3944.  7286.     5.69          6.9
## 3 1992-01-01       4198.  7576.     3.52          7.5
## 4 1993-01-01       4452   7699.     3.02          6.9
## 5 1994-01-01       4721   7908.     4.2           6.1
## 6 1995-01-01       4963.  8169.     5.84          5.6
summary(df)
##       date             consumption        income         interest    
##  Min.   :1990-01-01   Min.   : 3809   Min.   : 7225   Min.   :0.080  
##  1st Qu.:1998-04-02   1st Qu.: 5979   1st Qu.: 9313   1st Qu.:0.385  
##  Median :2006-07-02   Median : 9512   Median :11916   Median :2.045  
##  Mean   :2006-07-02   Mean   : 9493   Mean   :11768   Mean   :2.774  
##  3rd Qu.:2014-10-01   3rd Qu.:12192   3rd Qu.:13777   3rd Qu.:5.008  
##  Max.   :2023-01-01   Max.   :18833   Max.   :17268   Max.   :8.100  
##   unemployment  
##  Min.   :3.600  
##  1st Qu.:4.600  
##  Median :5.450  
##  Mean   :5.771  
##  3rd Qu.:6.725  
##  Max.   :9.600

Model Specification

Following Wooldridge (2019, Chapter 1), an econometric model must be specified before estimation. The Multiple Linear Regression (MLR) model is:

\[\text{Consumption}_t = \beta_0 + \beta_1 \text{Income}_t + \beta_2 \text{Interest}_t + \beta_3 \text{Unemployment}_t + u_t\]

where \(u_t\) is the error term capturing all unobserved factors.

# Descriptive statistics
df %>%
  select(consumption, income, interest, unemployment) %>%
  summary()
##   consumption        income         interest      unemployment  
##  Min.   : 3809   Min.   : 7225   Min.   :0.080   Min.   :3.600  
##  1st Qu.: 5979   1st Qu.: 9313   1st Qu.:0.385   1st Qu.:4.600  
##  Median : 9512   Median :11916   Median :2.045   Median :5.450  
##  Mean   : 9493   Mean   :11768   Mean   :2.774   Mean   :5.771  
##  3rd Qu.:12192   3rd Qu.:13777   3rd Qu.:5.008   3rd Qu.:6.725  
##  Max.   :18833   Max.   :17268   Max.   :8.100   Max.   :9.600
# Correlation matrix
cor_matrix <- cor(df %>% select(consumption, income, interest, unemployment),
                  use = "complete.obs")
corrplot(cor_matrix, method = "color", type = "upper",
         addCoef.col = "black", tl.col = "black")
Correlation Matrix of Variables

Correlation Matrix of Variables


Regression Results

# Estimate the OLS model
model <- lm(consumption ~ income + interest + unemployment, data = df)

# Summary output
summary(model)
## 
## Call:
## lm(formula = consumption ~ income + interest + unemployment, 
##     data = df)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1665.06  -406.89    12.94   201.55  1948.88 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -7.041e+03  1.375e+03  -5.121 1.66e-05 ***
## income        1.395e+00  6.204e-02  22.480  < 2e-16 ***
## interest      1.146e+02  8.796e+01   1.303    0.203    
## unemployment -3.390e+01  9.821e+01  -0.345    0.732    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 663.8 on 30 degrees of freedom
## Multiple R-squared:  0.976,  Adjusted R-squared:  0.9737 
## F-statistic: 407.5 on 3 and 30 DF,  p-value: < 2.2e-16
# Professional regression table
stargazer(model,
          type = "latex",   # change to "html" if knitting to HTML
          title = "OLS Regression Results: Consumption Function",
          dep.var.labels = "Personal Consumption Expenditure",
          covariate.labels = c("Disposable Income", 
                               "Federal Funds Rate",
                               "Unemployment Rate"),
          notes = "Standard errors in parentheses. Data: FRED (1990-2023).",
          star.cutoffs = c(0.10, 0.05, 0.01))
% Table created by stargazer v.5.2.3 by Marek Hlavac, Social Policy Institute. E-mail: marek.hlavac at gmail.com % Date and time: Wed, Apr 15, 2026 - 9:33:06 AM

Interpretation of Results

Coefficients

coef(model)
##  (Intercept)       income     interest unemployment 
## -7040.800257     1.394609   114.593519   -33.902633
confint(model)
##                     2.5 %       97.5 %
## (Intercept)  -9848.755941 -4232.844574
## income           1.267912     1.521307
## interest       -65.041113   294.228151
## unemployment  -234.468171   166.662906

Interpret below this chunk in your write-up like this:

  • Intercept (β₀): When income, interest rate, and unemployment are all zero, predicted consumption is $[value] billion. (Useful as a baseline anchor.)

  • Income (β₁): A $1 billion increase in real disposable income is associated with a $[β₁] billion increase in consumption, holding other variables constant. This is consistent with the Keynesian marginal propensity to consume.

  • Interest Rate (β₂): A 1 percentage point increase in the federal funds rate is associated with a $[β₂] billion change in consumption, ceteris paribus.

  • Unemployment (β₃): A 1 percentage point rise in unemployment is associated with a $[β₃] billion change in consumption, all else equal.

Statistical Significance

summary(model)$coefficients
##                  Estimate   Std. Error    t value     Pr(>|t|)
## (Intercept)  -7040.800257 1.374917e+03 -5.1208901 1.655851e-05
## income           1.394609 6.203754e-02 22.4800894 2.504260e-20
## interest       114.593519 8.795821e+01  1.3028178 2.025492e-01
## unemployment   -33.902633 9.820704e+01 -0.3452159 7.323409e-01
  • A variable is statistically significant at the 5% level if its p-value < 0.05.
  • This means we reject H₀: βᵢ = 0 and conclude the variable has a statistically meaningful relationship with consumption.

Model Evaluation

R-squared and Adjusted R-squared

cat("R-squared:         ", summary(model)$r.squared, "\n")
## R-squared:          0.9760496
cat("Adjusted R-squared:", summary(model)$adj.r.squared, "\n")
## Adjusted R-squared: 0.9736546

Interpretation: The R² of [value] indicates that [X]% of the variation in personal consumption is explained by the three independent variables. The Adjusted R² penalizes for additional variables and is a more reliable goodness-of-fit measure in multiple regression.

F-statistic (Overall Model Significance)

summary(model)$fstatistic
##  value  numdf  dendf 
## 407.53   3.00  30.00

Interpretation: The F-statistic tests whether all slope coefficients are jointly zero (H₀: β₁ = β₂ = β₃ = 0). A p-value < 0.05 means we reject this null — the model as a whole is statistically significant.

Diagnostic Plots

par(mfrow = c(2,2))
plot(model)
OLS Regression Diagnostics

OLS Regression Diagnostics


Conclusion

This report estimated a Keynesian consumption function using U.S. annual data (1990–2023). The OLS regression results [support/partially support] the theoretical predictions: disposable income is a strong positive predictor of consumption, consistent with Keynes’s marginal propensity to consume. [Discuss interest rate and unemployment findings based on your actual results.]

The model explains [X]% of variation in consumption (R² = [value]), and the F-statistic confirms overall model significance.

Limitations: This time-series model may suffer from autocorrelation — a concern for future work using more advanced techniques (e.g., Newey-West standard errors or dynamic models).


References