Back to Legewie's Bali natural experiment — but this time across ten countries. Was the effect of the terror attack on xenophobia the same everywhere, or did it depend on the country? That is an interaction between the treatment and country.
pacman::p_load(tidyverse, haven, estimatr, modelsummary)
ESS_raw <- read_dta("Legewie_ESS_02.dta") # from your project folder
event_date <- as.Date("2002-10-13") # the Bali attack
win_begin <- as.Date("2002-09-14")
win_end <- as.Date("2002-10-20")
ESS <- ESS_raw %>%
mutate(
int_date = as.Date(sprintf("%s-%s-%s", inwyr, inwmm, inwdd)),
treat = case_when(
int_date > event_date & int_date <= win_end ~ "After the attack",
int_date < event_date & int_date > win_begin ~ "Before the attack",
TRUE ~ NA_character_) %>% fct_relevel("Before the attack", "After the attack"),
anti_immi = rowMeans(across(c(imtcjob, imbleco, imbgeco, imueclt,
imwbcnt, imwbcrm, imbghct)), na.rm = TRUE) %>%
scale() %>% as.numeric(),
anti_immi = max(anti_immi, na.rm = TRUE) - anti_immi,
across(c(brncntr, mocntr, facntr), as_factor),
age = inwyr - yrbrn,
empl_stat = case_when(
pdwrk == 1 ~ "Working", uempla == 1 ~ "Unemployed",
rtrd == 1 ~ "Retired", TRUE ~ "Other"),
pspwght = pweight * dweight
) %>%
filter(!cntry %in% c("DK", "IL", "HU") & # keep 10 countries
brncntr == "yes" & mocntr == "yes" & facntr == "yes") %>%
select(treat, anti_immi, cntry, pspwght, age, empl_stat) %>%
drop_na() %>%
mutate(cntry = fct_relevel(cntry, "PT")) # Portugal = reference
pacman::p_load(...) run without red errors? Fix
that first.read_dta() can't find the file?
Legewie_ESS_02.dta must sit in your project
folder.Predict before you compute. You are about to fit
anti_immi ~ treat * cntry. In that model, what will the
plain treatAfter the attack coefficient represent?
Fit the interaction and look at whether the country-specific terms differ from Portugal.
lm_robust(anti_immi ~ treat * cntry, data = ESS, weights = pspwght)
— the treat:cntryXX rows are how much each country's effect
differs from Portugal's.
ols_int <- lm_robust(anti_immi ~ treat * cntry, data = ESS, weights = pspwght)
modelsummary(list("Xenophobia" = ols_int),
stars = TRUE, gof_map = c("nobs", "r.squared"),
output = "kableExtra")
Compared with Portugal, are the effects in the other countries mostly weaker or stronger?
Read a main term. What was the effect of the Bali attack in Portugal (the reference)?
Read a conditional effect. The effect in
Slovenia (SI) is the Portugal effect
plus the treatAfter the attack:cntrySI interaction
term. Compute it:
coef(ols_int)["treatAfter the attack"] +
coef(ols_int)["treatAfter the attack:cntrySI"]
# comment
explaining, in plain words, what a significant
treat:cntryXX interaction means — then
compare:A significant treat:cntryXX term means the effect of the
Bali attack in country XX was significantly different
from its effect in Portugal — the attack's impact on xenophobia
depended on the country. Because most of these terms
are negative and significant, the strong Portuguese reaction was
unusual: in most other countries the same attack moved xenophobia much
less, or not at all. The interaction is what lets one model carry ten
different effects at once.
age and
empl_stat as additive controls to the interaction model. Do
the country differences survive?ols_int2 <- lm_robust(anti_immi ~ treat * cntry + age + empl_stat,
data = ESS, weights = pspwght)
modelsummary(list("No controls" = ols_int, "+ controls" = ols_int2),
stars = TRUE, gof_map = c("nobs"), output = "kableExtra")
The interaction pattern is broadly robust — some countries even
become statistically indistinguishable from Portugal once age and
employment are held constant. Note you can freely mix an
interaction (treat * cntry) with ordinary
additive controls (+ age + empl_stat) in
the same model.
Discuss with your neighbour.