Did you know: the greater honeyguide, an African bird,
leads people to wild bees’ nests. People take
the honey, and the bird gets the leftover honeycomb.
Sources: Spottiswoode et al. (2016), Science; National Geographic
Lectures 6 and 7: several predictors, each with one effect.
An interaction: the effect of one predictor depends on the value of another. The lines are no longer parallel.
* adds both predictors and their interaction:
x and group are often called the main
effects, although with an interaction they are really simple effects (more below). x:group is
the interaction term: how much the effect of x changes from
one group to the other.
Interactions are common in linguistics: a frequency effect can be larger for L2 speakers, or a vowel can lengthen more before voiced consonants in one dialect than in another.
Did you know: Yao honey hunters in Mozambique call
honeyguides with a special brrr-hm. In
experiments, honeyguides were about twice as likely to start guiding
when they heard it than when they heard other sounds.
Sources: Spottiswoode et al. (2016), Science; National Geographic
A simulated lexical decision task with first-language
(L1) and second-language (L2) speakers:
set.seed(10)
lex <- tibble(group = rep(c("L1", "L2"), each = 200),
log_freq = runif(400, 1, 6)) |>
mutate(rt = if_else(group == "L1", 700 - 25 * log_freq,
900 - 55 * log_freq) + rnorm(400, 0, 40))In this simulation, frequency matters more for L2 speakers: −55 ms per log unit, against −25 ms for L1 speakers.
Two different slopes. Can last week’s model capture that?
(Intercept) log_freq groupL2
768.58134 -44.00400 92.00191
One slope for both groups: too shallow for L2, too steep for L1.
(Intercept) log_freq groupL2 log_freq:groupL2
711.46630 -27.05222 201.53411 -31.43419
| Coefficient | What it is |
|---|---|
(Intercept) |
the L1 reaction time at
log_freq = 0 |
log_freq |
the frequency slope for the reference group, L1 |
groupL2 |
the L2 minus L1 difference, at
log_freq = 0 |
log_freq:groupL2 |
how much steeper the frequency slope is for L2 |
L2 slope = -27.1 + (-31.4) = -58.5 ms per log unit.
groupL2 = 202 ms: is that the L1–L2 difference?
Only at log_freq = 0, a frequency that does not exist in
our data (1 to 6).
With an interaction, each lower-order coefficient is a simple effect: the effect of one predictor when the other is 0 (or at its reference level).
From lecture 5: centre the continuous predictor, so that 0 means “average frequency”.
lex <- lex |> mutate(log_freq_c = log_freq - mean(log_freq))
coef(lm(rt ~ log_freq_c * group, data = lex)) (Intercept) log_freq_c groupL2
616.93726 -27.05222 91.69311
log_freq_c:groupL2
-31.43419
groupL2 is now the L1–L2 difference for a word of
average frequency, which is what most readers expect it to mean. The
slope and the interaction do not change.
additive interaction
0.7078173 0.7709118
Adjusted R² goes up: separate slopes describe these data better. Whether the interaction is reliable beyond this sample is a question for inference, later in the course.
Did you know: Hadza hunters in Tanzania whistle instead. Honeyguides in Tanzania were over
three times more likely to cooperate with the Hadza whistle than with
the Yao call, and in Mozambique almost twice as likely with the Yao
call: the effect of the call depends on the place.
Source: Spottiswoode & Wood (2023), Science
Vowel duration by voicing of the following consonant and
speaking style, simulated:
set.seed(11)
cells <- tribble(
~style, ~voicing, ~mu,
"casual", "voiceless", 110,
"casual", "voiced", 145,
"clear", "voiceless", 125,
"clear", "voiced", 180
)
vs <- cells |>
uncount(40) |> # 40 tokens per cell
mutate(duration = round(rnorm(n(), mu, 18)),
voicing = fct_relevel(voicing, "voiceless")) |>
select(-mu)# A tibble: 4 × 3
style voicing mean
<chr> <fct> <dbl>
1 casual voiceless 104.
2 casual voiced 146.
3 clear voiceless 125.
4 clear voiced 182.
Clear speech lengthens vowels, more so before voiced consonants: the lines are not parallel.
(Intercept) voicingvoiced
104.175 41.525
styleclear voicingvoiced:styleclear
20.675 15.425
| Coefficient | Meaning |
|---|---|
(Intercept) |
mean of voiceless, casual (both reference levels) |
voicingvoiced |
voicing effect in casual speech only |
styleclear |
style effect for voiceless only |
voicingvoiced:styleclear |
how much bigger the voicing effect is in clear speech |
b <- coef(m_vs)
c(voiceless_casual = b[[1]],
voiced_casual = b[[1]] + b[[2]],
voiceless_clear = b[[1]] + b[[3]],
voiced_clear = b[[1]] + b[[2]] + b[[3]] + b[[4]])voiceless_casual voiced_casual voiceless_clear voiced_clear
104.175 145.700 124.850 181.800
The interaction coefficient is added only in the cell where both non-reference levels meet.
vs_sum <- vs |> mutate(style = factor(style))
contrasts(vs_sum$voicing) <- contr.sum(2)
contrasts(vs_sum$style) <- contr.sum(2)
coef(lm(duration ~ voicing * style, data = vs_sum)) (Intercept) voicing1 style1 voicing1:style1
139.13125 -24.61875 -14.19375 3.85625
voicing1, style1: effects
averaged over the other predictor, the classic main effectsWith treatment coding, each effect describes the reference level of the other predictor: the voicing effect in casual speech. With sum coding, each effect is averaged over the levels of the other predictor: the voicing effect across both styles.
With interactions, always check which coding you used before interpreting a “main effect”.
Did you know: honeyguides lay their eggs in other birds’
nests. The chick hatches with a hooked bill,
which it uses to kill its foster nest-mates.
Source: University of Cape Town, FitzPatrick Institute
Back to word frequency and length, simulated, now with an interaction:
set.seed(12)
w <- tibble(log_freq = runif(400, 1, 6),
length = round(runif(400, 3, 12))) |>
mutate(lf_c = log_freq - mean(log_freq),
len_c = length - mean(length),
rt = 760 - 30 * lf_c + 14 * len_c - 5 * lf_c * len_c + rnorm(400, 0, 40))The interaction term multiplies the two predictors: here, length matters less for frequent words.
(Intercept) log_freq length log_freq:length
620.941597 9.734164 31.430518 -5.103751
The frequency slope is positive? It is the effect of frequency for a word of length 0.
The effect of length at three frequencies. Compare lecture 6: the lines now fan out.
Without an interaction, the contour lines were straight and parallel (lecture 6). With one, they bend: the plane is twisted.
Did you know: in Niassa National Reserve, Mozambique,
75% of the bees’ nests that Yao honey hunters
found were found with the help of a honeyguide.
Source: Spottiswoode, Begg & Begg (2016), Science
expands to 7 coefficients beyond the intercept:
a,
b and ca:b,
a:c and b:ca:b:c:
the interaction between a and b changes with
cThree-way interactions are hard to interpret and need a lot of data. Include them only when your research question asks for one.
With palmerpenguins::penguins, after
drop_na():
body_mass_g by
flipper_length_mm * species. Plot the fitted lines.body_mass_g by
species * sex, first with treatment coding, then with sum
coding. Interpret the intercept of each.pengs <- palmerpenguins::penguins |>
drop_na(body_mass_g, flipper_length_mm, sex) |>
mutate(flipper_c = flipper_length_mm - mean(flipper_length_mm))
b_p <- coef(lm(body_mass_g ~ flipper_length_mm * species, data = pengs))
b_p (Intercept) flipper_length_mm
-2508.08774 32.68891
speciesChinstrap speciesGentoo
-529.10803 -4166.11653
flipper_length_mm:speciesChinstrap flipper_length_mm:speciesGentoo
1.88448 21.47651
[1] 54.16542
(Intercept) flipper_c
4061.30417 32.68891
speciesChinstrap speciesGentoo
-150.38985 149.95200
flipper_c:speciesChinstrap flipper_c:speciesGentoo
1.88448 21.47651
(Intercept) speciesChinstrap
3368.8356 158.3703
speciesGentoo sexmale
1310.9058 674.6575
speciesChinstrap:sexmale speciesGentoo:sexmale
-262.8928 130.4372
pengs_sum <- pengs
contrasts(pengs_sum$species) <- contr.sum(3)
contrasts(pengs_sum$sex) <- contr.sum(2)
coef(lm(body_mass_g ~ species * sex, data = pengs_sum)) (Intercept) species1 species2 sex1 species1:sex1
4173.84711 -467.68273 -440.75888 -315.25282 -22.07595
species2:sex1
109.37047
Treatment: the intercept is the mean of female Adelie penguins. Sum: the grand mean of the six species × sex cells.
y ~ x * z =
x + z + x:zThese slides
mcanzi.de/ws26_statistics/
Code, data and all lectures
github.com/mcanzi/ws26_statistics