Bei der Analyse größerer Datensätze untersuchen wir die Variablen oft auch auf Korrelationen. Dies kann einerseits wichtige deskriptive Informationen liefern und so zur Hypothesenbildung 1 beitragen oder auch als Voraussetzungsprüfung im Rahmen einer multiplen linearen Regression oder ANOVA dienen.2
Prinzip hinter Korrelationsmatrizen
Häufig werden zur Untersuchung der Zusammenhänge zwischen mehr als zwei Variablen sogenannte Korrelationsmatrizen verwendet. In einer Korrelationsmatrix sind alle Variablen miteinander korreliert; dargestellt werden die Korrelationskoeffizienten:
$$ r_{x_i} = \begin{bmatrix} r_{x_1, x_1} & r_{x_1, x_2} & r_{x_1, x_3} & r_{x_1, x_4} \\ r_{x_2, x_1} & r_{x_2, x_2} & r_{x_2, x_3} & r_{x_2, x_4} \\ r_{x_3, x_1} & r_{x_3, x_2} & r_{x_3, x_4} & r_{x_3, x_4} \\ r_{x_4, x_1} & r_{x_4, x_2} & r_{x_4, x_3} & r_{x_4, x_4} \end{bmatrix} $$
In dieser Korrelationsmatrix repräsentieren jede Zeile und jede Spalte eine Variable. In der Hauptdiagonalen wird jeweils die Variable mit sich selbst korreliert ($\rightarrow r = 1$). Da die Matrix symmetrisch ist, genügt die Darstellung in Form einer unteren Dreiecksmatrix – also alle Elemente inklusive und unter der Hauptdiagonale.
$$ r_{x_i} = \begin{bmatrix} 1 & \times & \times & \times \\ r_{x_2, x_1} & 1 & \times & \times \\ r_{x_3, x_1} & r_{x_3, x_2} & 1 & \times \\ r_{x_4, x_1} & r_{x_4, x_2} & r_{x_4, x_3} & 1 \end{bmatrix} $$
Korrelationen in R
In R kann eine tabellarische Korrelationsmatrix mit dem einfachen cor()
-Befehl erstellt werden. Unser Datensatz enthält die Variablen MotherEdu
, FatherEdu
, TVs
, Books
und Reading
; diese wollen wir miteinander korrelieren. Um eine übersichtliche Darstellung zu erhalten, ist es empfehlenswert, die Werte direkt auf zwei Nachkommastellen runden zu lassen.
round(cor(PISA2009[, c("MotherEdu", "FatherEdu", "TVs", "Books", "Reading")], use = "complete.obs"), 2)
## MotherEdu FatherEdu TVs Books Reading
## MotherEdu 1.00 0.46 -0.12 0.42 0.36
## FatherEdu 0.46 1.00 -0.12 0.38 0.29
## TVs -0.12 -0.12 1.00 -0.17 -0.09
## Books 0.42 0.38 -0.17 1.00 0.41
## Reading 0.36 0.29 -0.09 0.41 1.00
Die Tabelle beinhaltet alle wichtigen Informationen, ist allerdings visuell nicht sonderlich ansprechend. Da geht mehr! Mit der Basis-Plot-Funktion erhält man eine nur wenig übersichtliche Anhäufung von Streudiagrammen. Das ist nicht das mehr, das wir meinten.
plot(PISA2009[, c("MotherEdu", "FatherEdu", "TVs", "Books", "Reading")])

