Replication: A Contribution to the Empirics of Economic Growth by Mankiw, Romer, and Weil (1992)
Introduction
R Libraries and dataset
library(tibble) # nice dataframes
library(stargazer) # regression tables
library(ggplot2) # nice graphs
library(dplyr) # data manipulation
library(car) # test linear hypotheses
library(skimr) # descriptive statistics
library(haven) # reading stata data
options(warn = -1)
options(scipen = 10000)
options(repr.plot.width = 6, repr.plot.height = 4)
mrw_data <- read_dta("https://github.com/quarcs-lab/data-quarcs/raw/master/mrw1992/mrw2.dta")
skim(mrw_data)
mrw_data <- mrw_data %>%
rename(non_oil = n,
oecd = o,
intermediate = i,
gdp_60 = rgdpw60,
gdp_85 = rgdpw85,
gdp_growth_60_85 = gdpgrowth,
pop_growth_60_85 = popgrowth,
inv_gdp = i_y,
school = school)
delta_gamma <- 0.05
mrw_data <- mrw_data %>%
mutate(ln_gdp_85 = log(gdp_85),
ln_gdp_60 = log(gdp_60),
ln_gdp_growth = ln_gdp_85 - ln_gdp_60,
ln_inv_gdp = log(inv_gdp/100),
non_oil = factor(non_oil),
intermediate = factor(intermediate),
oecd = factor(oecd),
ln_ndg = log(pop_growth_60_85/100 + delta_gamma),
ln_school = log(school/100)) %>%
select(country, region, ln_gdp_85, ln_gdp_60, ln_inv_gdp,
non_oil, intermediate, oecd,
ln_ndg, ln_school, gdp_growth_60_85, ln_gdp_growth)
skim(mrw_data)
Data samples
non_oil <- mrw_data %>%
filter(non_oil == 1)
intermediate <- mrw_data %>%
filter(intermediate == 1)
oecd <- mrw_data %>%
filter(oecd == 1)
Additional samples for further exploration
africa <- mrw_data %>%
filter(region == "Africa")
asia <- mrw_data %>%
filter(region == "Asia")
europe <- mrw_data %>%
filter(region == "Europe")
latinAmerica <- mrw_data %>%
filter(region == "LatinAmerica")
northAmerica <- mrw_data %>%
filter(region == "NorthAmerica")
oceania <- mrw_data %>%
filter(region == "Oceania")
Textbook Solow model
Quantitative implications
Econometric specification
Unrestricted Regression
solow_oecd <- lm(ln_gdp_85 ~ ln_inv_gdp + ln_ndg, data = oecd)
solow_int <- lm(ln_gdp_85 ~ ln_inv_gdp + ln_ndg, data = intermediate)
solow_noil <- lm(ln_gdp_85 ~ ln_inv_gdp + ln_ndg, data = non_oil)
stargazer(solow_noil, solow_int, solow_oecd, digits=2, type = "text",
column.labels = c("Non-Oil",
"Intermediate",
"OECD"),
covariate.labels = c("log(I / GDP)",
"log(n+delta+g)",
"Constant"),
dep.var.labels = "Log(GDP) 1985",
omit.stat = c("f",
"rsq",
"ser"),
title = "Table 1 - Unrestricted Models",
style = "qje")
Restricted Regression
solow_noil_r <- lm(ln_gdp_85 ~ I(ln_inv_gdp - ln_ndg), data = non_oil)
solow_int_r <- lm(ln_gdp_85 ~ I(ln_inv_gdp - ln_ndg), data = intermediate)
solow_oecd_r <- lm(ln_gdp_85 ~ I(ln_inv_gdp - ln_ndg), data = oecd)
stargazer(solow_noil_r, solow_int_r, solow_oecd_r, digits=2, type = "text",
column.labels = c("Non-Oil",
"Intermediate",
"OECD"),
covariate.labels = c("log(I / GDP)- log(n+delta+g)",
"Constant"),
dep.var.labels = "Log(GDP) 1985",
omit.stat = c("f",
"rsq",
"ser"),
title = "Table 1 - Restricted Models",
style = "qje")
Test of Restriction
linearHypothesis(solow_noil, "ln_inv_gdp = - ln_ndg")
linearHypothesis(solow_int, "ln_inv_gdp = - ln_ndg")
linearHypothesis(solow_oecd, "ln_inv_gdp = - ln_ndg")
Implied alpha
C <- coef(solow_noil_r)[2]
alpha_solow_noil_r <- C/(1+C)
alpha_solow_noil_r <- round(alpha_solow_noil_r, 2)
print(paste("Implied alpha (Non oil):", alpha_solow_noil_r))
C <- coef(solow_int_r)[2]
alpha_solow_int_r <- C/(1+C)
alpha_solow_int_r <- round(alpha_solow_int_r, 2)
print(paste("Implied alpha (Intermediate):", alpha_solow_int_r))
C <- coef(solow_oecd_r)[2]
alpha_solow_oecd_r <- C/(1+C)
alpha_solow_oecd_r <- round(alpha_solow_oecd_r, 2)
print(paste("Implied alpha (OECD):", alpha_solow_oecd_r))
Augmented Solow model
Unrestricted regression
augsolow_noil <- lm(ln_gdp_85 ~ ln_inv_gdp + ln_ndg + ln_school, data = non_oil)
augsolow_int <- lm(ln_gdp_85 ~ ln_inv_gdp + ln_ndg + ln_school, data = intermediate)
augsolow_oecd <- lm(ln_gdp_85 ~ ln_inv_gdp + ln_ndg + ln_school, data = oecd)
stargazer(augsolow_noil, augsolow_int, augsolow_oecd, digits=2, type = "text",
column.labels = c("Non-Oil",
"Intermediate",
"OECD"),
covariate.labels = c("log(I / GDP)",
"log(n+delta+g)",
"log(school)",
"Constant"),
dep.var.labels = "Log(GDP) 1985",
omit.stat = c("f",
"rsq",
"ser"),
title = "Table 2 - Unrestricted Models",
style = "qje")
Restricted regression
augsolow_noil_r <- lm(ln_gdp_85 ~ I(ln_inv_gdp - ln_ndg) + I(ln_school - ln_ndg), data = non_oil)
augsolow_int_r <- lm(ln_gdp_85 ~ I(ln_inv_gdp - ln_ndg) + I(ln_school - ln_ndg), data = intermediate)
augsolow_oecd_r <- lm(ln_gdp_85 ~ I(ln_inv_gdp - ln_ndg) + I(ln_school - ln_ndg), data = oecd)
stargazer(augsolow_noil_r, augsolow_int_r, augsolow_oecd_r, digits=2, type = "text",
column.labels = c("Non-Oil",
"Intermediate",
"OECD"),
covariate.labels = c("log(I / GDP)- log(n+delta+g)",
"log(school)- log(n+delta+g)",
"Constant"),
dep.var.labels = "Log(GDP) 1985",
omit.stat = c("f",
"rsq",
"ser"),
title = "Table 2 - Restricted Models",
style = "qje")
Test of restriction
linearHypothesis(augsolow_oecd, "ln_inv_gdp + ln_ndg + ln_school = 0")
linearHypothesis(augsolow_noil, "ln_inv_gdp + ln_ndg + ln_school = 0")
linearHypothesis(augsolow_int, "ln_inv_gdp + ln_ndg + ln_school = 0")
Implied alpha and beta
c2 <- round(coef(augsolow_noil_r)[2], 2)
c2
c3 <- round(coef(augsolow_noil_r)[3], 2)
c3
x = c2 / (c2+c3+1)
x = round(x, 2)
print(paste("Implied alpha (Non oil):", x))
y = c3 / (c2+c3+1)
y = round(y, 2)
print(paste("Implied beta (Non oil):", y))
c2 <- round(coef(augsolow_int_r)[2], 2)
c2
c3 <- round(coef(augsolow_int_r)[3], 2)
c3
x = c2 / (c2+c3+1)
x = round(x, 2)
print(paste("Implied alpha (Intermediate):", x))
y = c3 / (c2+c3+1)
y = round(y, 2)
print(paste("Implied beta (Intermediate):", y))
c2 <- round(coef(augsolow_oecd_r)[2], 2)
c2
c3 <- round(coef(augsolow_oecd_r)[3], 2)
c3
x = c2 / (c2+c3+1)
x = round(x, 2)
print(paste("Implied alpha (OECD):", x))
y = c3 / (c2+c3+1)
y = round(y, 2)
print(paste("Implied beta (OECD):", y))
Convergence
Unconditional convergence
ucc_noil <- lm(ln_gdp_growth ~ ln_gdp_60, data = non_oil)
ucc_int <- lm(ln_gdp_growth ~ ln_gdp_60, data = intermediate)
ucc_oecd <- lm(ln_gdp_growth ~ ln_gdp_60, data = oecd)
stargazer(ucc_noil, ucc_int, ucc_oecd, digits=2, type = "text",
column.labels = c("Non-Oil",
"Intermediate",
"OECD"),
covariate.labels = c("log(GDP '60)",
"Constant"),
dep.var.labels = "Log(GDP '85) - Log(GDP '60)",
omit.stat = c("f",
"rsq",
"ser"),
title = "Table 3 - Unconditional Convergence",
style = "qje")
Implied speed of convergence
# Implied speed of convergence and halflife
speed = -log(1+coef(ucc_noil)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 5)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (Non-oil):", speed))
print(paste("Implied halflife of unconditional (Non-oil):", halfLife))
# Implied speed of convergence and halflife
speed = - log(1+coef(ucc_int)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 5)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (Intermediate):", speed))
print(paste("Implied halflife of unconditional (Intermediate):", halfLife))
# Implied speed of convergence and halflife
speed = - log(1+coef(ucc_oecd)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 4)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (OECD):", speed))
print(paste("Implied halflife of unconditional (OECD):", halfLife))
Conditional convergence
cc_noil <- lm(ln_gdp_growth ~ ln_gdp_60 + ln_inv_gdp + ln_ndg, data = non_oil)
cc_int <- lm(ln_gdp_growth ~ ln_gdp_60 + ln_inv_gdp + ln_ndg, data = intermediate)
cc_oecd <- lm(ln_gdp_growth ~ ln_gdp_60 + ln_inv_gdp + ln_ndg, data = oecd)
stargazer(cc_noil, cc_int, cc_oecd, digits=2, type = "text",
column.labels = c("Non-Oil",
"Intermediate",
"OECD"),
covariate.labels = c("log(GDP '60)",
"log(I / GDP)",
"log(n+delta+g)",
"Constant"),
dep.var.labels = "Log(GDP '85) - Log(GDP '60)",
omit.stat = c("f",
"rsq",
"ser"),
title = "Table 4 - Conditional Convergence",
style = "qje")
Implied speed of convergence
# Implied speed of convergence and halflife
speed = -log(1+coef(cc_noil)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 5)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (Non-oil):", speed))
print(paste("Implied halflife of unconditional (Non-oil):", halfLife))
# Implied speed of convergence and halflife
speed = - log(1+coef(cc_int)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 4)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (Intermediate):", speed))
print(paste("Implied halflife of unconditional (Intermediate):", halfLife))
# Implied speed of convergence and halflife
speed = -log(1+coef(cc_oecd)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 4)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (OECD):", speed))
print(paste("Implied halflife of unconditional (OECD):", halfLife))
Augmented conditional convergence
augcc_noil <- lm(ln_gdp_growth ~ ln_gdp_60 + ln_inv_gdp + ln_ndg + ln_school, data = non_oil)
augcc_int <- lm(ln_gdp_growth ~ ln_gdp_60 + ln_inv_gdp + ln_ndg + ln_school, data = intermediate)
augcc_oecd <- lm(ln_gdp_growth ~ ln_gdp_60 + ln_inv_gdp + ln_ndg + ln_school, data = oecd)
stargazer(augcc_noil, augcc_int, augcc_oecd, digits=2, type = "text",
column.labels = c("Non-Oil",
"Intermediate",
"OECD"),
covariate.labels = c("log(GDP '60)",
"log(I / GDP)",
"log(n+delta+g)",
"log(school)",
"Constant"),
dep.var.labels = "Log(GDP '85) - Log(GDP '60)",
omit.stat = c("f",
"rsq",
"ser"),
title = "Table 5 - Augmented Conditional Convergence",
style = "qje")
Implied speed of convergence
# Implied speed of convergence and halflife
speed = -log(1+coef(augcc_noil)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 4)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (Non-oil):", speed))
print(paste("Implied halflife of unconditional (Non-oil):", halfLife))
# Implied speed of convergence and halflife
speed = - log(1+coef(augcc_int)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 4)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (Intermediate):", speed))
print(paste("Implied halflife of unconditional (Intermediate):", halfLife))
# Implied speed of convergence and halflife
speed = -log(1+coef(augcc_oecd)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 4)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (OECD):", speed))
print(paste("Implied halflife of unconditional (OECD):", halfLife))
Restricted augmented conditional convergence
augcc_noil_r <- lm(ln_gdp_growth ~ ln_gdp_60 + I(ln_inv_gdp - ln_ndg) + I(ln_school - ln_ndg), data = non_oil)
augcc_int_r <- lm(ln_gdp_growth ~ ln_gdp_60 + I(ln_inv_gdp - ln_ndg) + I(ln_school - ln_ndg), data = intermediate)
augcc_oecd_r <- lm(ln_gdp_growth ~ ln_gdp_60 + I(ln_inv_gdp - ln_ndg) + I(ln_school - ln_ndg), data = oecd)
stargazer(augcc_noil_r, augcc_int_r, augcc_oecd_r, digits=3, type = "text",
column.labels = c("Non-Oil",
"Intermediate",
"OECD"),
covariate.labels = c("log(GDP '60)",
"log(I / GDP) - log(n+delta+g)",
"log(school) - log(n+delta+g)",
"Constant"),
dep.var.labels = "Log(GDP '85) - Log(GDP '60)",
omit.stat = c("f",
"rsq",
"ser"),
title = "Table 6 - Restricted Augmented Conditional Convergence",
style = "qje")
Test of restriction
linearHypothesis(augcc_noil, "ln_inv_gdp + ln_ndg + ln_school = 0")
linearHypothesis(augcc_int, "ln_inv_gdp + ln_ndg + ln_school = 0")
linearHypothesis(augcc_oecd, "ln_inv_gdp + ln_ndg + ln_school = 0")
Implied speed of convergence
# Implied speed of convergence and halflife
speed = -log(1+coef(augcc_noil_r)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 4)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (Non-oil):", speed))
print(paste("Implied halflife of unconditional (Non-oil):", halfLife))
# Implied speed of convergence and halflife
speed = -log(1+coef(augcc_int_r)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 4)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (Intermediate):", speed))
print(paste("Implied halflife of unconditional (Intermediate):", halfLife))
# Implied speed of convergence and halflife
speed = -log(1+coef(augcc_oecd_r)[2])/(1985-1960)
halfLife = log(2)/speed
speed = round(speed, 4)
halfLife = round(halfLife)
print(paste("Implied speed of unconditional (OECD):", speed))
print(paste("Implied halflife of unconditional (OECD):", halfLife))
Figures: Unconditional vs conditional convergence
ggplot(intermediate, aes(x = ln_gdp_60, y = ln_gdp_growth)) +
geom_point(shape = 1) +
geom_smooth(method=lm, se=FALSE, color = "red") +
theme_bw() +
ggtitle("A: Unconditional") +
ylab("Log Growth rate: 1960 - 85") +
xlab("Log output per working age adult: 1960")
y2 <- lm(ln_gdp_growth ~ ln_inv_gdp + ln_ndg, data = intermediate)$residuals
x2 <- lm(ln_gdp_60 ~ ln_inv_gdp + ln_ndg, data = intermediate)$residuals
panel_b <- tibble(y2, x2)
ggplot(panel_b, aes(x = x2, y = y2)) +
geom_point(shape = 1) +
geom_smooth(method=lm, se=FALSE, color = "red") +
theme_bw() +
ggtitle("B: Conditional on Saving and Population Growth") +
ylab("Log Growth rate: 1960 - 85") +
xlab("Log output per working age adult: 1960")
y3 <- lm(ln_gdp_growth ~ ln_inv_gdp + ln_ndg + ln_school, data = intermediate)$residuals
x3 <- lm(ln_gdp_60 ~ ln_inv_gdp + ln_ndg + ln_school, data = intermediate)$residuals
panel_c <- tibble(y3, x3)
ggplot(panel_c, aes(x = x3, y = y3)) +
geom_point(shape = 1) +
geom_smooth(method=lm, se=FALSE, color = "red") +
theme_bw() +
ggtitle("C: Conditional on Saving and Population Growth and Human Capital") +
ylab("Log Growth rate: 1960 - 85") +
xlab("Log output per working age adult: 1960")