Same ESS data as exercise 1 (Denmark & Bulgaria; run that setup first). In exercise 1 you fitted a polynomial of age. Now you try the log₂ transformation instead — and decide which you prefer.
log2(agea), keeping the same controls, weighted by
pspwght.lm_robust(imwbcnt ~ cntry + gndr + eduyrs + log2(agea), data = ESS, weights = pspwght)
ols_log <- lm_robust(imwbcnt ~ cntry + gndr + eduyrs + log2(agea),
data = ESS, weights = pspwght)
modelsummary(list("Xenophobia" = ols_log),
coef_rename = c("log2(agea)" = "Age (log2)"),
stars = TRUE, gof_map = c("nobs", "r.squared"), output = "kableExtra")
The log2(agea) coefficient is
.
Because the predictor is on a log₂ scale, this reads
as: a doubling of age (say from 20 to 40, or 40 to 80)
is associated with about
scale points
.
Compare the two curves. Put the log₂ model next to the quadratic from exercise 1 and look at the fit statistics.
ols_poly <- lm_robust(imwbcnt ~ cntry + gndr + eduyrs + poly(I(agea / 10), 2, raw = TRUE),
data = ESS, weights = pspwght)
modelsummary(list("Quadratic" = ols_poly, "log2" = ols_log),
gof_map = c("nobs", "r.squared", "adj.r.squared"),
stars = TRUE, output = "kableExtra")
According to \(R^2\) and adjusted \(R^2\), which model fits better?
Given that the two fit about equally well, which would you report — and why?
Write one sentence as a # comment
justifying your choice — then compare:
The log₂ and quadratic models fit the age–xenophobia relationship about equally well (nearly identical \(R^2\) and adjusted \(R^2\)). When fit is a tie, prefer the simpler, more interpretable model: the log₂ needs a single coefficient and reads cleanly as "a doubling of age is associated with about 0.4 points more xenophobia", whereas the quadratic needs two coefficients and a turning point to interpret. The one reason to prefer the quadratic would be a genuine rise-then-fall in age — which we did not find here.
# 1. Fictional data spanning the observed ages, controls held constant
fict <- tibble(
agea = seq(15, 90, by = 1),
cntry = "Denmark",
gndr = "Female",
eduyrs = mean(ESS$eduyrs)
)
# 2. Predicted xenophobia + 95% interval
fict <- predict(ols_log, newdata = fict, interval = "confidence")$fit %>%
as_tibble() %>%
bind_cols(fict, .)
# 3. Plot
ggplot(fict, aes(x = agea, y = fit)) +
geom_ribbon(aes(ymin = lwr, ymax = upr), alpha = 0.25) +
geom_line(linewidth = 1, colour = "#901A1E") +
labs(x = "Age", y = "Predicted xenophobia (0–10)") +
theme_minimal()
The curve rises quickly among the young and flattens among the old — the signature shape of a log predictor.
log() is undefined at 0 and for negatives. Income with
zeros, counts that include 0, or anything centred around 0 cannot be
logged directly. Common fixes: add a small constant
(log(x + 1), i.e. log1p), or use a different
transformation. Age is safe because everyone is older than zero.
Discuss with your neighbour.
log2(agea) is 0.4." Why is "per
doubling" a more honest way to say this than "per
year"?