# A tibble: 1 × 9
.y. group1 group2 n1 n2 p p.signif p.adj p.adj.signif
* <chr> <chr> <chr> <int> <int> <dbl> <chr> <dbl> <chr>
1 weight F M 81 81 9.34e-24 **** 9.34e-24 ****
Interpretation Summary
RM1 > RM4 > RM21
Significant main effect of RM type
Interaction between RM type and gender significant
Males lift significantly more than females across all RM types
Sphericity Explained
Assumption: Variance of the differences between RM levels are equal
Test: Mauchly’s Test
If violated:
Use Greenhouse-Geisser correction (default conservative choice)
anova_res$`Mauchly's Test for Sphericity`
Effect W p p<.05
1 RM_type 0.914 0.095
Conclusion
Repeated measures ANOVA is powerful when assumptions are met or adjusted
Mixed ANOVA enables testing interactions with between-subject factors
Use corrected tests (e.g., GG) when sphericity is violated
✅ Step-by-step Procedure using lme4
We will assume the data is in long format (as simulated previously), with variables: - subject: participant ID - gender: between-subjects factor (optional) - RM_type: within-subject factor (e.g., RM1, RM4, RM21) - weight: outcome variable
1. Load required packages
library(lme4)library(lmerTest) # for p-values and ANOVA
2. Fit the linear mixed model
# Main repeated measures model (random intercept for subject)model <-lmer(weight ~ gender + RM_type + (1| subject), data = sim_data_long)summary(model)
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: weight ~ gender + RM_type + (1 | subject)
Data: sim_data_long
REML criterion at convergence: 1491.4
Scaled residuals:
Min 1Q Median 3Q Max
-2.80588 -0.74290 -0.01438 0.67387 2.64020
Random effects:
Groups Name Variance Std.Dev.
subject (Intercept) 0.0 0.00
Residual 666.5 25.82
Number of obs: 162, groups: subject, 54
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 277.716 4.057 158.000 68.461 < 2e-16 ***
genderM 120.757 4.057 158.000 29.768 < 2e-16 ***
RM_typeRM4 -27.861 4.968 158.000 -5.608 8.94e-08 ***
RM_typeRM21 -136.686 4.968 158.000 -27.512 < 2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Correlation of Fixed Effects:
(Intr) gendrM RM_RM4
genderM -0.500
RM_typeRM4 -0.612 0.000
RM_typeRM21 -0.612 0.000 0.500
optimizer (nloptwrap) convergence code: 0 (OK)
boundary (singular) fit: see help('isSingular')
RM_type: fixed effect (within-subject factor)
(1 | subject): random intercept for subjects to account for repeated measures
3. Obtain the ANOVA table with Type III SS
anova_results <-anova(model, type =3)print(anova_results)
Type III Analysis of Variance Table with Satterthwaite's method
Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
gender 590578 590578 1 158 886.15 < 2.2e-16 ***
RM_type 563438 281719 2 158 422.71 < 2.2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
This will provide: - Sum of Squares for the within-subject effect (RM_type) - Mean Squares, F-statistics, and p-values
4. Estimate between-subject variability (subject-level random effect)
The between-subjects SS is not shown directly in the ANOVA table but can be extracted from the model’s random effects:
# Extract random effects variance (between-subjects variability)VarCorr(model)
Groups Name Std.Dev.
subject (Intercept) 0.000
Residual 25.816
You will see something like:
Groups Name Variance Std.Dev.
subject (Intercept) XXX YYY
Residual ZZZ ...
subject (Intercept) reflects the between-subject variability
Residual is the within-subject (error) variance
To calculate the sum of squares for these components, you can multiply the variances by their degrees of freedom (or number of units):