Graphische Korrelationsmatrizen mit ggplot2
Um eine Korrelationsmatrix graphisch darzustellen, kann das Paket ggplot2
verwendet werden. Dafür muss jedoch zunächst das Datenformat angepasst werden. ggplot2
kommt nur mit Dataframes klar, die sich im Long-Format befinden. Im Long-Format sind die Variablen alle in einer Spalte gesammelt, die Werte in einer zweiten Spalte und die Kombinationen an Variablen werden zeilenweise dargestellt.
Datensatz vorbereiten
Wir speichern uns zunächst die Korrelationskoeffizienten aus der cor()
-Funktion:
cor <- round(cor(PISA2009[,c("Books", "FatherEdu", "MotherEdu", "Reading", "TVs")], use = "complete.obs"), 1)
Anschließend können wir mit der melt()
-Funktion aus dem Paket reshape2
die Matrix aus dem Long-Format in einen Dataframe im Wide-Format überführen. Dabei schmilzen die Spalten förmlich zusammen und ergeben einen längeren, aber schmaleren Datensatz.
cor <- melt(cor)
Der Datensatz sieht nun so aus:
## Var1 Var2 value
## 1 Books Books 1.0
## 2 FatherEdu Books 0.4
## 3 MotherEdu Books 0.4
## 4 Reading Books 0.4
## 5 TVs Books -0.2
## 6 Books FatherEdu 0.4
## 7 FatherEdu FatherEdu 1.0
## 8 MotherEdu FatherEdu 0.5
## 9 Reading FatherEdu 0.3
## 10 TVs FatherEdu -0.1
## 11 Books MotherEdu 0.4
## 12 FatherEdu MotherEdu 0.5
## 13 MotherEdu MotherEdu 1.0
## 14 Reading MotherEdu 0.4
## 15 TVs MotherEdu -0.1
## 16 Books Reading 0.4
## 17 FatherEdu Reading 0.3
## 18 MotherEdu Reading 0.4
## 19 Reading Reading 1.0
## 20 TVs Reading -0.1
## 21 Books TVs -0.2
## 22 FatherEdu TVs -0.1
## 23 MotherEdu TVs -0.1
## 24 Reading TVs -0.1
## 25 TVs TVs 1.0
Nun können wir mit ggplot2
die Korrelationsmatrix graphisch darstellen. Als geom verwenden wir geom_tile()
– die Werte werden durch farbige Rechtecke repräsentiert.
Plot erstellen
ggplot(data = cor, aes(x=Var1, y=Var2, fill=value)) +
geom_tile()

Farbschema anpassen
Standardmäßig werden die Werte durch einen Gradienten von hellblau bis dunkelblau repräsentiert. Um dies zu ändern, können wir mit der Funktion scale_fill_gradient2()
die Farbrepräsentation anpassen. Mit dem Argument low
wählen wir aus, durch welche Farbe niedrige Werte repräsentiert werden – analog werden hohe Werte durch high
repräsentiert. Da für die Interpretation von Korrelationskoeffizienten vor allem entscheidend ist, ob überhaupt eine Korrelation besteht, sollte auch eine Repräsentation für Nullkorrelationen bestehen. Auf der Skala des Korrelationskoeffizienten (limit = c(-1,1)
) befindet sich die Nullkorrelation in der Mitte (midpoint = 0
), weswegen hierfür das Argument mid
definiert wird. Darüber hinaus können wir die Achsenbeschriftungen mit labs(x = NULL, y = NULL)
entfernen und als Theme theme_minimal()
3 auswählen.
ggplot(data = cor, aes(x=Var1, y=Var2, fill=value)) +
geom_tile() +
scale_fill_gradient2(low = "red", high = "lightblue", mid = "white",
midpoint = 0, limit = c(-1,1),
name="Correlation\nCoefficient") +
labs(x = NULL, y = NULL) +
theme_minimal()

Hin und wieder ist es erforderlich, einen Zeilenumbruch in einer Achsenbeschriftung, einer Plot-Überschrift oder einem Legenden-Titel vorzunehmen. Hierfür wird der Befehl
\n
verwendet. Leerzeichen sind keine erforderlich.
Der aktuelle Plot weist zwei Probleme auf:
- Die Hauptdiagonale geht von rechts oben nach links unten. Idealerweise sollte sie jedoch von links oben nach rechts unten verlaufen. Dadurch wird sichergestellt, dass die Variablennamen direkt an den tiles anliegen und der Plot gut lesbar ist.
- Eine Hälfte der graphische Korrelationsmatrix ist redundant.
Diese beiden Probleme können gelöst werden, indem wir den Datensatz weiter anpassen. Mit der Funktion upper.tri()
werden die Elemente rechts jenseits der Hauptdiagonale ausgewählt. Damit können wir diese Werte mit NA
überschreiben. Anschließend wird der Datensatz mit melt()
„geschmolzen“.
Hauptdiagonale spiegeln
Um die Richtung der Hauptdiagonalen im Plot zu verändern, müssen die Variablen aus zwei Richtungen ausgelesen werden. Hierfür kann die reorder()
-Funktion aus dem dplyr
-Paket direkt in der aes()
-Funktion von ggplot2
verwendet werden.
ggplot(data = cor, aes(reorder(Var2, -desc(as.character(Var2))),
reorder(Var1, desc(as.character(Var1))), fill=value)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "red", high = "lightblue", mid = "white",
midpoint = 0, limit = c(-1,1), space = "Lab", na.value = "white",
name="Correlation\nCoefficient") +
labs(x = NULL, y = NULL,
title = "Correlation Matrix") +
geom_text(aes(label = round(value,3))) +
theme_minimal()

