Did you know: the peacock mantis shrimp smashes snail
shells with a club that reaches 14 to 23 metres per
second. The energy for the strike is stored in a saddle-shaped
spring in its limb.
Source: Patek, Korff & Caldwell (2004), Nature
Every data set in this course so far was simulated. We chose the true effects, generated the data, and checked whether the model found them again.
Today we turn that around. Before a study is run, the same kind of simulation can tell us how often a planned design would detect an effect of a given size: its power. From there we can work out how many participants and items we need.
{simr}Did you know: a mantis shrimp strike hits twice. The
club strikes first, and about 0.4 ms later the collapse of cavitation bubbles between club and shell delivers a
second force peak.
Source: Patek & Caldwell (2005), Journal of Experimental Biology
| No true effect | True effect | |
|---|---|---|
| p < .05 | Type I error (α, usually 5%) | correct: the probability is the power |
| p ≥ .05 | correct | Type II error (β) |
Power = 1 − β: the probability that a test rejects the null hypothesis when an effect of a given size exists. The usual target of 80% is an arbitrary convention (Green & MacLeod, 2016).
Only the sample sizes are under our control once the design and the effect of interest are fixed.
2,000 simulated studies with 20 participants per group. Only 15% are significant, and the significant positive estimates average 0.79 (dashed), 2.6 times the true effect (Gelman & Carlin, 2014).
If only significant results get published, published effects from underpowered studies are too large. Vasishth et al. (2018) ran seven direct replications of a psycholinguistic finding, with 268 participants in total. The original estimates turned out too noisy to be informative, and a larger-sample study gave a smaller effect.
A power analysis based on a published effect size then promises more power than the next study will have.
Did you know: peak impact forces of peacock mantis
shrimp strikes reached 1,501 newtons in one
study, thousands of times the animal’s body weight.
Source: Patek & Caldwell (2005), Journal of Experimental Biology
Because the effect exists in every simulated data set, every non-significant result is a Type II error (Green & MacLeod, 2016).
A two-group comparison with 30 participants per group and a true difference of 0.5 SD:
sim_p <- function(n, d) t.test(rnorm(n, d), rnorm(n, 0), var.equal = TRUE)$p.value
set.seed(1)
p <- replicate(2000, sim_p(n = 30, d = 0.5))
mean(p < 0.05)[1] 0.483
[1] 0.477841
The simulation agrees with the formula, up to simulation error.
For d = 0.5, about 64 participants per group reach 80% power.
Writing the simulation also forces us to state every assumption about effect sizes, variances and the design.
{simr}Did you know: some mantis shrimp have 12 types of colour photoreceptors, against three in
humans. In tests, they still told colours apart worse than humans
do.
Source: Thoen, How, Chiou & Marshall (2014), Science
We want to replicate the lexical decision study from lecture 1, and the question is the interaction: does word frequency matter more for L2 than for L1 speakers?
{simr} simulates from an
lmer() or glmer() model, refits it and tests a
fixed effect, many times (Green & MacLeod, 2016). The model can come
from a pilot study, or be built from scratch
with makeLmer()fixef<- sets the effect size;
extend() and powerCurve() vary the sample
sizeset.seed(2035)
participants <- tibble(participant = factor(sprintf("P%02d", 1:30)),
group = rep(c(-0.5, 0.5), 15),
p0 = rnorm(30, 0, 60), p1 = rnorm(30, 0, 12))
words <- tibble(word = factor(sprintf("w%02d", 1:40)),
freq_c = runif(40, 1, 6) - 3.5, w0 = rnorm(40, 0, 30))
pilot <- crossing(participants, words) |>
mutate(rt = 750 + p0 + w0 + 120 * group + (-30 - 20 * group + p1) * freq_c + rnorm(n(), 0, 70)) |>
select(participant, group, word, freq_c, rt)
m_pilot <- lmer(rt ~ freq_c * group + (1 + freq_c | participant) + (1 | word), data = pilot)
round(fixef(m_pilot), 1) (Intercept) freq_c group freq_c:group
756.4 -29.2 127.5 -29.1
group is coded −0.5 (L1) and 0.5 (L2), so
freq_c:group is the difference between the two frequency
slopes. The groups alternate, so any first k participants are
balanced.
The pilot estimate of the interaction is noisy, and it may be large by chance. Planning with it repeats the significance filter.
Instead, decide on the smallest effect of interest: the smallest difference that would matter for the theory. Here we say the slopes should differ by at least 10 ms per log unit.
Retrospective “observed power”, with the effect size taken from the data, gives misleading results (Hoenig & Heisey, 2001; Green & MacLeod, 2016). More on this at the end.
Power for predictor 'freq_c:group', (95% confidence interval):
51.00% (43.85, 58.12)
Test: z-test
Effect size for freq_c:group is -10.
Based on 200 simulations, (0 errors, 3 warnings, 0 messages)
Time elapsed: 0 h 0 m 9 s
51% power for 30 participants and 40 words. The z-test is fast, which
suits exploring designs, but it is too liberal with few participants.
For the final calculation use "sa" (Satterthwaite) or
"kr" (Kenward–Roger), and 1,000 simulations or more.
m_part <- extend(m_pilot, along = "participant", n = 80)
pc_part <- powerCurve(m_part, test = fixed("freq_c:group", "z"), along = "participant",
breaks = c(10, 20, 30, 40, 60, 80), nsim = 100, seed = 1)
m_word <- extend(m_pilot, along = "word", n = 120)
pc_word <- powerCurve(m_word, test = fixed("freq_c:group", "z"), along = "word",
breaks = c(20, 40, 60, 80, 120), nsim = 100, seed = 1)extend() adds new participants (or words) by copying the
design of existing ones, and powerCurve() fits the model to
the first 10, 20, … of them.
The interaction compares groups of participants, and participants differ in their frequency slopes. Extra participants raise power much faster than extra words, which only make each participant’s slope a little more precise.
Without a pilot study, makeLmer() builds the model from
values we choose, for example from earlier studies:
design <- select(pilot, participant, group, word, freq_c)
m_scratch <- makeLmer(rt ~ freq_c * group + (1 + freq_c | participant) + (1 | word),
fixef = c(750, -30, 120, -10),
VarCorr = list(participant = matrix(c(60^2, 0, 0, 12^2), 2), word = 30^2),
sigma = 70, data = design)The random-effect variances matter as much as the fixed effect. Because they are estimates too, try a plausible range and see how much the power changes.
Did you know: mantis shrimp were the first animals shown
to see circularly polarised light. Some species
also reflect it from body parts they display in courtship.
Source: Chiou et al. (2008), Current Biology
Post hoc power, also called observed or retrospective power, is computed after a study, with the effect size estimated from its own data. Reviewers often ask for it (Heinsberg & Weeks, 2022).
The calculation is the same as in a power analysis. The next slides show why the result is still uninformative.
Heinsberg and Weeks (2022) simulated the same mouse experiment, run in parallel at two universities (n = 100 each), with different true effects.
| Estimate (95% CI) | p | Post hoc power | True effect | True power | |
|---|---|---|---|---|---|
| A | 0.290 (−0.002, 0.582) | .052 | 0.584 | 0.402 | 0.841 |
| B | 0.275 (−0.002, 0.553) | .052 | 0.537 | 0.201 | 0.322 |
The two studies look almost identical, and so does their post hoc power. Their true power is very different, and nothing in the data reveals it.
1,000 studies of the same design, all with 28% true power. Post hoc power falls on one curve of the p-value: about 50% at p = .05, and below 50% whenever p > .05 (Hoenig & Heisey, 2001).
powerSim() on your final model
without changing the effect size computes the same thingYou report a non-significant interaction. A reviewer asks for a post hoc power analysis “to show whether the study was underpowered”.
How would you answer? What could you report instead that would help the reader judge the null result?
We determined the sample size by simulation with
{simr}(Green & MacLeod, 2016), using a linear mixed model with the structure of the planned analysis. The smallest interaction of interest was a difference of 10 ms per log unit between the frequency slopes of the two groups; the random-effect variances came from a pilot study. With 40 words, 60 participants gave an estimated power of 79%.
Also report the test, the number of simulations (1,000 or more in a real study) and how you chose every value.
{simr}, set the smallest effect
of interest with fixef<-, then vary participants and
items with extend() and powerCurve()These slides
mcanzi.de/ss27_advanced_statistics/
Code and all lectures
github.com/mcanzi/ss27_advanced_statistics