MANOVA mit R
Kommentiertes Codebeispiel

Arndt Regorz, Dipl. Kfm. & MSc. Psychologie, 03.12.2025

Einführung

Die MANOVA ist ein Verfahren für den Gruppenvergleich bei zwei oder mehr abhängigen Variablen.

Dieses Tutorial wird zunächst Datenaufbereitung und deskriptive Vorabauswertungen zeigen. Anschließend folgt die eigentliche MANOVA. Daran schließen sich mögliche Post-hoc-Tests an sowie Code zum Testen der Verfahrensvoraussetzungen. Das Tutorial endet mit einem kurzen Einblick in eine robuste Verfahrensalternative, die man bei verletzten Voraussetzungen einsetzen kann.

Vorbereitung der Daten

Dieses Tutorial nutzt als Beispieldatensatz mtcars, der mit der Basisversion von R ausgeliefert wird. Dabei werden zahlreiche Automobilmodelle hinsichtlich verschiedener Parameter miteinander verglichen.

head(mtcars)
nrow(mtcars)

Hier wollen wir prüfen, inwieweit sich die beiden abhängigen Variablen Verbrauch (mpg) und Beschleunigung (qsec) zwischen Autos mit drei, vier oder fünf Gängen unterscheiden. Dazu muss zuächst die Gruppenvariable (gear = Gänge) in einen Faktor transformiert werden.

# AVs:
# mpg (Miles/gallon) = Verbrauch
# qsec (1/4 mile time) = Beschleunigung
# Faktor: gear - Gänge (als Faktor) - 3, 4, 5

# Anzahl Gänge als Faktor
mtcars_t <- mtcars
mtcars_t$gear <- as.factor(mtcars_t$gear)

Deskriptive Auswertungen

Zunächst betrachten wir Mittelwerte und Standardabweichungen für beide abhängigen Variablen je Gruppe.

# Dekriptive Daten

library(psych)
describeBy(mpg + qsec ~ gear,
data = mtcars_t)

Anschließend visualisieren wir die Daten mit Boxplots, entweder getrennt je abhängige Variable oder in einem gemeinsamen Diagramm. In diesem Beispiel mit unterschiedlichen Metriken für Beschleunigung und Verbrauch würde ich eher zu zwei getrennten Diagrammen neigen. Wenn man jedoch die gleiche Metrik für alle AVs hat (z.B. Likert-Skalen mit gleicher Punktzahl), dann bevorzuge ich ein gemeinsames Diagram.

# Visualisierung

library(ggpubr)
ggboxplot(
mtcars_t, x = "gear", y = "mpg",
merge = TRUE)

ggboxplot(
mtcars_t, x = "gear", y = "qsec",
merge = TRUE)

ggboxplot(
mtcars_t, x = "gear", y = c("mpg", "qsec"),
merge = TRUE, palette = "jco")

Eigentliche MANOVA

Die eigentliche MANOVA ist der kürzeste Teil des Tutorials. Die MANOVA-Funktion ist Teil der Basisversion von R.

Die abhängigen Variablen werden dabei mit der cbind()-Funktion verbunden, dann folgt die Tilde und der Faktor (oder bei einer mehrfaktoriellen MANOVA die Faktoren, mit dem "*"-Zeichen verbunden). Außerdem wird noch der Dataframe angegeben.

erg_manova <- manova(cbind(mpg, qsec) ~ gear,
data = mtcars_t)
summary(erg_manova)

Für eine MANOVA stehen verschiedene Teststatistiken zur Wahl. Die Default-Variante ist Pillai, aber es können ebenso die Statistiken nach Wilks, Hotelling-Lawley oder Roy gewählt werden. Der Aufruf der MANOVA selbst bleibt dabei gleich, stattdessen wird im Rahmen der Summary-Funktion der Name der gewünschten Teststatistik mit übergeben.

# MANOVA mit anderer Teststatistik
summary(erg_manova,
test = "Wilks")
summary(erg_manova,
test = "Hotelling-Lawley")
summary(erg_manova,
test = "Roy")

Follow-Up-Analysen

Wenn die MANOVA signifikant wird, dann weiß man, dass sich die Kombination der abhängigen Variablen zwischen mindestes zwei Gruppen voneinander unterscheidet.

Eine häufige Follow-Up-Analyse bei einer signifikanten MANOVA ist die Lineare Diskriminanzanalyse, die jedoch als eigentständiges Verfahren außerhalb des Fokus dieses Tutorials liegt. Den R-Code für eine Diskriminanzanalyse finden Sie hier.

Weiterhin kann man als Follow-Up-Analysen ANOVAs durchführen, um getrennt für die AVs zu prüfen, ob sich die Gruppen unterscheiden. Dazu nutzt man das Ergebnis der MANOVA und die Funktion summary.aov.

# ANOVAs

summary.aov(erg_manova)

Aber auch bei signifikanten ANOVAs weiß man noch nicht, welche Gruppen sich genau voneinander unterscheiden. Zu diesem Zweck kann man Post-hoc-Tests je AV durchführen.

