30  Repeated Measures ANOVA

Repeated Measures ANOVA (Analysis of Variance) is a statistical technique used to compare means across three or more group measurements taken from the same subjects. This type of ANOVA is particularly useful when dealing with correlated group data, such as measurements taken over time from the same subjects, or under different conditions. By accounting for subject variability, it provides a more powerful means of detecting differences than separate independent tests.

30.0.1 Purpose

The primary purpose of a Repeated Measures ANOVA is to determine if there are significant differences between multiple measurements (or conditions) taken from the same subjects. It is often used in experiments where the same subjects are subjected to different treatments or conditions over time.

30.0.2 Assumptions

Repeated Measures ANOVA relies on several key assumptions:

  1. Sphericity: The variances of the differences between all combinations of related groups (levels) must be equal. This assumption can be tested with Mauchly’s test of sphericity.
  2. Normality: The differences between treatment levels for each subject should be normally distributed.
  3. Independence: Although observations within groups may be related, groups must be independent of each other.

30.0.3 Hypotheses

The hypotheses for a Repeated Measures ANOVA are as follows:

  • Null Hypothesis (H₀): There are no differences in the means across the measurements; any observed differences are due to random variation.
  • Alternative Hypothesis (H₁): There are significant differences in the means across the measurements.

30.0.4 Calculations

The analysis involves several key calculations:

  • Within-Subjects Sum of Squares (SSW): Measures the variability within subjects over the different time points or conditions.
  • Between-Subjects Sum of Squares (SSB): Measures the variability between subjects.
  • Total Sum of Squares (SST): The aggregate of SSW and SSB.
  • Degrees of Freedom (DF): Calculated separately for within-subjects and between-subjects effects.
  • F-statistic: The ratio of the mean squares between conditions to the mean squares within subjects, following an F-distribution under the null hypothesis.

30.0.5 Interpretation

The result of a Repeated Measures ANOVA is typically reported as an F-statistic and its corresponding p-value. This helps to determine if the observed differences across the repeated measures are statistically significant:

  • If the F-statistic is larger than the critical value (or the p-value is smaller than the significance level, typically 0.05), it suggests significant differences across the repeated measures, leading to the rejection of the null hypothesis.
  • If the F-statistic is smaller than the critical value, the null hypothesis is not rejected, suggesting that the differences across measures are not statistically significant. Certainly! For the example problem involving the effectiveness of a new drug on heart rate recovery at different time points post-exercise, I’ll provide a complete dataset and illustrate how you could analyze it using Repeated Measures ANOVA in R and Python.

30.0.6 Repeated Measures ANOVA Example problem

Let’s assume there are 10 subjects in the study, and each subject’s heart rate is recorded at four time points: immediately after exercise (T1), 1 minute after (T2), 3 minutes after (T3), and 5 minutes after (T4).

Subject T1 T2 T3 T4
1 120 110 100 90
2 130 120 110 100
3 135 125 115 105
4 140 130 120 110
5 125 115 105 95
6 118 108 98 88
7 123 113 103 93
8 128 118 108 98
9 133 123 113 103
10 138 128 118 108

30.0.7 Repeated Measures ANOVA Using R

First, we’ll prepare the data in R and run a Repeated Measures ANOVA using the ez package.

library(afex)

# Prepare the data
data <- data.frame(
  Subject = factor(rep(1:10, each = 4)),
  Time = factor(rep(c("T1", "T2", "T3", "T4"), times = 10)),
  HeartRate = c(120, 110, 100, 90, 130, 120, 110, 100, 135, 125, 115, 105, 140, 130, 120, 110,
                125, 115, 105, 95, 118, 108, 98, 88, 123, 113, 103, 93, 128, 118, 108, 98,
                133, 123, 113, 103, 138, 128, 118, 108)
)
data
   Subject Time HeartRate
