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
Für einen schnell graphischen Überblick über größere Korrelationstabellen wird die Installation und das Laden des corrplot
Packages empfohlen.
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 die Korrelationen konzentrieren. Wichtig ist hierbei das method
Argument, welches standardmäßig die Produkt-Moment-Korrelation berechnet. Als Argument müssen wir die einzelnen Spalten als Wertereihe mithilfe des Dollar-Operators aus dem Datensatz extrahieren (siehe Kapitel 4.5).
[1] 0.06972529
Beim Vorliegen ordinaler Daten bevorzugen wir hingegen Rangkorrelation nach Spearman ("spearman"
) oder Kendall ("kendall"
), wofür das Argument method
entsprechend anpassen.
[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 uns zunächst die Spalten Alter, Extraversion und Neurotizismus aus und bezeichnen das Zwischenergebnis als big5_sub
.
Anschließend berechnen wir die Korrelation 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
Allerdings ist die Ausgabe vor allem bei größeren Korrelationstabellen nicht sonderlich übersichtlich. Deswegen verwenden wir zusätzlich die corrplot
Funktion aus dem gleichnamigen Package, wobei wir an dieser Stelle nur die Korrelationen (method = "number"
) im unteren Dreieck (type = "lower"
) anschauen möchten. In Abbildung 7.1 sehen wir auf der linken Seite die Korrelation mit farblicher Markierung. Positive Korrelation werden in blau und negative Korrelation in rot illustriert. Je kleiner die Korrelation, desto blasser ist Farbe der abgebildeten Korrelation.
Eine alternative Betrachtungsweise für Zusammenhänge sind Streudiagramme. Wir werden diese zwar im Detail erst in Kapitel 8.3 kennenlernen, allerdings bietet die direkt in R integrierte Funktion pairs()
einen schönen ersten Überblick über mögliche Assoziationen der jeweiligen Merkmale (siehe Abbildung 7.1 rechts).
Bei sehr großen Korrelationstabellen werden aber auch diese Visualisierungen schnell unübersichtlich. Daher bietet es sich an, stattdessen nur Kreise darzustellen, die je nach Richtung der Korrelation eine andere Farbe mit unterschiedlicher Deckkraft und je nach Betrag einen anderen Durchmesser haben. Exemplarisch untersuchen wir dafür die Assoziation zwischen den Fragen zur Extraversion und zum Neurotizismus aus dem im remp
enthaltenen Datensatz namens big5_comp
. Dafür wählen wir die interessierenden Spalten aus und erstellen die Korrelationstabelle (siehe Kapitel 6.2).
Abschließend verwenden wir die bereits kennengelernte Funktion corrplot()
ohne zusätzliche Argumente. In Abbildung 7.2 wird sehen wir anschaulich, dass nur die jeweils die Fragen der entsprechenden Dimension miteinander korrelieren. Negative Korrelation innerhalb der Fragen zur Extraversion oder dem Neurotizismus weisen auf eine inverse Kodierung hin.
Zusammenhangsmaße im Kontext von Kontingenztafeln werden im Rahmen von Kapitel 9.6 besprochen.
Übung 7.3. (Noch nicht enthalten) Starte die Übung mit uebung_starten(7.3)
.