Acemoglu & Angrist (2000) had an idea. US federal states required children to have a minimum amount of schooling before they were allowed to work — and how much differed across states and changed over time. They argued that the exact year a given state reformed its child-labour law was essentially arbitrary. That gives us an instrument for schooling.
cl7,
cl8 and cl9 are dummies for living in a state
that required 7, 8 or 9 years of schooling. Collapse them into
one continuous variable, and make state of birth and
census year categorical.pacman::p_load(tidyverse, estimatr, ivreg, modelsummary, masteringmetrics)
data("child_labor", package = "masteringmetrics")
child_labor <- child_labor %>%
mutate(
# One continuous child-labour-law variable: 7, 8 or 9 required years
chld_lb_lw = case_when(
cl7 == 1 ~ 7,
cl8 == 1 ~ 8,
cl9 == 1 ~ 9
),
sob = factor(sob), # US state of birth
year = factor(year) # Census year
) %>%
drop_na(chld_lb_lw)
pacman::p_load(...) run without red errors?
ivreg is new this week — if it is missing, run
install.packages("ivreg") once.data() can't find child_labor? It ships
inside masteringmetrics, which is a GitHub
package — see About & setup on the course
website.Predict before you compute. The instrument is "how many years of schooling the law required". Before running anything: which sign do you expect for the first stage — the effect of the law on actual years of education?
Estimate the first stage. Regress
indEduc on the instrument, controlling for year of birth
(yob), census year (year) and state of birth
(sob).
lm_robust(indEduc ~ chld_lb_lw + yob + year + sob, data = child_labor)
first_stage <- lm_robust(indEduc ~ chld_lb_lw + yob + year + sob,
data = child_labor)
modelsummary(list("Years of education" = first_stage),
coef_map = c("chld_lb_lw" = "Required years of schooling"),
stars = TRUE, gof_map = c("nobs"), output = "kableExtra")
One extra year of required schooling translates into extra years of actual education. Call this \(\phi\).
lnwkwage is
the log weekly wage. Use the same controls.reduced_form <- lm_robust(lnwkwage ~ chld_lb_lw + yob + year + sob,
data = child_labor)
modelsummary(list("log weekly wage" = reduced_form),
coef_map = c("chld_lb_lw" = "Required years of schooling"),
stars = TRUE, gof_map = c("nobs"), output = "kableExtra")
One extra required year raises log wages by . Call this \(\rho\). This number is the causal effect of the law — not of education — .
Compute the Wald ratio by hand. Divide, and mind which goes on top.
\[\lambda = \frac{\rho}{\phi} = \;?\]
Your answer:
phi <- coef(first_stage)["chld_lb_lw"]
rho <- coef(reduced_form)["chld_lb_lw"]
rho / phi
ivreg(). Write
the 2SLS in one line. Remember: the controls must appear on
both sides of the |.The pattern is
ivreg(outcome ~ treatment + controls | instrument + controls, data = ...).
Here the treatment is indEduc and the instrument is
chld_lb_lw.
twosls <- ivreg(
lnwkwage ~ indEduc + yob + year + sob | chld_lb_lw + yob + year + sob,
data = child_labor
)
modelsummary(list("2SLS" = twosls),
coef_map = c("indEduc" = "Years of education"),
stars = TRUE, gof_map = c("nobs"), output = "kableExtra")
The 2SLS estimate is — compared with your hand-computed Wald ratio of 0.14. They are .
# comment
interpreting the 2SLS estimate in plain language, with units — then
compare:Among men whose schooling was actually changed by child-labour laws, one additional year of education raises weekly wages by about 14%. Because the estimate uses only the variation in schooling driven by the timing of state law reforms, it is not contaminated by ability or family background — provided that timing really was as-if random and affected wages only through schooling. Note this is a LATE: it describes compliers — children who would have left school earlier under a laxer law — not the population as a whole.
lnwkwage on indEduc with the same
controls. Which is larger, and does that match the ability-bias
prediction?ols <- lm_robust(lnwkwage ~ indEduc + yob + year + sob, data = child_labor)
modelsummary(list("OLS" = ols, "2SLS" = twosls),
coef_map = c("indEduc" = "Years of education"),
stars = TRUE, gof_map = c("nobs"), output = "kableExtra")
As in the lecture, the IV estimate comes out larger than OLS — the opposite of what simple ability bias predicts. The same three explanations apply: LATE versus ATE (compliers are people pushed through school by law, whose returns may be higher), measurement error in schooling biasing OLS toward zero, and instrument weakness.
Discuss with your neighbour. The whole design rests on one untestable claim.