Today we ask a new question of the same data: do better-educated Danes trust the police more? — and does the answer depend on whether we use weights?
pacman::p_load(tidyverse, haven, estimatr, modelsummary)
ESS <- read_spss("ESS9e03_1.sav") %>%
filter(cntry == "DK") %>%
select(idno, pspwght, gndr, eduyrs, agea, psppsgva, trstlgl, trstplc) %>%
mutate(across(c(psppsgva, trstlgl, trstplc, pspwght), zap_labels),
eduyrs = pmin(pmax(eduyrs, 9), 21), # Censor education at 9 & 21
gndr = as_factor(gndr)) %>%
drop_na()
Stuck?
read_spss()can't find the file?ESS9e03_1.savmust sit in your project folder — download it from Absalon and check the Files pane in RStudio.- Did
pacman::p_load(...)run without red errors? Fix that first.- Odd results? Session → Restart R, then run your script from the top.
- Still stuck? Ask (and answer!) in the t-R-ouble forum on Absalon.
trstplc) on
years of education (eduyrs) with lm_robust(),
and read off the slope. A one-year increase in education goes with a
change in police trust of
(three digits; point or comma is fine).mod1 <- lm_robust(trstplc ~ eduyrs, data = ESS)
modelsummary(list("Trust in police" = mod1),
statistic = NULL, gof_map = c("nobs", "r.squared"))
| Trust in police | |
|---|---|
| (Intercept) | 7.530 |
| eduyrs | 0.033 |
| Num.Obs. | 1511 |
| R2 | 0.005 |
trstplc on
gndr.
mod2 <- lm_robust(trstplc ~ gndr, data = ESS)
modelsummary(list("Trust in police" = mod2),
statistic = NULL, gof_map = c("nobs", "r.squared"))
| Trust in police | |
|---|---|
| (Intercept) | 7.929 |
| gndrFemale | 0.159 |
| Num.Obs. | 1511 |
| R2 | 0.002 |
Predict before you compute: you are about to add survey weights to both models. What do you expect?
Rerun both regressions with
weights = pspwght and show all four models in one table. Do
the weights matter here?
mod1_w <- lm_robust(trstplc ~ eduyrs, data = ESS, weights = pspwght)
mod2_w <- lm_robust(trstplc ~ gndr, data = ESS, weights = pspwght)
modelsummary(
list("Edu (unw.)" = mod1, "Gender (unw.)" = mod2,
"Edu (wt.)" = mod1_w, "Gender (wt.)" = mod2_w),
statistic = NULL, gof_map = c("nobs", "r.squared"))
| Edu (unw.) | Gender (unw.) | Edu (wt.) | Gender (wt.) | |
|---|---|---|---|---|
| (Intercept) | 7.530 | 7.929 | 7.782 | 7.801 |
| eduyrs | 0.033 | 0.013 | ||
| gndrFemale | 0.159 | 0.323 | ||
| Num.Obs. | 1511 | 1511 | 1511 | 1511 |
| R2 | 0.005 | 0.002 | 0.001 | 0.008 |
# comment) on
whether weighting changed your conclusion. Then compare:Weighting nudged the coefficients only slightly and left the substantive story unchanged: better-educated people trust the police a little more, and the gender difference stays small. That the Danish ESS is already close to representative is exactly why weights move the numbers so little here — in a badly skewed sample they would matter far more.
Bonus (for the fast): how big are the ESS
weights? Summarise pspwght with summary() and
make a histogram. Which respondents get weights well above 1, and
why?
summary(ESS$pspwght)
ggplot(ESS, aes(x = pspwght)) +
geom_histogram(bins = 30) +
labs(x = "Post-stratification weight", y = "Count") +
theme_minimal()
Weights well above 1 belong to under-represented groups (e.g. younger, less-educated, harder-to-reach respondents): each such person "stands in" for several who were missed. Weights below 1 belong to over-represented groups. They cluster tightly around 1 because the ESS sample is already close to representative.