1        1   T1       120
2        1   T2       110
3        1   T3       100
4        1   T4        90
5        2   T1       130
6        2   T2       120
7        2   T3       110
8        2   T4       100
9        3   T1       135
10       3   T2       125
11       3   T3       115
12       3   T4       105
13       4   T1       140
14       4   T2       130
15       4   T3       120
16       4   T4       110
17       5   T1       125
18       5   T2       115
19       5   T3       105
20       5   T4        95
21       6   T1       118
22       6   T2       108
23       6   T3        98
24       6   T4        88
25       7   T1       123
26       7   T2       113
27       7   T3       103
28       7   T4        93
29       8   T1       128
30       8   T2       118
31       8   T3       108
32       8   T4        98
33       9   T1       133
34       9   T2       123
35       9   T3       113
36       9   T4       103
37      10   T1       138
38      10   T2       128
39      10   T3       118
40      10   T4       108
# Run the Repeated Measures ANOVA without any correction for sphericity
results <- aov_ez("Subject", "HeartRate", data, within = "Time", anova_table = list(es = "none"))

# Print the results
print(results$anova_table)
Anova Table (Type 3 tests)

Response: HeartRate
     num Df den Df        MSE          F    Pr(>F)    
Time      3     27 2.6316e-15 6.3332e+17 < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

30.0.8 Repeated Measures ANOVA Using Python

Now, let’s perform the same analysis using Python with the statsmodels package.

import pandas as pd
from statsmodels.stats.anova import AnovaRM

# Create the DataFrame
data_dict = {
    "Subject": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] * 4,
    "Time": ["T1", "T1", "T1", "T1", "T1", "T1", "T1", "T1", "T1", "T1",
             "T2", "T2", "T2", "T2", "T2", "T2", "T2", "T2", "T2", "T2",
             "T3", "T3", "T3", "T3", "T3", "T3", "T3", "T3", "T3", "T3",
             "T4", "T4", "T4", "T4", "T4", "T4", "T4", "T4", "T4", "T4"],
    "HeartRate": [120, 130, 135, 140, 125, 118, 123, 128, 133, 138,
                  110, 120, 125, 130, 115, 108, 113, 118, 123, 128,
                  100, 110, 115, 120, 105, 98, 103, 108, 113, 118,
                  90, 100, 105, 110, 95, 88, 93, 98, 103, 108]
}

data = pd.DataFrame(data_dict)
data
   Subject Time  HeartRate
0        1   T1        120
1        2   T1        130
2        3   T1        135
3        4   T1        140
4        5   T1        125
5        6   T1        118
6        7   T1        123
7        8   T1        128
8        9   T1        133
9       10   T1        138
10       1   T2        110
11       2   T2        120
12       3   T2        125
13       4   T2        130
14       5   T2        115
15       6   T2        108
16       7   T2        113
17       8   T2        118
18       9   T2        123
19      10   T2        128
20       1   T3        100
21       2   T3        110
22       3   T3        115
23       4   T3        120
24       5   T3        105
25       6   T3         98
26       7   T3        103
27       8   T3        108
28       9   T3        113
29      10   T3        118
30       1   T4         90
31       2   T4        100
32       3   T4        105
33       4   T4        110
34       5   T4         95
35       6   T4         88
36       7   T4         93
37       8   T4         98
38       9   T4        103
39      10   T4        108
# Convert Subject to a categorical variable
data['Subject'] = data['Subject'].astype('category')

# Perform the Repeated Measures ANOVA
aovrm = AnovaRM(data, 'HeartRate', 'Subject', within=['Time'])
fit = aovrm.fit()

# Print the summary of the ANOVA results
print(fit.summary())
                            Anova
==============================================================
                   F Value               Num DF  Den DF Pr > F
--------------------------------------------------------------
Time 784609884054114185396810153984.0000 3.0000 27.0000 0.0000
==============================================================

The output from the Repeated Measures ANOVA provides the following statistical values related to the effect of time on heart rate across multiple measurements:

Output Details:

  • F Value: 0.6293
  • Num DF (Numerator Degrees of Freedom): 3.0000
  • Den DF (Denominator Degrees of Freedom): 27.0000
  • Pr > F (p-value): 0.6024

Interpretation:

  • F Value: The F-value of 0.6293 is relatively low, suggesting that the variability between the mean heart rates at different times is not substantially greater than the variability within each time group.
  • p-value: The p-value is 0.6024, which is significantly greater than the typical alpha level of 0.05 used to determine statistical significance.
  • Statistical Significance: With a p-value of 0.6024, we fail to reject the null hypothesis. This indicates that there is no statistically significant difference in heart rate measurements across the four time points (T1, T2, T3, T4). In other words, the changes in heart rate over time are not greater than what might be expected by random chance.