Für Post-hoc-Tests stehen verschiedene Methoden zur Verfügung, die sich in der Art der Kontrolle des Alpha-Fehlers voneinander unterscheiden. Hier im Beispiel wird die Methoden nach Holm verwendet.

# Univariate Post-hoc Tests

pairwise.t.test(mtcars_t$mpg,
mtcars_t$gear,
p.adjust.method = "holm")

pairwise.t.test(mtcars_t$qsec,
mtcars_t$gear,
p.adjust.method = "holm")

# alternative Methoden wg. alpha-Fehler:
# "holm", "hochberg", "hommel", "bonferroni", "BH", "BY", "fdr", "none"
?p.adjust.methods

Prüfung der Voraussetzungen

Statistische Verfahren haben Voraussetzungen, die man prüfen muss, bevor man die Ergebnisse interpretieren kann. Nachfolgend wird der R-Code zur Prüfung folgender Voraussetzungen aufgeführt:

  • Multivariate Normalverteilung, keine multivariate Ausreißer
  • Homogenität der Varianz-/Kovarianzmatrizen
  • Keine Multikollinearität der AV
  • Linearität zwischen den AVs

# Multivariate Normalverteilung und Abwesenheit multivariater Outlier je Gruppe

library(MVN)
library(dplyr)

mult_n3 <- mvn(filter(mtcars_t, gear == 3)[, c("mpg", "qsec")],
mvn_test = "mardia",
univariate_test ="SW",
multivariate_outlier_method = "adj")
summary(mult_n3)

mult_n4 <- mvn(filter(mtcars_t, gear == 4)[, c("mpg", "qsec")],
mvn_test = "mardia",
univariate_test ="SW",
multivariate_outlier_method = "adj")
summary(mult_n4)

mult_n5 <- mvn(filter(mtcars_t, gear == 5)[, c("mpg", "qsec")],
mvn_test = "mardia",
univariate_test ="SW",
multivariate_outlier_method = "adj")
summary(mult_n5)

# Homogenität Varianz-/Kovarianzmatrizen

library(biotools)
erg_boxM <- boxM(cbind(mtcars_t$mpg, mtcars_t$qsec), mtcars_t$gear)
erg_boxM
erg_boxM$cov # Anzeige der Varianz-/Kovarianzmatrizen

# (sehr sensitiv, ggf. alpha = .001 statt .05 als Kriterium nehmen)

# pro AV

library(car)
leveneTest(mtcars_t$mpg, mtcars_t$gear)
leveneTest(mtcars_t$qsec, mtcars_t$gear)

# Keine Multikollinearität der AVs

# library(psych)
corr.test(mtcars_t[,c("mpg", "qsec")])

# (sollten alle absolut unter .90 liegen)

# Linearität zwischen AVs

plot(mtcars_t$mpg, mtcars_t$qsec)

Robuste MANOVA

Doch was können Sie tun, wenn die Normalverteilungsvoraussetzung oder die Annahme der Gleichheit der Varianz-/Kovarianzmatrizen verletzt ist? Für diesen Fall gibt es robuste Verfahren, die häufig auf Resampling (Bootstrapping) beruhen und diese Voraussetzungen nicht haben. Damit können Sie also auch bei einer Verletzung dieser beiden Voraussetzungen Ihre MANOVA durchführen.

In R können Sie dafür das Modul MANOVA.RM nutzen. Dieses ermöglicht eine robuste MANOVA, deren Aufruf sehr ähnlich ist wie bei der normalen MANOVA. Wenn Sie den Code mit der gewöhnlichen MANOVA oben vergleichen, dann sehen Sie, dass lediglich zwei weitere Parameter hinzugekommen sind, iter und seed. Diese beiden dienen für die Steuerung des Bootstrappings und setzen zum einen die Anzahl der Bootstrap-Stichproben fest. Zum anderen wird mit dem Seed-Wert ein Startwert für den Zufallszahlengenerator vorgegeben, damit man bei jedem Aufruf mit denselben Daten auch ein identisches Ergebnis erhält.

library(MANOVA.RM)
erg_manova_rob <- MANOVA.wide(cbind(mpg, qsec) ~ gear,
data = mtcars_t,
iter = 5000,
seed = 12345)
summary(erg_manova_rob)

Als Ergebnis erhalten Sie zwei verschiedene Teststatistiken, eine Wald-Typ-Statistik (WTS) und eine Modifizierte ANOVA-Type Statistik (MATS). In den meisten Fällen ist hier die MATS die bessere Wahl, weil diese Statistik robuster gegen kleine Stichproben ist und auch mit unregelmäßigen Varianz-/Kovarianzmatrizen besser umgehen kann. Sie erhalten dafür keine normalen p-Werte, sondern p-Werte die auf einem parametrischen Bootstrap-Verfahren beruhen.

Wenn Sie diese robuste MANOVA durchführen, dann kann die folgende Literaturquelle hilfreich sein, die von den Verfassern des MANOVA.RM-Moduls ist:

Friedrich, S., Konietschke, F., & Pauly, M. (2018).
Analysis of multivariate data and repeated measures designs with the R package MANOVA.RM
arXiv preprint arXiv:1801.08002.