Within-Within Subjects ANOVA
Two or more within-subjects (repeated) factors analyzed simultaneously (e.g., Time × Condition)..
What is it?
Two-Way Repeated Measures ANOVA assesses the impact of two independent factors on a continuous outcome, where all combinations of factors are measured on the same subjects.
When to use it
- 2 Within Factors: (e.g., Time [Pre/Post] and Drug [A/B]).
- Outcome: Continuous scale variable.
- Single Group: Every subject goes through all 4 test cells.
Core Idea
We map how subjects react to both factors simultaneously. For example, does active drug reduce scores over time, while placebo does not?
This design has extreme statistical power because it controls for both participant baseline and general temporal trends.
Hypotheses
How it works
Calculates distinct error terms for each test:
- Time tested against $Time \times Subjects$
- Drug tested against $Drug \times Subjects$
- Interaction tested against $Time \times Drug \times Subjects$
Assumptions
Important Note
Carryover effects (fatigue, learning) are the biggest threat. They must be controlled by counterbalancing or randomized scheduling of conditions.
Quick Example
| Subj / time | Active Pre | Active Post | Placebo Pre |
|---|---|---|---|
| Subj 1 | 52.3 | 81.0 | 50.1 |
| Subj 2 | 41.4 | 58.2 | 42.8 |
Two-Way RM ANOVA Live Laboratory
Adjust Time, Treatment, and Interaction values to observe how repeated measures handle multi-factor data.
| Source | SS | df | F | p-value |
|---|---|---|---|---|
| Factor A (Time) | 0.0 | 1 | 0.00 | 1.0000 |
| Factor B (Drug) | 0.0 | 1 | 0.00 | 1.0000 |
| Interaction (AB) | 0.0 | 1 | 0.00 | 1.0000 |
| Error (Residual) | 525.0 | 21 | - | - |
Hypotheses
Pragmatic null and alternative hypotheses defined in mathematical notation.
H₀: No main effects or interaction exist for the two within-subjects factors (all condition means are equal after controlling for individual differences)
Hₐ: At least one main effect or interaction exists between the two within-subjects factors
Tests 3 effects: Main effect A, Main effect B, and A×B interaction. All effects are within-subjects, requiring sphericity assumption. Repeated measures on same participants increases power by removing between-subjects variance.
Assumptions
The core mathematical criteria needed to ensure that statistical testing remains unbiased and valid.
Diagnostics
Checking residual plots and indices to examine model deviations and ensure standard error integrity.
- Mauchly's test of sphericity for both main effects and interaction
- Greenhouse-Geisser or Huynh-Feldt epsilon (ε) if sphericity violated
- Descriptive statistics (M, SD) for all conditions
- Interaction plot (profile plot) to visualize Factor A × Factor B
- Q-Q plots of residuals or key difference scores
- Shapiro-Wilk test on difference scores for main contrasts
- Check for missing data patterns (% missing per condition)
- Residual plots to detect outliers
- Counterbalancing check (order × condition interaction)
- Simple effects analysis for significant interaction
- Effect sizes (partial η² or generalized η²) for all effects
Applied Minds
Review concrete study examples, data layout guidelines, and copy executable syntax scripts.
Caffeine Effects on Cognitive Performance Across Time and Task Type
Research question: Does caffeine improve cognitive performance differently across task types and time since ingestion? Design: 30 participants complete 2 tasks (Memory, Attention) at 3 time points (30min, 60min, 90min post-caffeine) in fully within-subjects 2×3 design. Each participant completes all 6 conditions in counterbalanced order. Outcome: Performance accuracy (% correct, 0-100).
# Two-way RM-ANOVA: Task × Time on Cognitive Performance
# Fully within-subjects design (2×3 = 6 conditions per participant)
# Load packages
library(tidyverse) # Data manipulation and ggplot2
library(ez) # For ezANOVA
library(rstatix) # For anova_test
library(emmeans) # For post-hoc contrasts
# Set seed
set.seed(2025)
# Simulate realistic data
n_subjects <- 30
data <- expand.grid(
subject = factor(1:n_subjects),
task = factor(c("Memory", "Attention")),
time = factor(c("30min", "60min", "90min"), levels = c("30min", "60min", "90min"))
)
# Generate accuracy with realistic effects
data <- data %>%
mutate(
# Base accuracy by task
base_acc = ifelse(task == "Memory", 72, 75),
# Time effect (caffeine peaks at 60min)
time_effect = case_when(
time == "30min" ~ 0,
time == "60min" ~ 5,
time == "90min" ~ 3
),
# Task × Time interaction (caffeine more beneficial for Attention)
interaction_effect = case_when(
task == "Attention" & time == "60min" ~ 4,
task == "Attention" & time == "90min" ~ 2,
TRUE ~ 0
),
# Subject random effect
subject_effect = as.numeric(subject) * 0.4 - 6,
# Generate accuracy
accuracy = base_acc + time_effect + interaction_effect + subject_effect + rnorm(n(), 0, 3.5)
) %>%
mutate(accuracy = pmin(pmax(accuracy, 0), 100)) %>%
select(subject, task, time, accuracy)
cat("=== Data Structure ===", "\n")
cat("Total observations:", nrow(data), "\n")
cat("Observations per subject:", nrow(data) / n_subjects, "\n")
cat("Design: 2 tasks × 3 time points = 6 conditions per participant\n\n")
# === STEP 1: Check Assumptions ===
# 1. Missing data
cat("Missing observations:", sum(is.na(data$accuracy)), "\n\n")
# 2. Descriptive statistics
cat("=== Descriptive Statistics ===", "\n")
desc_stats <- data %>%
group_by(task, time) %>%
summarise(n = n(), M = mean(accuracy), SD = sd(accuracy), .groups = "drop")
print(desc_stats)
# === STEP 2: Run Two-way RM-ANOVA ===
cat("\n=== Two-way RM-ANOVA(ezANOVA) ===", "\n")
anova_result <- ezANOVA(
data = data,
dv = accuracy,
wid = subject,
within = .(task, time),
detailed = TRUE,
type = 3
)
print(anova_result)
# Check sphericity
if(!is.null(anova_result$`Mauchly's Test for Sphericity`)) {
cat("\n=== Mauchly's Test for Sphericity ===", "\n")
print(anova_result$`Mauchly's Test for Sphericity`)
cat("\nInterpretation: p < .05 indicates sphericity violated\n")
}
# Sphericity corrections
if(!is.null(anova_result$`Sphericity Corrections`)) {
cat("\n=== Sphericity Corrections ===", "\n")
print(anova_result$`Sphericity Corrections`)
cat("\nGG = Greenhouse-Geisser, HF = Huynh-Feldt\n")
cat("Use GG if epsilon < .75, HF if epsilon > .75\n\n")
}
# === STEP 3: Check Normality ===
cat("=== Normality Check ===", "\n")
# Compute within-subject residuals
data <- data %>%
group_by(subject) %>%
mutate(residual = accuracy - mean(accuracy)) %>%
ungroup()
# Q-Q plot and histogram
par(mfrow=c(1,2))
qqnorm(data$residual, main="Q-Q Plot of Residuals")
qqline(data$residual, col="red")
hist(data$residual, breaks=25, main="Histogram of Residuals", xlab="Residual")
# Shapiro-Wilk test
shapiro_test <- shapiro.test(data$residual)
cat("\nShapiro-Wilk test: W =", round(shapiro_test$statistic, 3),
", p =", round(shapiro_test$p.value, 4), "\n")
cat(ifelse(shapiro_test$p.value > .05, "✓ Normality OK", "⚠ Normality violated"), "\n\n")
# === STEP 4: Visualize Interaction ===
cat("=== Interaction Plot ===", "\n")
task_time_means <- data %>%
group_by(task, time) %>%
summarise(M = mean(accuracy), SE = sd(accuracy)/sqrt(n()), .groups="drop")
p1 <- ggplot(task_time_means, aes(x=time, y=M, color=task, group=task)) +
geom_line(linewidth=1.2) +
geom_point(size=3) +
geom_errorbar(aes(ymin=M-SE, ymax=M+SE), width=0.1) +
labs(title="Task × Time Interaction: Caffeine Effects on Performance",
subtitle="Caffeine more beneficial for Attention at peak(60min)",
x="Time Since Caffeine Ingestion",
y="Accuracy(% correct) ± SE",
color="Task Type") +
theme_classic() +
theme(legend.position="right")
print(p1)
# === STEP 5: Simple Effects Analysis (if interaction significant) ===
if(anova_result$ANOVA$`Pr(>F)`[3] < .05) { # If interaction p < .05
cat("\n=== Simple Effects: Effect of Time for each Task ===", "\n")
# Memory task
cat("\n--- Memory Task ---\n")
memory_data <- data %>% filter(task == "Memory")
memory_anova <- anova_test(data = memory_data, dv = accuracy, wid = subject, within = time)
print(get_anova_table(memory_anova))
# Attention task
cat("\n--- Attention Task ---\n")
attention_data <- data %>% filter(task == "Attention")
attention_anova <- anova_test(data = attention_data, dv = accuracy, wid = subject, within = time)
print(get_anova_table(attention_anova))
}
# === STEP 6: Post-hoc Pairwise Comparisons ===
cat("\n=== Pairwise Comparisons: Time(Main Effect) ===", "\n")
pairwise_time <- data %>%
pairwise_t_test(accuracy ~ time, paired = TRUE, p.adjust.method = "bonferroni")
print(pairwise_time)
# === STEP 7: Effect Sizes ===
cat("\n=== Effect Sizes ===", "\n")
cat("From ANOVA table(ges = generalized eta squared):\n")
cat("Interpretation: .01 = small, .06 = medium, .14 = large(Cohen, 1988)\n\n")
# === APA-Style Reporting ===
cat("=== APA-Style Report ===", "\n")
cat("
A two-way repeated measures ANOVA was conducted to examine the effects of
caffeine on cognitive performance across task type(Memory, Attention) and
time since ingestion(30min, 60min, 90min). Mauchly's test indicated sphericity
was violated for the Time main effect(p = .032, ε = .85), so Huynh-Feldt
corrected values are reported.
Results revealed a significant main effect of Time, F(1.70, 49.30) = 42.15,
p < .001, η²_G = .28 (large effect), with peak performance at 60 minutes
post-ingestion. The Task main effect was also significant, F(1, 29) = 8.34,
p = .007, η²_G = .05 (small effect), with Attention tasks(M = 77.8%, SD = 3.8)
outperforming Memory tasks(M = 74.2%, SD = 4.1).
Crucially, a significant Task × Time interaction emerged, F(2, 58) = 6.78,
p = .002, η²_G = .04 (small-to-medium effect). Simple effects analysis revealed
that caffeine improved Attention performance significantly at 60min (M = 84.2%)
compared to baseline 30min (M = 75.3%), Δ = 8.9%, p < .001, but the effect was
smaller for Memory tasks(60min: M = 77.5% vs 30min: M = 72.1%, Δ = 5.4%, p = .003).
By 90 minutes, Attention performance remained elevated(M = 81.4%) while Memory
returned near baseline.
These findings support caffeine's time-dependent and task-specific cognitive
enhancement, with maximal benefits for attention tasks occurring 60 minutes
post-ingestion, consistent with pharmacokinetic profiles(McLellan et al., 2016).
")
cat("\n=== Key Statistics to Report ===", "\n")
cat("• Main effect Task: F(df1, df2) = X.XX, p = .XXX, η²_G = .XX\n")
cat("• Main effect Time: F(df1, df2) = X.XX, p < .001, η²_G = .XX(report corrected df if violated)\n")
cat("• Interaction Task × Time: F(df1, df2) = X.XX, p = .XXX, η²_G = .XX\n")
cat("• Sphericity tests and corrections(report ε and which correction used)\n")
cat("• Descriptive statistics(M, SD) for all conditions\n")
cat("• Simple effects analysis for significant interaction\n")
cat("• Post-hoc pairwise comparisons with Bonferroni correction\n")Significant Task × Time interaction (F[2,58] = 6.78, p = .002, η²_p = .19): Caffeine improved Attention performance more than Memory, with peak benefits at 60 minutes post-ingestion. Attention accuracy increased 8.9% from baseline (30min) to peak (60min), compared to only 5.4% for Memory. By 90 minutes, Attention remained elevated (+6.1% from baseline) while Memory declined. Main effects: Time (F[2,58] = 42.15, p < .001, η²_p = .59), Task (F[1,29] = 8.34, p = .007, η²_p = .22). Findings align with pharmacokinetics (peak plasma caffeine ~60min) and support task-specific cognitive enhancement.
Alternatives
Structured fallback pathways for choosing alternative tests when normality or slopes requirements fail.
- Greenhouse-Geisser Correction — The mandatory shield for within-subject variance heterogeneity.
- MANOVA Path — bypass sphericity by treating the crossover cells as a multivariate profile.
- Linear Mixed Models — Use if participants are further clustered within clinical sites or periods.
Post-hoc
Group mean comparisons and correction controls (e.g. Tukey HSD, Bonferroni) to protect against Family-Wise Error Rates.
Post-hoc pairwise tests defined for this model.
No specific guidelines provided.
Effect Size
Understanding effect sizes (e.g., Cohen's d, Partial Eta-Squared) and clinical impact benchmarks.
Proportion of variance explained after removing other effects. Small: .01, Medium: .06, Large: .14 (Cohen, 1988). Most commonly reported for RM-ANOVA
More appropriate for designs with both between- and within-subjects factors. Same thresholds as partial η²
Less biased estimate of population effect size. Preferred for within-subjects designs when available
0.2
0.5
0.8
Sample Size
Guidelines for minimum sample requirements and power analysis parameters.
At least 15-20 subjects for adequate power, depends on effect size and correlation among repeated measures
| Effect Size | Parameters | Required n |
|---|---|---|
| Small Effect | α=.05, power=.80 | n ≈ 54 subjects |
| Medium Effect | α=.05, power=.80 | n ≈ 12 subjects |
| Large Effect | α=.05, power=.80 | n ≈ 6 subjects |
Reporting
How to compile statistical results into publication prose matching APA and journal style guides.
A two-way repeated measures ANOVA was conducted to examine the effects of Factor A and Factor B on DV. Mauchly's test of sphericity was assessed for both main effects and the interaction; state if violated and which correction used: Greenhouse-Geisser (ε = .XX) or Huynh-Feldt (ε = .XX) for specific effects. Results revealed describe main effects with F(df1, df2) = X.XX, p = .XXX, η²_p = .XX. If interaction significant: A significant Factor A × Factor B interaction emerged, F(df1, df2) = X.XX, p = .XXX, η²_p = .XX. Simple effects analysis revealed describe pattern with means and p-values. Post-hoc pairwise comparisons using correction method indicated specific differences.
- F-statistic for both main effects and interaction
- degrees of freedom (corrected if sphericity violated)
- p-values
- effect sizes (partial η² or generalized η²)
- sphericity test results and corrections applied
- descriptive statistics (M, SD) for all conditions
- simple effects analysis for significant interaction
- post-hoc pairwise comparisons with corrections
Manuscript Lab
Copy standard summary tables and forensic reporting grids to outline analysis details.
| Source | df | MS | F | p | ηp² |
|---|---|---|---|---|---|
| Time (Within) | 2 | 85.4 | 12.5 | < .001 | .27 |
| Condition (Within) | 1 | 42.1 | 6.2 | .018 | .15 |
| Time × Condition | 2 | 18.5 | 3.1 | .055 | .08 |
| Error (T×C) | 68 | 6.0 | — | — | — |
Indicates that every subject experienced every combination of Time and Condition.
The 'crossover' effect. Did the pattern over time differ depending on the condition?
Interaction Error. The specific variance associated with the subject-by-time-by-condition interaction.
Command Center
Syntax libraries and function parameters for executing calculations in stats packages.
# 1. Execute Doubly Repeated ANOVA
model <- aov_ez(id = 'subject', dv = 'score', data = df,
within = c('time', 'condition'))
# 2. Plot the Within-Subject factorial
afx_plot(model, x = 'time', trace = 'condition', error = 'within')In doubly repeated designs, missing data is fatal (casewise deletion). Audit for completeness first.
# Missing Data Audit
naniar::vis_miss(df)
# Sphericity Check for both Main Effects and Interaction
performance::check_sphericity(model)Common Mistakes
Analytical caveats and corrections to maintain modeling integrity.
References
Scholarly lineage and citation keys grounding the statistical framework.