library(haven)
library(dplyr)
library(tidyr)
library(psych)
library(GPArotation)
library(knitr)
# library(plm)
library(sandwich)
library(lmtest)
library(broom)
library(purrr)
library(readr)
Chapter 3: Immigration Policy and Two Eras of Globalization
Required packages
Read data
I downloaded D131F01 D131F03, D131F04, and D131F05 from the browser and put it in data/
.
Peter’s code
use "data_opentrade_closedborders_replication_cleanedup.dta", clear
set more off
Pacha’s code
<- read_dta("data/Peters_WP_2015_data_opentrade_closedborders_replication_cleanedup.dta") peters2015
Table A14: Factor loadings
Peter’s code
factor natcode skillcode qcode reccode labcode famcode refcode asylcode citcode
decode encode, pcf factors(2)
rightscode
predict immipol imrights
Pacha’s code
# subset, otherwise the NAs in the data break the correlation matrix
<- c(
vars "natcode", "skillcode", "qcode", "reccode", "labcode", "famcode",
"refcode", "asylcode", "citcode", "rightscode", "decode", "encode"
)
<- peters2015 %>%
peters2015_factor select(all_of(vars)) %>%
drop_na()
# fa(..., fm = "pa") uses principal factor
# principal(...) uses principal component
<- principal(
principal_axis r = peters2015_factor, nfactors = 2, rotate = "none"
)
# predict immipol and imrights
<- predict(
peters2015_predictions
principal_axis,data = select(peters2015, all_of(vars))
)
<- peters2015 %>%
peters2015 mutate(
immipol = peters2015_predictions[, 1],
imrights = peters2015_predictions[, 2]
)
# final table
<- principal_axis$loadings
loadings
<- tibble(
table3 variable = rownames(loadings),
factor1 = loadings[, 1],
factor2 = loadings[, 2],
uniqueness = principal_axis$uniqueness
)
kable(
%>%
table3 mutate_if(is.numeric, round, 4) %>%
rename(
Variable = variable,
`Factor Loading Immigration Policy` = factor1,
`Factor Loading Rights of Immigrants` = factor2,
Uniqueness = uniqueness
) )
Variable | Factor Loading Immigration Policy | Factor Loading Rights of Immigrants | Uniqueness |
---|---|---|---|
natcode | 0.3868 | 0.1451 | 0.8293 |
skillcode | 0.7438 | -0.0364 | 0.4455 |
qcode | 0.4278 | -0.4310 | 0.6313 |
reccode | 0.5485 | 0.0713 | 0.6940 |
labcode | 0.4264 | 0.5465 | 0.5195 |
famcode | -0.6910 | 0.4365 | 0.3321 |
refcode | -0.4836 | 0.6175 | 0.3849 |
asylcode | -0.4526 | 0.4400 | 0.6016 |
citcode | 0.2434 | 0.6050 | 0.5747 |
rightscode | 0.4569 | 0.6360 | 0.3868 |
decode | 0.7410 | 0.4097 | 0.2831 |
encode | 0.7463 | -0.0790 | 0.4368 |
Table 3.2: Immigration Policy Regressed on Trade Policy by Era
Peter’s code:
set more off
clear
eststo xtreg immipol imports_free ltime_trend politycl mad_gdpgrowth war ibn.year, fe vce(robust)
eststo: xtreg immipol imports_free ltime_trend politycl mad_gdpgrowth war ibn.year if year<=1879, fe vce(robust)
eststo: xtreg immipol imports_free ltime_trend politycl mad_gdpgrowth war ibn.year if year>1879 & year<1914, fe vce(robust)
eststo: xtreg immipol imports_free ltime_trend politycl mad_gdpgrowth war ibn.year if year>=1914 & year<=1945, fe vce(robust)
eststo: xtreg immipol imports_free ltime_trend politycl mad_gdpgrowth war ibn.year if year>1945 & year<=1972, fe vce(robust)
eststo: xtreg immipol imports_free ltime_trend politycl mad_gdpgrowth war ibn.year if year>1972, fe vce(robust)
eststo: xtreg immipol imports_free ltime_trend politycl mad_gdpgrowth war ibn.year if year>1972 & ccode!=160, fe vce(robust)
eststo: using trade_only_by_eras.rtf, label b(2) se(2) star(+ 0.10 * 0.05 ** 0.01 *** 0.001) ///
esttab title(Immigration policy regressed on trade policy by era \label{tab:era}) ///
"All Years" "Pre-Globalization" "19th Cen. Globalization" "Interwar" "Bretton Woods" "Post Bretton Woods" "Post Bretton Woods, No Argentina" ) ///
mtitles(replace nogaps r2(2)
Pacha’s code
<- list(
year_range c(-Inf, Inf, "all_years"),
c(-Inf, 1879, "pre_globalization"),
c(1879, 1914, "cen19_globalization"),
c(1914, 1945, "interwar"),
c(1946, 1972, "bretton_woods"),
c(1973, Inf, "post_bretton_woods"),
c(1973, Inf, "post_bretton_woods_no_argentina")
)
<- map_df(
all_models
year_range,function(y) {
print(y)
<- peters2015 %>%
peters2015_subset filter(year >= y[1] & year <= y[2])
if (y[3] == "post_bretton_woods_no_argentina") {
<- peters2015_subset %>%
peters2015_subset filter(ccode != 160)
}
# peters2015_subset <- pdata.frame(
# peters2015_subset,
# index = c("ccode", "year")
# )
# fml <- immipol ~ imports_free + ltime_trend + politycl + mad_gdpgrowth +
# war
<- immipol ~ imports_free + ltime_trend + politycl + mad_gdpgrowth +
fml + as.factor(ccode) + as.factor(year)
war
# similar r-sq, different slopes
# fit <- plm(fml, data = peters2015_subset, model = "within")
# very different r2, same slopes and I get the "grand mean"
# very close numbers :)
<- lm(fml, data = peters2015_subset)
fit
# rse <- coeftest(fit, vcov = vcovHC(fit, type = "HC1", cluster = "group"))
<- coeftest(
rse
fit,vcov = vcovCL(fit, cluster = peters2015_subset[, "ccode"])
)
# remove factor variables
<- rse %>%
rse tidy() %>%
filter(!grepl("factor", term))
<- rse %>%
out mutate(
model = y[3],
sign = case_when(
< 0.001 ~ "***",
p.value < 0.01 ~ "**",
p.value < 0.05 ~ "*",
p.value < 0.1 ~ "+",
p.value TRUE ~ ""
),estimate = paste0(
round(estimate, 2), sign, " (", round(std.error, 2),
")"
)
)
<- fit %>%
out2 glance() %>%
select(adj.r.squared, nobs) %>%
mutate(
adj.r.squared = round(adj.r.squared, 2),
model = y[3]
%>%
) pivot_longer(adj.r.squared:nobs,
names_to = "term",
values_to = "estimate"
%>%
) mutate(estimate = as.character(estimate))
%>%
out bind_rows(out2) %>%
select(term, model, estimate)
} )
[1] "-Inf" "Inf" "all_years"
[1] "-Inf" "1879" "pre_globalization"
[1] "1879" "1914" "cen19_globalization"
[1] "1914" "1945" "interwar"
[1] "1946" "1972" "bretton_woods"
[1] "1973" "Inf" "post_bretton_woods"
[1] "1973" "Inf"
[3] "post_bretton_woods_no_argentina"
<- all_models %>%
all_models pivot_wider(names_from = model, values_from = estimate)
# auxiliary table for the final presentation
<- all_models %>%
all_models_aux select(term) %>%
mutate(
term2 = case_when(
== "(Intercept)" ~ "Constant",
term == "imports_free" ~ "Trade openness",
term == "ltime_trend" ~ "Years since inclusion",
term == "politycl" ~ "Polity",
term == "mad_gdpgrowth" ~ "GDP growth",
term == "war" ~ "War",
term == "adj.r.squared" ~ "Adj. R-squared",
term == "nobs" ~ "N. obs"
term
)
)
<- all_models %>%
all_models left_join(all_models_aux, by = "term")
# final table ----
kable(
%>%
all_models select(term2, everything(), -term) %>%
rename(
`Variable` = term2,
`All Years` = all_years,
`Pre-Globalization` = pre_globalization,
`19th Cen. Globalization` = cen19_globalization,
`Interwar` = interwar,
`Bretton Woods` = bretton_woods,
`Post Bretton Woods` = post_bretton_woods,
`Post Bretton Woods, No Argentina` = post_bretton_woods_no_argentina
),align = c("l", rep("r", 7))
)
Variable | All Years | Pre-Globalization | 19th Cen. Globalization | Interwar | Bretton Woods | Post Bretton Woods | Post Bretton Woods, No Argentina |
---|---|---|---|---|---|---|---|
Constant | 3.65*** (0.81) | 1.72 (1.28) | 2.6*** (0.66) | 5.7** (2.12) | -3.33+ (1.77) | 1.55 (1.28) | 3.48*** (0.9) |
Trade openness | -3.04*** (0.9) | -1.81* (0.71) | -1.71** (0.6) | -3.25+ (1.69) | -1.27* (0.56) | -1.33 (1.22) | -3.6** (1.15) |
Years since inclusion | -0.01*** (0) | 0 (0.01) | -0.03*** (0) | -0.03*** (0.01) | 0.02 (0.01) | -0.01*** (0) | -0.01** (0) |
Polity | 0.01 (0.01) | 0.06* (0.02) | 0.15+ (0.09) | 0.02 (0.02) | 0.02+ (0.01) | 0.01+ (0) | 0.01 (0.01) |
GDP growth | 0.17 (0.16) | 0.18 (0.18) | 0.27** (0.09) | -0.16 (0.33) | 0.03 (0.36) | 0.16 (0.18) | 0.01 (0.16) |
War | 0.17 (0.12) | 0.96+ (0.56) | -0.02 (0.07) | 0.2 (0.22) | -0.01 (0.1) | -0.03 (0.04) | -0.03 (0.04) |
Adj. R-squared | 0.8 | 0.97 | 0.88 | 0.67 | 0.91 | 0.85 | 0.88 |
N. obs | 1577 | 77 | 314 | 298 | 325 | 580 | 548 |
Table 3.3: Effect of Trade Policy Lagged on Immigration Policy by Era
I can recycle parts of the replication for Table 3.2.
<- map_df(
all_models
year_range,function(y) {
print(y)
<- peters2015 %>%
peters2015_subset filter(year >= y[1] & year <= y[2])
if (y[3] == "post_bretton_woods_no_argentina") {
<- peters2015_subset %>%
peters2015_subset filter(ccode != 160)
}
# compute lags
<- peters2015_subset %>%
peters2015_subset arrange(ccode, year) %>%
group_by(ccode) %>%
mutate(
imports_free_l1 = lag(imports_free, 1),
imports_free_l5 = lag(imports_free, 5)
%>%
) ungroup()
<- immipol ~ 0 + imports_free_l1 + ltime_trend +
fml1 + mad_gdpgrowth + war + as.factor(ccode) + as.factor(year)
politycl
<- immipol ~ 0 + imports_free_l5 + ltime_trend +
fml5 + mad_gdpgrowth + war + as.factor(ccode) + as.factor(year)
politycl
# very close numbers :)
<- lm(fml1, data = peters2015_subset)
fit1 <- lm(fml5, data = peters2015_subset)
fit5
<- coeftest(
rse1
fit1,vcov = vcovCL(fit1, cluster = peters2015_subset[, "ccode"])
)
<- coeftest(
rse5
fit5,vcov = vcovCL(fit5, cluster = peters2015_subset[, "ccode"])
)
# remove factor variables
<- rse1 %>%
rse tidy() %>%
filter(!grepl("factor", term)) %>%
bind_rows(
%>%
rse5 tidy() %>%
filter(!grepl("factor", term))
%>%
) filter(term %in% c("imports_free_l1", "imports_free_l5"))
<- rse %>%
out mutate(
model = y[3],
sign = case_when(
< 0.001 ~ "***",
p.value < 0.01 ~ "**",
p.value < 0.05 ~ "*",
p.value < 0.1 ~ "+",
p.value TRUE ~ ""
),estimate = paste0(
round(estimate, 2), sign, " (", round(std.error, 2),
")"
)
)
%>%
out select(term, model, estimate)
} )
[1] "-Inf" "Inf" "all_years"
[1] "-Inf" "1879" "pre_globalization"
[1] "1879" "1914" "cen19_globalization"
[1] "1914" "1945" "interwar"
[1] "1946" "1972" "bretton_woods"
[1] "1973" "Inf" "post_bretton_woods"
[1] "1973" "Inf"
[3] "post_bretton_woods_no_argentina"
<- all_models %>%
all_models pivot_wider(names_from = model, values_from = estimate)
# auxiliary table for the final presentation
<- all_models %>%
all_models_aux select(term) %>%
mutate(
term2 = case_when(
== "imports_free_l1" ~ "One-year lag",
term == "imports_free_l5" ~ "Five-year lag"
term
)
)
<- all_models %>%
all_models left_join(all_models_aux, by = "term")
# final table ----
kable(
%>%
all_models select(term2, everything(), -term) %>%
rename(
`Variable` = term2,
`All Years` = all_years,
`Pre-Globalization` = pre_globalization,
`19th Cen. Globalization` = cen19_globalization,
`Interwar` = interwar,
`Bretton Woods` = bretton_woods,
`Post Bretton Woods` = post_bretton_woods,
`Post Bretton Woods, No Argentina` = post_bretton_woods_no_argentina
),align = c("l", rep("r", 7))
)
Variable | All Years | Pre-Globalization | 19th Cen. Globalization | Interwar | Bretton Woods | Post Bretton Woods | Post Bretton Woods, No Argentina |
---|---|---|---|---|---|---|---|
One-year lag | -3.09*** (0.88) | -1.39 (0.88) | -1.67** (0.61) | -3.3* (1.63) | -1.52** (0.51) | -1.42 (1.04) | -3.2** (1.08) |
Five-year lag | -3.05*** (0.74) | -1.05 (0.86) | -0.8 (0.63) | -2.1 (1.35) | -1.45* (0.57) | 0.1 (1.01) | -1.25 (1.14) |
Table 3.4: Effect of Trade Policy on Immigration Policy by Era and Economy Type
From page 54:
- Large economies: Argentina, Australia, Canada, Brazil, France, Germany, Japan, the United Kingdom, and the United States.
- Small open economies: Hong Kong, the Netherlands, New Zealand, Singapore, South Korea, Switzerland, and Taiwan.
- Resource economies: Kuwait, Saudi Arabia, and South Africa.
# I need to use ccode, there are missing values in countrynm
sort(unique(peters2015$countrynm))
[1] "" "Argentina" "Australia" "Brazil" "Canada"
[6] "France" "Germany" "Hong Kong" "Japan" "Kuwait"
[11] "Netherlands" "New Zealand" "Saudi Arabia" "Singapore" "South Africa"
[16] "South Korea" "Switzerland" "Taiwan" "UK" "US"
# I need to know the ccode
# The PDF in data mentions COW
# Hong Kong = 711 is not in COW
<- "https://correlatesofwar.org/wp-content/uploads/COW-country-codes.csv"
cowurl <- "data/COW-country-codes.csv"
cowfile
if (!file.exists(cowfile)) {
download.file(cowurl, cowfile)
}
<- read_csv(cowfile) %>%
cow select(ccode = `CCode`, state = `StateNme`) %>%
distinct() %>%
mutate(
economy_type = case_when(
%in% c(
state "Argentina", "Australia", "Canada", "Brazil", "France", "Germany",
"Japan", "United Kingdom", "United States of America"
~ "large",
) %in% c(
state "Hong Kong SAR", "Netherlands", "New Zealand", "Singapore",
"South Korea", "Switzerland", "Taiwan"
~ "small_open",
) %in% c(
state "Kuwait", "Saudi Arabia", "South Africa"
~ "resource"
)
)%>%
) filter(!is.na(economy_type)) %>%
bind_rows(
tibble(
ccode = 711,
state = "Hong Kong",
economy_type = "small_open"
)
)
# verify
# filter(cow, economy_type == "large")
# filter(cow, economy_type == "small_open")
# filter(cow, economy_type == "resource")
<- peters2015 %>%
peters2015 left_join(cow, by = "ccode")
# page 57
# small economy: the sum of the coefficient on trade openness and
# the interaction term of small economies with trade opennness
# resource economy: the sum of the coefficient on trade openness and
# the interaction term of resource economies with trade opennness
<- peters2015 %>%
peters2015 mutate(
large = ifelse(economy_type == "large", imports_free, 0),
small_open = ifelse(economy_type == "small_open", imports_free, 0),
resource = ifelse(economy_type == "resource", imports_free, 0)
)
<- map_df(
all_models
year_range,function(y) {
print(y)
<- peters2015 %>%
peters2015_subset filter(year >= y[1] & year <= y[2])
if (y[3] == "post_bretton_woods_no_argentina") {
<- peters2015_subset %>%
peters2015_subset filter(ccode != 160)
}
<- peters2015_subset %>%
peters20215_subset_large filter(economy_type == "large")
<- immipol ~ 0 + imports_free + ltime_trend + politycl +
fml1 + war + as.factor(ccode) + as.factor(year)
mad_gdpgrowth
<- immipol ~ 0 + small_open + imports_free + ltime_trend +
fml2 + mad_gdpgrowth + war + as.factor(ccode) + as.factor(year)
politycl
<- immipol ~ 0 + resource + imports_free + ltime_trend +
fml3 + mad_gdpgrowth + war + as.factor(ccode) + as.factor(year)
politycl
# very close numbers :)
<- lm(fml1, data = peters20215_subset_large)
fit1 <- lm(fml2, data = peters2015_subset)
fit2 <- lm(fml3, data = peters2015_subset)
fit3
<- vcovCL(fit1, cluster = peters20215_subset_large[, "ccode"])
vcov1 <- vcovCL(fit2, cluster = peters2015_subset[, "ccode"])
vcov2 <- vcovCL(fit3, cluster = peters2015_subset[, "ccode"])
vcov3
<- coeftest(fit1, vcov = vcov1)
rse1 <- coeftest(fit2, vcov = vcov2)
rse2 <- coeftest(fit3, vcov = vcov3)
rse3
<- rse2 %>%
rse2 tidy() %>%
filter(term == "small_open")
<- rse3 %>%
rse3 tidy() %>%
filter(term == "resource")
if (nrow(rse2) > 0) {
<- sqrt(vcov2["small_open", "small_open"] +
se2 "imports_free", "imports_free"] +
vcov2[2 * vcov2["small_open", "imports_free"])
<- 2 * (1 - pnorm(abs(sum(coef(fit2)[
pv2 c("small_open", "imports_free")
/ se2)))
])
<- rse2 %>%
rse2 bind_rows(
%>%
rse1 tidy() %>%
filter(term == "imports_free")
%>%
) mutate(term = "Small economies") %>%
group_by(term) %>%
summarise(
estimate = sum(estimate),
std.error = se2,
p.value = pv2
)
}
if (nrow(rse3) > 0) {
<- sqrt(vcov3["resource", "resource"] +
se3 "imports_free", "imports_free"] +
vcov3[2 * vcov3["resource", "imports_free"])
<- 2 * (1 - pnorm(abs(sum(coef(fit3)[
pv3 c("resource", "imports_free")
/ se3)))
])
<- rse3 %>%
rse3 bind_rows(
%>%
rse1 tidy() %>%
filter(term == "imports_free")
%>%
) mutate(term = "Resource economies") %>%
group_by(term) %>%
summarise(
estimate = sum(estimate),
std.error = se3,
p.value = pv3
)
}
# remove factor variables
<- rse1 %>%
rse tidy() %>%
filter(term == "imports_free") %>%
mutate(term = "Large economies") %>%
bind_rows(rse2) %>%
bind_rows(rse3)
<- rse %>%
out mutate(
model = y[3],
sign = case_when(
< 0.001 ~ "***",
p.value < 0.01 ~ "**",
p.value < 0.05 ~ "*",
p.value < 0.1 ~ "+",
p.value TRUE ~ ""
),estimate = paste0(
round(estimate, 2), sign, " (", round(std.error, 2),
")"
)
)
%>%
out select(term, model, estimate)
} )
[1] "-Inf" "Inf" "all_years"
[1] "-Inf" "1879" "pre_globalization"
[1] "1879" "1914" "cen19_globalization"
[1] "1914" "1945" "interwar"
[1] "1946" "1972" "bretton_woods"
[1] "1973" "Inf" "post_bretton_woods"
[1] "1973" "Inf"
[3] "post_bretton_woods_no_argentina"
<- all_models %>%
all_models pivot_wider(names_from = model, values_from = estimate)
kable(
%>%
all_models rename(
`Variable` = term,
`All Years` = all_years,
`Pre-Globalization` = pre_globalization,
`19th Cen. Globalization` = cen19_globalization,
`Interwar` = interwar,
`Bretton Woods` = bretton_woods,
`Post Bretton Woods` = post_bretton_woods,
`Post Bretton Woods, No Argentina` = post_bretton_woods_no_argentina
),align = c("l", rep("r", 7))
)
Variable | All Years | Pre-Globalization | 19th Cen. Globalization | Interwar | Bretton Woods | Post Bretton Woods | Post Bretton Woods, No Argentina |
---|---|---|---|---|---|---|---|
Large economies | -3.45*** (0.95) | -1.55+ (0.8) | -1.9** (0.69) | -3.47+ (1.84) | -1.67*** (0.49) | -1.27 (1.37) | -5.69+ (2.95) |
Small economies | -0.15 (0.83) | -2.11 (1.47) | -0.73 (0.82) | -7.12*** (1.28) | 0.95** (0.34) | -1.88 (1.23) | -3.22 (1.35) |
Resource economies | 1.16 (1.64) | NA | NA | NA | -4.28*** (0.93) | -5.68*** (0.69) | -8.04*** (0.77) |