Den gewonnen Weißraum können wir verwenden, um die Legende platzsparend zu positionieren:
ggplot(data = cor, aes(reorder(Var2, -desc(as.character(Var2))),
reorder(Var1, desc(as.character(Var1))), fill=value)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "red", high = "lightblue", mid = "white",
midpoint = 0, limit = c(-1,1), space = "Lab", na.value = "white",
name="Correlation\nCoefficient") +
labs(x = NULL, y = NULL,
title = "Correlation Matrix") +
geom_text(aes(label = round(value,3))) +
theme_minimal() +
theme(legend.key.size = unit(.8, "cm"),
legend.position = c(0.8, 0.75))

Da es sich meist um Pearson-Korrelationen handelt, muss der Korrelationskoeffizient in diesem Fall nicht näher erläutert werden. Sollten allerdings andere Verfahren wie Kendalls $\tau$ oder Spearmans $\rho$ zum Einsatz kommen, sollte dies angegeben werden.
Signifikanzen darstellen
Grundsätzlich sollten uns nur solche Korrelationen interessieren, die auch statistisch signifikant sind. In R lassen sich Korrelationen mit der cor.test()
-Funktion testen. Allerdings kommt diese Funktion nur mit zwei Variablen klar.
$p$-Werte bestimmen und zum Datensatz hinzufügen
Eine Alternative für mehrere Tests bietet die corr.test()
-Funktion aus dem psych
-Paket. Diese gibt neben der Korrelationsmatrix eine Matrix für die $p$-Werte der Korrelationen aus. Dies machen wir uns zunutze, um die Signifikanzen in den Plot zu integrieren. Dabei gehen wir weitestgehend analog zur Erstellung des Datensatzes cor
vor, um die Variable p.value
am Ende an den ursprünglichen cor
-Datensatz anzufügen.
cor_p <- psych::corr.test(PISA2009[,c("Books", "FatherEdu", "MotherEdu", "Reading", "TVs")],
use = "complete.obs",
alpha = .05)$p # p-Werte speichern
cor_p[upper.tri(cor_p)] <- NA # Redundante Werte überschreiben
cor_p <- cor_p |> melt() # Matrix schmelzen
cor <- cbind(cor, cor_p$value) # p-Werte an ursprünglichen Datensatz anfügen
colnames(cor)[4] <- c("p.value") # Variablennamen anpassen
$p$-Werte mit ggplot2
abbilden
Da in ggplot2
die Funktion geom_text()
nur einmal verwendet werden kann, müssen wir einen Workaround finden, um dennoch sowohl die Korrelationskoeffizienten als auch die $p$-Werte darzustellen. Ein möglicher Weg ist die paste()
-Funktion, mit der sich verschiedene Elemente als character
kombinieren und ausgeben lassen.
cor_plot <- ggplot(data = cor, aes(reorder(Var2, -desc(as.character(Var2))),
reorder(Var1, desc(as.character(Var1))), fill=value)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "red", high = "lightblue", mid = "white",
midpoint = 0, limit = c(-1,1), space = "Lab", na.value = "white",
name="Correlation\nCoefficient") +
labs(x = NULL, y = NULL) +
theme_minimal() +
theme(legend.key.size = unit(.8, "cm"),
legend.position = c(0.8, 0.75))
cor_plot + geom_text(aes(label = paste("r =", round(value, 3), "\n", "p =", round(p.value, 4))),
color = "black", size = 3.5)

Leider werden nun auch alle NA
für die Elemente oberhalb der Hauptdiagonale angezeigt. Dies liegt daran, dass die paste()
-Funktion den Typ character
ausgibt und ggplot2
somit nicht in der Lage ist, zu evaluieren, ob es sich um einen NA
handelt oder nicht. Doch dieses Problem lässt sich mit einer logischen Abfrage und einem kleinen Trick lösen. Der Trick dabei ist, dass leere Anführungszeichen keinen Text darstellen.
cor_plot + geom_text(aes(label = ifelse(is.na(value),
"",
paste("r =", round(value, 3), "\n", "p =", round(p.value, 3)))),
color = "black", size = 3.5)

-
für künftige Forschungsvorhaben ↩︎
-
Dabei wird vor allem überprüft, ob die vorhersagenden, unabhängigen Variablen zu stark untereinander korrelieren. Wenn dies der Fall ist, wird von Multikollinearität gesprochen. Diese hat zur Folge, dass die Schätzung der Korrelationsgewichte weniger stabil und die Aussagekraft des Modells verringert sind. Im besten Fall ist eine der Variablen redundant (fügt dem Modell also keine Vorhersagekraft hinzu) und kann aus dem Modell entfernt werden. ↩︎
-
theme_minimal()
hat den Vorteil, dass kein hellgrauer, leicht überstehender Hintergrund besteht. ↩︎