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 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 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
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
# 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
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.
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
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.
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.
par(mfrow = c(2,2))
plot(model)
OLS Regression Diagnostics
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).