Advanced Economic Methods
Exercise 7: Exploring dynamic econometric models
Overview
The following tutorial will introduce you to working with dynamic econometric models using a macroeconomic data set as an example. If you have not done the previous tutorials, go back to the introductory lesson here to learn how to set up the appropriate working paths for the code to work.
Setup
Header
Start a new script file and add your header and the appropriate
libraries. We will need the readxl package because the
example data set is only available in .xls format, the
dplyr and ggplot2 packages for data
organization and generating graphical analyses, and the
lmtest package to test for autocorrelation. For a refresher
on autocorrelation, please refer back to the tutorial here.
###########################################################################
# Project: Dynamic econometric models
# Author: [Your name]
# Date: [Today's date]
###########################################################################
# Clear environment and load libraries
rm(list=ls())
library(readxl)
library(dplyr)
library(ggplot2)
library(lmtest)
# Set working drive
setwd("C:/Projects/applied-econometrics/R") # Replace with your directory pathLoading data
As always, let’s take a look at the data:
## # A tibble: 6 × 5
## obs CPI GDP M2 R
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 1975Q1 18 131 96 8
## 2 1975Q2 18.5 136 101. 7
## 3 1975Q3 18.9 141 108. 6
## 4 1975Q4 19.4 146 114. 6
## 5 1976Q1 20.2 155 120. 12
## 6 1976Q2 21.5 168 126. 12
Analysis
Our analysis will require some data transformations prior to the analysis. The following code produces three transformations:
- Converts GDP and M2 to real GDP and real money balances using the consumer price index
- Transforms real GDP and money balance to log values (for interpretation as % change)
- Generates a lag term for the log money balance
- Drops any observations with missing values (the lag term will be missing in the first observation)
d <- d %>%
mutate(lGDP = log(CPI/GDP),
lR = log(R),
lM2 = log(M2/CPI),
lM2_l1 = lag(lM2, 1)) %>%
na.omit(d)Note: The transformation of \(CPI/GDP\) is actually incorrect. It should be \(GDP/CPI\), but this would have resulted in a sign reversal that does not match the example in the textbook, nor would it have reflected real economic theory. The reason for this is unclear, but is likely an error in the data provided by the textbook.
Partial adjustment model
We will test the partial adjustment model, which includes a lagged term of the dependent (Y) variable as an independent (X) variable. We can write the model statement as:
\[ log(M_t) = \beta_0 + \beta_1 log(Y_t) + \beta_2 log(R_t) + \beta_3 log(M_{t-1}) + u_t\]
Since we already did the log and lag transformations in the code above, we can simply enter those variables into the regression code as:
##
## Call:
## lm(formula = lM2 ~ lGDP + lR + lM2_l1, data = d)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.044847 -0.010097 0.001123 0.012441 0.026430
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.184265 0.049705 3.707 0.000368 ***
## lGDP 0.026614 0.010571 2.518 0.013642 *
## lR -0.017358 0.005859 -2.962 0.003935 **
## lM2_l1 0.959451 0.030822 31.129 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.01561 on 87 degrees of freedom
## Multiple R-squared: 0.9335, Adjusted R-squared: 0.9312
## F-statistic: 406.9 on 3 and 87 DF, p-value: < 2.2e-16
Interpretations: We can interpret the results as the following:
- A 1% increase in real GDP leads to a 0.027% increase in real money demand in the short run
- A 1% increase in the interest rate decreases log money demand by 0.017%. It’s a small change, but the relationship follows economic theory because higher interest rates increase the opportunity cost of holding money, thereby reducing money demand
On the adjustment coefficient \(\lambda\):
- \(\lambda\) = 1 - 0.959 = 0.041 (or 4.1%)
- This indicates very slow adjustment: only 4.1% of the gap between actual and desired money demand closes each quarter (16.4% per year)
- This finding suggests that people don’t immediately adjust their money balances to desired levels due to adjustment costs
Testing for autocorrelation
Autocorrelation (i.e. serial correlation) is always an important consideration when running time series analyses, particularly when working with lagged terms. We will run through a couple tests to see if serial correction is a problem in our model.
Extracting the residuals
As in the previous tutorial, we will first extract the residuals,
then create two variables: res1 for the residual, and
res2 for a lagged residual:
Graphical analysis
Now we will generate a couple plots to look at the the residuals over time and the first residual compared to the lagged residual.
If autocorrelation is present in the model, we would likely see a wave pattern that switches signs in the case of positive autocorrelation, or a sawtooth pattern for negative correlation:
ggplot(d, aes(x = obs, y = res1)) +
geom_point(shape = 16, color="darkblue", size = 3) +
geom_hline(yintercept = 0, color = "darkred", linetype = "dashed") +
labs(title = "Residuals over time",
x = "Time", y = "Residual") +
theme_minimal()The first plot does not show anything concerning. It all looks quite random. In the second plot, autocorrelation would should up as an upward or downward trend depending on the sign of the effect:
ggplot(d, aes(x = res2, y = res1)) +
geom_point(shape = 16, color = "darkblue", size = 3) +
geom_hline(yintercept = 0, color = "darkred", linetype = "dashed") +
labs(title = "Residuals vs lagged residuals",
x = "Lagged residuals", y = "Residuals") +
theme_minimal()## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_point()`).
This also looks good.
BG test
As a final assurance test, we will run the Breusch-Godfrey test with an order of 4 since it is quarterly data:
##
## Breusch-Godfrey test for serial correlation of order up to 4
##
## data: reg1
## LM test = 18.751, df = 4, p-value = 0.0008798
Unfortunately, we do a problem here. The null hypothesis for the test is that autocorrelation is not present, and a low p-value (in this case, p=0.00088) means we reject the null hypothesis. As such, it will be important to adjust the standard errors before we can make inferences on the results. This is a fairly involved process, so refer back to Exercise 4 to get the code.