Kapitel 7 Deskriptive Statistik
Die beschreibende Statistik bietet neben Informationen über die Verteilungen und Zusammenhänge der interessierenden Merkmale ebenfalls die Möglichkeit, unplausible Werte zu identifizieren, die mit den im vorherigen Kapitel gelernten Methoden entfernt oder korrigiert werden müssen. Die Beschreibungen der kontinuierlichen und kategorialen Merkmale dürfen in keiner wissenschaftlichen Arbeit fehlen.
7.1 Lagemaße und Streuungsmaße
Für dieses Kapitel müssen die Packages des tidyverse
und remp
installiert und geladen werden.
Wir werden in diesem Kapitel den big5_mod
Datensatz ohne die Spalte namens ID
verwenden und bezeichnen diesen als big5_mod1
.
# A tibble: 200 × 5
Alter Geschlecht Extraversion Neurotizismus Gruppe
<dbl> <chr> <dbl> <dbl> <fct>
1 36 m 3 1.9 Mittel
2 30 f 3.1 3.4 Jung
3 23 m 3.4 2.4 Jung
4 54 m 3.3 4.2 Weise
# ℹ 196 more rows
Einen ersten Überblick über die Daten können wir mit der direkt in R integrierten Funktion summary()
erhalten, der wir lediglich den Namen des Datensatzes übergeben müssen.
Alter Geschlecht Extraversion Neurotizismus Gruppe
Min. :13.00 Length:200 Min. :2.300 Min. :1.400 Jung :147
1st Qu.:18.75 Class :character 1st Qu.:2.800 1st Qu.:2.700 Mittel: 39
Median :23.00 Mode :character Median :3.000 Median :3.100 Weise : 14
Mean :26.48 Mean :3.076 Mean :3.133
3rd Qu.:31.25 3rd Qu.:3.300 3rd Qu.:3.600
Max. :60.00 Max. :4.300 Max. :4.600
Hier sehen wir einen Vorteil von Faktoren. Während wir die Häufigkeiten der einzelnen Altersgruppen ausgegeben bekommen, kann R für die Spalte mit Geschlecht lediglich die Anzahl an vorhandenen Character Werten zählen. Für weitere Informationen über Faktoren und deren Umgang schaue dir erneut Kapitel 4.3.2 und 6.10 an.
Allerdings fehlt bei dieser Ansicht zum Beispiel die Standardabweichung und man kann mit die Ausgabe nicht vernünftig zum Exportieren formatieren. Im begleitenden remp Package gibt es die Funktion descriptive()
, die standardmäßig Anzahl, Minimum, 25% Quartil, Mittelwert, Median, 75% Quartil, die Standardabweichung und den Standardfehler für alle numerischen Spalten ausgibt. Möchte man Spalten nicht in der Ausgabe sehen, sollte man dieser zuvor mit select()
entfernen (siehe Kapitel 6.2).
# A tibble: 3 × 10
Variable N Min Q1 Mean Median Q3 Max SD SE
<chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Alter 200 13 18.8 26.5 23 31.2 60 11.4 0.8
2 Extraversion 200 2.3 2.8 3.08 3 3.3 4.3 0.35 0.02
3 Neurotizismus 200 1.4 2.7 3.13 3.1 3.6 4.6 0.68 0.05
Zusätzlich könnte man mit dem .print
Argument die Anzahl ausgegebener Spalten erhöhen. Für Grupperiungen der deskriptiven Statistiken verwenden wir die Funktion group_by()
aus dem dplyr
Package des tidyverse
. Dabei können wir der Funktion beliebig viele Spalten ohne Anführungszeichen übergeben. So können wir beispielsweise nach Geschlecht aufteilen.
# A tibble: 6 × 11
# Groups: Geschlecht [2]
Geschlecht Variable N Min Q1 Mean Median Q3 Max SD SE
<chr> <chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 f Alter 118 14 18 25.9 22 29.8 60 11.4 1.05
2 f Extraversion 118 2.4 2.8 3.05 3 3.2 4.3 0.36 0.03
3 f Neurotizismus 118 1.4 2.82 3.25 3.3 3.7 4.6 0.63 0.06
4 m Alter 82 13 20 27.3 23 32 59 11.4 1.25
# ℹ 2 more rows
Bei Interesse nach Unterschieden innerhalb der Geschlechter je nach Altersgruppe, fügen wir die Spalte Gruppe
in die Funktion group_by()
hinzu.
# A tibble: 18 × 12
# Groups: Geschlecht, Gruppe [6]
Geschlecht Gruppe Variable N Min Q1 Mean Median Q3 Max SD SE
<chr> <fct> <chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 f Jung Alter 89 14 17 20.4 20 23 30 4.21 0.45
2 f Jung Extraversion 89 2.4 2.8 3.07 3 3.3 4.3 0.37 0.04
3 f Jung Neurotizismus 89 1.4 2.9 3.29 3.3 3.6 4.6 0.58 0.06
4 f Mittel Alter 20 31 34.8 39.0 39 42.2 49 5.16 1.15
# ℹ 14 more rows
Der Nachteil an dieser Funktion ist die fehlende Flexibilität, falls man andere Schätzer inkludieren möchte. Dafür bietet sich die Funktion summarise()
aus dem dplyr
Package (Teil des tidyverse
). Als Argumente übergeben wir auf der linken Seite der Gleichung den gewünschten Namen der neu erstellen Spalte und auf der rechten Seite die Funktion zur Berechnung der Statistik mit dem gewünschten Spaltennamen.
Exemplarisch soll zunächst der Mittelwert mit der Funktion mean()
und die Standardabweichung mit sd()
berechnet werden. Bei fehlenden Werten müsste man zusätzlich das Argument na.rm
zum Entfernen fehlender Werte bei der Berechnung hinzufügen (z.B. mean(Extraversion, na.rm = TRUE)
). Wichtig ist allerdings, dass die innerhalb von summarise()
verwendeten Funktionen nur einen Wert pro Spalte ausrechnen.
# A tibble: 1 × 2
M SD
<dbl> <dbl>
1 3.08 0.347
Auch hier gruppieren wir mit der zuvor kennengelernten Funktion group_by()
.
# A tibble: 2 × 3
Geschlecht M SD
<chr> <dbl> <dbl>
1 f 3.05 0.358
2 m 3.11 0.328
Grundsätzlich kann jede Funktion summarise()
übergeben werden, die einen einzelnen Wert berechnet. Somit unterscheidet sich die Anwendung maßgeblich vom bereits kennengelernten mutate()
. Dort musste die Ausgabe immer eine Reihe von Werten umfassen, die der Anzahl der Zeilen im Datensatz entspricht.
Grundsätzlich können wir beliebig viele Berechnungen in einem Funktionsaufruf durchführen. Möchte man die gleichen Statistiken für mehrere Spalten berechnen, greifen wir erneut auf die Hilfsfunktion across()
zurück (siehe Kapitel 6.4.2). Hier müssen wir die verschiedenen Funktionen mit entsprechendem Namen innerhalb einer Liste übergeben. Listen als solche werden erst später eingeführt und müssen uns an dieser Stelle nicht weiter interessieren (siehe Kapitel 11.4).
big5_mod1 |>
summarise(across(
.cols = Extraversion:Neurotizismus,
.fns = list(M = mean, Median = median, SD = sd))
)
# A tibble: 1 × 6
Extraversion_M Extraversion_Median Extraversion_SD Neurotizismus_M Neurotizismus_Median
<dbl> <dbl> <dbl> <dbl> <dbl>
1 3.08 3 0.347 3.13 3.1
# ℹ 1 more variable: Neurotizismus_SD <dbl>
Wie dir vielleicht bereits aufgefallen ist, sieht die Ausgabe von summarise()
für mehrere Spalten anders aus als die von descriptive()
. Während erstere die Variablen nebeneinander in neue Spalten auflistet, fügt descriptive()
die Ergebnisse zeilenweise hinzu. Wenn wir die gleiche Ausgabe wie in descriptive()
erreichen möchten, müssen wir den Datensatz zunächst in ein langes Format bringen (siehe Kapitel 6.6). Nun gruppieren wir nach der neu erstellten Spalte namens Variable
. Anschließend können wir wie gewohnt mit summarise()
die gewünschten Berechnungen durchführen. Nichts anderes macht die Funktion descriptive()
hinter den Kulissen.
big5_mod1 |>
pivot_longer(
cols = c(Alter, Extraversion, Neurotizismus),
names_to = "Variable",
values_to = "Wert"
) |>
group_by(Variable) |>
summarise(
Q1 = quantile(Wert, 0.25),
Mean = mean(Wert),
Q3 = quantile(Wert, 0.75)
)
# A tibble: 3 × 4
Variable Q1 Mean Q3
<chr> <dbl> <dbl> <dbl>
1 Alter 18.8 26.5 31.2
2 Extraversion 2.8 3.08 3.3
3 Neurotizismus 2.7 3.13 3.6
Alternativen für einen schnellen Überblick bieten beispielsweise auch das skimr
Package mit der Funktion skim()
oder describe()
aus dem psych
Package. Beide können auch nicht-numerische Spalten auswerten und erstere gibt zu jeder Spalte sogar ein kleines Histogramm aus.
Übung 7.1. (Noch nicht enthalten) Starte die Übung mit uebung_starten(7.1)
.
7.2 Häufigkeiten und Kontingenztafeln
Zum Ausführen der Funktionen dieses Kapitels muss das tidyverse
und das Package janitor
installiert und geladen sein.
In diesem Kapitel verwenden wir den big5_mod
Datensatz aus dem remp
Package. Der schnellste Weg zur Berechnung von Häufigkeiten ist die direkt in R integrierte Funktion namens tables()
. Dabei übergeben wir die Spalten mithilfe des Dollar-Operators (siehe Kapitel 4.5). Hier wählen wir die Spalte Geschlecht
aus.
f m
118 82
Durch das Hinzufügen einer weiteren Variable, erhalten wir eine klassische Kontingenztafel, die wir mit Methoden im Rahmen von Kapitel 9.6 inferenzstatistisch betrachten werden. An dieser Stelle möchten wir die absoluten Häufigkeiten der Geschlechter zusätzlich nach den drei Altersgruppen aufteilen. In diesem Fall beinhalten beide Spalten Textbezeichnung. Hätten wir zwei numerische Spalten (z.B. Tod 0/1 und Geschlecht 0/1) solltest zusätzlich das Argument dnn
zum Festlegen der Dimensionsnamen verwenden.
Altersgruppe
Geschlecht Jung Mittel Weise
f 89 20 9
m 58 19 5
Ein weiteres nützliches Argument ist useNA
, welches wir zum Anzeigen fehlender Werte auf "ifany"
setzen können. Darüber hinaus können wir durch das Argument exclude
eine Faktorstufe für die Erstellung einer Kontingenztafel zur späteren Auswertung herausnehmen. Wäre bei der Variable Geschlecht
beispielsweise eine dritte Stufe namens Divers
mit wenigen Beobachtungen vorhanden, könnten wir diese so für die Hypothesentests ausblenden. Die Voraussetzung dafür ist, dass die Variable als Faktor kodiert ist (siehe Kapitel 4.3.2 und 6.10).
Eine dritte Dimension führt zur Ausgabe als sogenannte Liste (siehe Kapitel 11.4). Die erste Kontingenztafel unter dem Wort FALSE
beinhaltet alle Personen mit einer Extraversion kleiner oder gleich 3.5 und die Kontingenztafel darunter entsprechend alle Personen mit einer Extraversion größer 3.5, jeweils aufgeteilt nach Geschlecht und Altersgruppe. Das Inkludieren einer logischen Abfrage ist eine der großen Vorteil der table()
Funktion.
, , = FALSE
Jung Mittel Weise
f 81 18 9
m 54 18 4
, , = TRUE
Jung Mittel Weise
f 8 2 0
m 4 1 1
Nachteile der table()
Funktion sind hingegen die unbefriedigenden Möglichkeiten zum Exportieren als Word oder PDF Dokument sowie die umständliche Anzeige relativer Häufigkeiten und bedingter Wahrscheinlichkeiten. An dieser Stelle kommt die Funktion tabyl()
aus dem janitor
Package ins Spiel. Dabei ist das erste Argument der Name des Datensatzes gefolgt von ein bis drei Spaltennamen. Fehlende Werte werden automatisch angezeigt. Falls dies nicht erwünscht ist, könnten wir diese mit dem Argument show_na = FALSE
ausblenden.
Geschlecht n percent
f 118 0.59
m 82 0.41
Neben der absoluten werden zusätzlich die relativen Häufigkeiten angezeigt. Die Ausgaben der Funktion tabyl()
sind außerdem mit der Hilfe von R Markdown direkt nach Word exportierbar (siehe Kapitel 10.3.1). Möchten wir wie zuvor zwei Variablen miteinander in Bezug auf Häufigkeiten analysieren, sollten wir auf einige Formatierungshilfen aus dem janitor
Package zurückgreifen. Auch wenn diese zunächst umständlich erscheinen, profitiert man durch die übersichtliche Ausgabe enorm.
Die Funktionen zum Formatieren beginnen alle mit dem Präfix adorn
. In unserem ersten Beispiel sind wir an Unterschieden in Bezug auf die Häufigkeit der Altersgruppen je nach Geschlecht interessiert. Ausgeben möchten wir also die Zeilenrandsummen in einer extra Spalte ("col"
), die bedingten Wahrscheinlichkeiten für jede Altersgruppe gegeben des jeweiligen Geschlechts ("row"
) in Prozent, nur eine Nachkommastelle der Prozentwerte, die absoluten Häufigkeiten in Klammern und abschließend die Namen der verwendeten Spalten.
tabyl(big5_mod, Geschlecht, Gruppe) |>
adorn_totals("col") |>
adorn_percentages("row") |>
adorn_pct_formatting(digits = 1) |>
adorn_ns() |>
adorn_title()
Gruppe
Geschlecht Jung Mittel Weise Total
f 75.4% (89) 16.9% (20) 7.6% (9) 100.0% (118)
m 70.7% (58) 23.2% (19) 6.1% (5) 100.0% (82)
Möchten wir hingegen herausfinden, ob mehr Frauen oder Männer in den jeweiligen Altersgruppen befragt wurden, lassen wir uns stattdessen die Spaltenrandsummen in einer extra Zeile ("row"
) und die bedingten Wahrscheinlichkeiten mit Konditionierung auf die Altersgruppe ("col"
) ausgeben.
tabyl(big5_mod, Geschlecht, Gruppe) |>
adorn_totals("row") |>
adorn_percentages("col") |>
adorn_pct_formatting(digits = 1) |>
adorn_ns() |>
adorn_title()
Gruppe
Geschlecht Jung Mittel Weise
f 60.5% (89) 51.3% (20) 64.3% (9)
m 39.5% (58) 48.7% (19) 35.7% (5)
Total 100.0% (147) 100.0% (39) 100.0% (14)
Während die Funktion table()
vor allem für einen ersten Überblick und zum Erstellen von Kontingenztafeln für Hypothesentests geeignet ist, bietet die Funktion tabyl()
viele Formatierungsmöglichkeiten mit direkter Kompatibilität mit R Markdown zum Exportieren in ein Word Dokument.
Übung 7.2. (Noch nicht enthalten) Starte die Übung mit uebung_starten(7.2)
.
7.3 Zusammenhangsmaße
Zur Ausgabe von Korrelationen wird kein zusätzliches Package benötigt, da die dafür zuständigen Funktionen direkt in R integriert sind. Möchte man Korrelationstabellen hingegen optisch ansprechender oder als Graphik ausgeben lassen, sollten die Packages correlation
und see
installiert und geladen werden.
In diesem Kapitel wird ebenfalls der big5_mod
Datensatz aus dem remp
Package verwendet. Zwei der wichtigsten Zusammenhangsmaße für metrische Variablen sind die Kovarianz und die darauf basierende Korrelation. Eine Korrelation berechnen wir mit der cor()
Funktion, äquivalent dazu die Kovarianz mit cov()
. Wir werden uns im weiteren Verlauf auf Korrelationen konzentrieren. Zusammenhangsmaße im Kontext von Kontingenztafeln werden hingegen erst im Rahmen des Kapitels 9.6 besprochen. Ein zentrales Argument in der Funktion cor()
ist method
, welches standardmäßig Pearsons Produkt-Moment-Korrelation berechnet. Die ersten beiden Argumente stellen die einzelnen Spalten dar, die wir als Wertereihe mithilfe des Dollar-Operators aus dem Datensatz extrahieren (siehe Kapitel 4.5).
[1] 0.06972529
Beim Vorliegen ordinaler Daten bevorzugen wir hingegen Rangkorrelationen nach Spearman ("spearman"
) oder Kendall ("kendall"
), wofür das Argument method
entsprechend angepasst werden muss.
[1] 0.04874732
Um auf einen Schlag die Zusammenhänge von mehr als zwei Merkmalen zu explorieren, können wir der Funktion cor()
den Datensatz mit den interessierenden Variablen auch direkt übergeben. Wichtig ist dabei, dass alle Spalten numerisch sind. Für unser Beispiel wählen wir zunächst die Spalten Alter, Extraversion und Neurotizismus aus und bezeichnen das Zwischenergebnis als big5_sub
.
Anschließend berechnen wir die Korrelationen mit der Funktion cor()
.
Alter Extraversion Neurotizismus
Alter 1.0000000 -0.12250136 -0.23019948
Extraversion -0.1225014 1.00000000 0.06972529
Neurotizismus -0.2301995 0.06972529 1.00000000
Die Korrelationen sind allerdings nicht gerundet und auch sonst können wir diese Ausgabe nicht gut zum Exportieren in Word oder als PDF verwenden. Alternativ bietet sich die Funktion correlation()
aus dem gleichnamigen Package an. Das Ergebnis dieser übergeben wir zusätzlich der Funktion summary()
. Die Sterne (Asterisk) symbolisieren statistische Signifikanz.
# Correlation Matrix (pearson-method)
Parameter | Neurotizismus | Extraversion
-------------------------------------------
Alter | -0.23** | -0.12
Extraversion | 0.07 |
p-value adjustment method: Holm (1979)
Zur graphischen Ausgabe der Korrelationsmatrix verwenden wir schließlich die Funktion plot()
aus dem see
Package. In Abbildung 7.1 sehen wir die Korrelationen gefärbt in Abhängigkeit der Höhe und Richtung. Positive Korrelationen werden dabei in Blautönen und negative Korrelationen in Rottönen illustriert. Je geringer die Ausprägung der jeweiligen Korrelation ist, desto blasser erscheinen deren Farben.
Für Korrelationen zwischen lediglich drei Variablen erscheint diese Art der Visualisierung übertrieben. Bei größeren Korrelationstabellen erhalten wir hingegen einen schnellen Überblick über Zusammenhänge, die wir genauer betrachten sollten. In einem weiteren Beispiel wählen wir daher mit allen Fragen zur Extraversion dieses Mal zehn Spalten aus. Die verwendeten Funktionen verändern sich nicht. In Abbildung 7.2 wird deutlich ersichtlich, welche Fragen zur Extraversion invers mit einer gegensätzlichen Formulierung gestellt wurden. Jede zweite Frage involviert eine Verneinung, weswegen die Korrelation erwartungsgemäß negativ ist. Zur inferenzstatistischen Auswertung müssten wir daher diese Fragen vorher entsprechend umkodieren (siehe Kapitel 6.4.3).
In dem nächsten Kapitel werden wir die einzelnen Bestandteile von Abbildungen wie dieser kennenlernen. Zudem werden typische Anpassungsmöglichkeiten vorgestellt. So können wir beispielsweise mit theme_minimal()
den grauen Hintergrund verändern oder mit scale_x_discrete(guide = guide_axis(n.dodge = 3, check.overlap = TRUE))
dafür sorgen, dass sich die Namen der Variablen auf der x-Achse auf 3 Zeilen verteilen, falls sich diese ansonsten überlappen (siehe Kapitel 8.10.2).
Übung 7.3. (Noch nicht enthalten) Starte die Übung mit uebung_starten(7.3)
.