MANOVA and MANCOVA - Practical

Dataset

Begin by downloading the dataset here:

https://www.dropbox.com/scl/fi/4navyr4aqekgirjbkml8t/warmup_data.csv?rlkey=xbr543igt8qsohnuiiear9jph&dl=1

Overview

You have data from an experimental study investigating the effect of warm-up protocols on two sports performance outcomes, Speed and Accuracy, in athletes.

Additionally, you suspect that years of experience (a continuous variable) might affect performance, so you want to account for it when doing MANCOVA.

There are three groups (levels of WarmupProtocol):

  • None: No warm-up.
  • Short: A short 5-minute warm-up.
  • Long: A longer 15-minute warm-up.

The dataset has:

  • 45 participants (15 in each group).
  • Two performance measures (PerformanceSpeed and PerformanceAccuracy).
  • A continuous covariate (ExperienceYears).

Load the Dataset

Begin by downloading the dataset here:

Show solution
warmup_data <- read.csv("https://www.dropbox.com/scl/fi/4navyr4aqekgirjbkml8t/warmup_data.csv?rlkey=xbr543igt8qsohnuiiear9jph&dl=1")

Data Exploration

  • Inspect the dataset structure: use functions like head(), str(), and summary().
  • Visualise the distribution of the two performance outcomes (PerformanceSpeed, PerformanceAccuracy) across the three warm-up protocols (e.g., boxplots).
  • Plot the relationship between experience and each performance measure.
Show solution
# Inspect structure
head(warmup_data)
str(warmup_data)
summary(warmup_data)

# Visualie distribs
par(mfrow = c(1, 2))
boxplot(PerformanceSpeed ~ WarmupProtocol, data = warmup_data,
        main = "Speed by Warm-up Protocol",
        xlab = "Warm-up Protocol",
        ylab = "Performance Speed")
boxplot(PerformanceAccuracy ~ WarmupProtocol, data = warmup_data,
        main = "Accuracy by Warm-up Protocol",
        xlab = "Warm-up Protocol",
        ylab = "Performance Accuracy")
Show solution
# Relationship between experience and speed
# (NO colour-coding! just use a single color/point type)
par(mfrow = c(1, 2))  # two side-by-side scatter plots
plot(warmup_data$ExperienceYears, warmup_data$PerformanceSpeed,
     pch = 19,
     xlab = "Experience (Years)",
     ylab = "Performance Speed",
     main = "Experience vs. Speed")

# Relationship between experience and accuracy
plot(warmup_data$ExperienceYears, warmup_data$PerformanceAccuracy,
     pch = 19,
     xlab = "Experience (Years)",
     ylab = "Performance Accuracy",
     main = "Experience vs. Accuracy")

MANOVA

  • Perform a MANOVA to see if WarmupProtocol has a multivariate effect on PerformanceSpeed and/or PerformanceAccuracy.

  • Interpret the result: Is there a significant overall difference between the three protocols, considering both Speed and Accuracy together?

Show solution
# Fit MANOVA model
manova_model <- manova(cbind(PerformanceSpeed, PerformanceAccuracy) ~ WarmupProtocol, 
                       data = warmup_data)

# Wilks' Lambda (or Pillai's trace)
summary(manova_model, test = "Wilks")
summary(manova_model, test = "Pillai")

# Interpretation:
# - Check p-value for WarmupProtocol.
# - If p < 0.05, we can conclude there's a significant multivariate effect
#   of WarmupProtocol on Speed & Accuracy combined.

Post-hoc Univariate ANOVAs and TukeyHSD

  • Check the univariate ANOVAs for each performance measure separately (Speed, Accuracy).
  • Use TukeyHSD (or another post-hoc test) to see which protocols differ significantly for each measure.
Show solution
# Univariate ANOVAs from MANOVA model
summary.aov(manova_model)

# Alternatively, fit each ANOVA separately:
aov_speed <- aov(PerformanceSpeed ~ WarmupProtocol, data = warmup_data)
aov_accuracy <- aov(PerformanceAccuracy ~ WarmupProtocol, data = warmup_data)

# TukeyHSD
tukey_speed <- TukeyHSD(aov_speed, "WarmupProtocol")
tukey_accuracy <- TukeyHSD(aov_accuracy, "WarmupProtocol")

# Inspect results
tukey_speed
tukey_accuracy

# Interpretation
# - Check which pairs (None vs Short, None vs Long, Short vs Long) 
#   have p < 0.05 for Speed or Accuracy.

MANCOVA (Including Covariate)

  • Perform a MANCOVA, adding ExperienceYears as a covariate.
  • Check if WarmupProtocol remains significant after controlling for ExperienceYears.
  • Also see if ExperienceYears has a significant effect on (PerformanceSpeed, PerformanceAccuracy).
Show solution
# Fit MANCOVA inc ExperienceYears
mancova_model <- manova(cbind(PerformanceSpeed, PerformanceAccuracy) ~ 
                          WarmupProtocol + ExperienceYears, 
                        data = warmup_data)

summary(mancova_model, test = "Wilks")
summary(mancova_model, test = "Pillai")

# Interpretation:
# - If WarmupProtocol is still significant, the effect is robust 
#   even after controlling for experience.
# - If ExperienceYears is significant, we see that years of experience 
#   plays a role in overall performance.

Visualising Adjusted Means (Optional)

  • Choose one of the outcome variables (e.g., PerformanceSpeed), fit an ANCOVA model in lm() or aov() style (i.e., PerformanceSpeed ~ WarmupProtocol + ExperienceYears), and use emmeans to generate adjusted means and a plot.
Show solution
library(emmeans)

# Fit univariate ANCOVA for PerformanceSpeed
mod_speed <- lm(PerformanceSpeed ~ WarmupProtocol + ExperienceYears, data = warmup_data)

# Obtain estimated marginal means for WarmupProtocol
emm_speed <- emmeans(mod_speed, ~ WarmupProtocol)

# View the table of adjusted means
emm_speed

# Plot the adjusted means with 95% confidence intervals
plot(emm_speed, comparison = TRUE)

Interpretation:

This shows the group means for each protocol adjusted for the average value of ExperienceYears (or for the distribution of ExperienceYears, depending on the model).

If the confidence intervals do not overlap between groups, that suggests significant differences in adjusted means.