Repeated Measures in R

Info sheet · Statistics for Psychology & Neuroscience

Author

Andrew Bell

Published

August 13, 2026

Info sheet 0.2 (draft) · Prerequisites: repeated-measures ANOVA (the idea) · Give feedback ↗

Working notes for the author — not shown to students once collapsed; remove before publishing.

  • [ ]

What you’ll get from this sheet

Last sheet we built the logic of repeated-measures ANOVA. Now we actually run one — and meet a subtlety that trips people up. By the end you should be able to:

  1. Say why aov() isn’t the right tool for repeated measures.
  2. Describe, broadly, the four types of sums of squares.
  3. Run a repeated-measures ANOVA in R with three different functions.
  4. Know which sums-of-squares type is the safe default (spoiler: Type III).

aov() defaults to Type I sums of squares, where each factor is credited only for the variance left after the previous factors — so the answer depends on the order you list your factors. For repeated-measures and factorial designs, use Type III, where order doesn’t matter.

Why not just use aov()?

Until now aov() has served us well — it’s built into base R and works nicely for independent designs. The catch: aov() defaults to Type I (sequential) sums of squares. Each factor is entered in the order you specify, and its SS is computed without fully accounting for the factors listed after it. So order of entry matters — two people running the same factorial ANOVA with the IVs in a different order can get different answers. Type I is fine when your design is balanced and your factors are independent, but for repeated-measures or mixed designs it isn’t appropriate — which is why we can’t just keep reaching for aov().

Why order matters: shared variance

When two factors are correlated, they overlap — some variance in the outcome could be credited to either. Type I hands that shared slice entirely to whichever factor you entered first. Type III refuses to give it to either, crediting each factor only with the variance it uniquely explains. Change the overlap and the entry rule below, and watch each factor’s sum of squares:

Flip between “A first” and “B first” under Type I and Factor A’s sum of squares jumps — same data, different answer, purely because of the order you typed the factors. Switch to Type III and both factors report only their unique variance no matter what; the overlap is credited to neither. That order-independence is exactly why Type III is the safe choice once your factors are correlated — which, in a repeated-measures design, they usually are.

The four types of sums of squares

You don’t need the algebra, just the broad differences:

  • Type I (sequential). Factors entered in order; order matters. The base-R aov() default. Only safe for balanced, independent designs.
  • Type II. Each factor tested after the others, but ignoring interactions. Order-independent; fine if you only care about main effects.
  • Type III. Each factor tested after all others and their interactions. Order-independent. Best for repeated-measures and mixed ANOVAs, and the default in SPSS.
  • Type IV. Like II/III but built to handle missing data. Rarely used, but worth knowing it exists.

For our purposes: stick with Type III. It’s the most widely accepted, especially when replicating psychology or biomedical analyses.

Three ways to run it

Many R functions handle repeated measures; here are three practical options (plus the Python equivalent).

library(rstatix)
res <- anova_test(
  data   = oreo_ratings,
  dv     = rating,
  wid    = subject_id,
  within = cookie_type
)                       # defaults to Type III
get_anova_table(res)    # tidy table with F, p, and effect sizes (ges)
library(afex)
aov_ez(
  id     = "subject_id",
  dv     = "rating",
  data   = oreo_ratings,
  within = "cookie_type"
)                       # Type III by default; also try ezANOVA() from the ez package

The aov() and Python tabs run live; rstatix/afex/ez are the tools you’d reach for in a real analysis.

A colleague runs a two-factor ANOVA, then reruns it with the two factors swapped, and gets different F-values. What happened — and how do you fix it?

They’re using Type I sums of squares (the aov() default), which credits each factor only with the variance left after the earlier ones — so entry order changes the result whenever the factors are correlated. Switch to Type III (via afex::aov_ez, rstatix::anova_test, or car::Anova(..., type = 3)), where each factor is tested against all the others and order no longer matters.

Don’t reach for car::Anova(type = 3) on a model fitted with R’s default treatment contrasts — Type III SS are only correct with orthogonal contrasts (e.g. contr.sum). The afex and rstatix wrappers set this up for you, which is another good reason to use them rather than rolling your own.

Where this shows up next

See Chapter (Repeated Measures) for the worked Oreo analysis and the full sums-of-squares discussion.