To run a repeated measures ANOVA in R, the cleanest route is the afex package with aov_ez(), which handles the within-subjects error term, applies the sphericity correction, and returns an effect size in one call. The analysis that holds up depends on supplying data in long format, checking Mauchly's test of sphericity, and applying the Greenhouse-Geisser correction when it fails. This guide covers the full procedure and why the base aov() approach trips people up.
When you need a repeated measures ANOVA
A repeated measures ANOVA is for designs where the same participants are measured under several conditions or at several time points, so the observations are not independent. Treating those measures as independent groups, as a one-way ANOVA in R would, ignores the within-person correlation and inflates the error term. The conceptual background, including when a mixed design is needed, is covered in our repeated measures ANOVA overview.
Why your data must be in long format
Most spreadsheets store repeated measures in wide format, one row per participant with a column per time point. R needs long format: one row per observation, with columns for the participant id, the within-subjects condition, and the outcome. Reshape it first:
library(tidyr)
long <- pivot_longer(
wide,
cols = c(time1, time2, time3),
names_to = "time",
values_to = "score"
)
long$id <- factor(long$id)
long$time <- factor(long$time)The id column is what tells the model which rows belong to the same person. Omitting it is the most common reason a repeated measures model silently collapses into an ordinary ANOVA.
Fitting the model with afex
The afex package wraps the awkward error-term syntax and does the sphericity correction for you:
library(afex)
model <- aov_ez(
id = "id",
dv = "score",
data = long,
within = "time"
)
model # prints F, df, p, and generalized eta squared
summary(model) # adds Mauchly's test and the correctionsThe printed table already includes a generalized eta squared effect size, which is the recommended one for repeated measures designs and saves the hand calculation an ordinary aov() model would need.
Checking sphericity and correcting for it
Repeated measures ANOVA assumes sphericity, that the variances of the differences between every pair of conditions are equal. summary(model) reports Mauchly's test: a significant result means sphericity is violated and the uncorrected F is too liberal. Do not abandon the analysis; apply a correction:
# afex applies Greenhouse-Geisser by default; see both corrections:
summary(model)$pval.adjustmentsUse the Greenhouse-Geisser correction when the estimate is below about .75 and the Huynh-Feldt correction when it is higher. Report which one you used and the corrected degrees of freedom.
Following up with pairwise comparisons
A significant within-subjects effect tells you the conditions differ somewhere. Locate the differences with the emmeans package, which respects the repeated measures structure and adjusts for multiple comparisons:
library(emmeans)
emm <- emmeans(model, ~ time)
pairs(emm, adjust = "holm")The Holm adjustment is a sound default; Bonferroni is acceptable but more conservative. The reasoning behind controlling error across many comparisons is the same one explained in understanding p-values.
The mixed design with a between-subjects factor
When you also have a between-subjects grouping, such as a treatment versus control group measured over time, add it to aov_ez() with the between argument:
model <- aov_ez(
id = "id", dv = "score", data = long,
within = "time", between = "group"
)The interaction between the within and between factors is usually the result of interest, read the same way as the interaction in a two-way ANOVA in R. For complex designs with missing time points, a mixed effects model in R is often the better tool because it tolerates unbalanced data.
Reporting a repeated measures ANOVA
Report the within-subjects effect as F(corrected df1, corrected df2) = value, the exact p, and the generalized eta squared, naming the sphericity correction you applied. State the pairwise findings with their adjusted p-values. The full formatting rules sit in reporting results in APA format, and the narrative goes in your results section.