Ein zum Thema passendes Youtube Video gibt’s hier
Man kann Statistik in deskriptive/erkundende und schließende/inferentielle/induktive/mathematische Statistik unterteilen. Erstere beschreibt die Daten im Prinzip nur und versucht sie zusammenfassend darzustellen. Zweitere nutzt Methode und Verfahren um die Daten anhand von Tests zu analysieren und Entscheidungen zu treffen. Im Data Science Bereich formuliert Hadley Wickham die Unterteilung wie folgt:
It’s possible to divide data analysis into two camps: hypothesis generation and hypothesis confirmation (sometimes called confirmatory analysis).
Viele, die R (oder andere Statistiksoftware) für ihre schließende Statistik (i.e. ANOVA, post-hoc Tests, Regression etc.) nutzen, führen vrher die deskriptive Statistik (i.e. einfache Mittelwerte, Minimum, Maximum ausrechen) noch in Excel durch. Grund dafür ist, dass dies mit Excel-Funktionen wie =MITTELWERT()
schlichtweg sehr schnell zu machen ist und die Ergebnisse dann direkt neben der Datentabelle zu sehen sind.
Es gibt aber auch Argumente, die dafür sprechen selbst diese deskriptive Statistik schon in R durchzuführen. Zum einen kann das Einfügen von Mittelwerten neben den eigentlichen Datentabellen in einem Excel-Tabellenblatt dazu führen, dass der folgende Import in R auf Probleme stößt. Zum anderen kann selbst die Berechnung von einfachen Mittelwerten in Excel schnell mühsam werden, wenn z.B. ein Mittelwert pro Gruppe unter nicht-Berücksichtigunge bestimmter Werte durchgeführt werden soll.
Dieses Kapitel soll deshalb zeigen wie schnell und komfortabel deskriptive Statistiken in R erstellt werden können.
Als Beispiel nehmen wir hier den in R hinterlegten Datensatz mtcars
: The data was extracted from the 1974 Motor Trend US magazine, and comprises fuel consumption and other aspects of automobile design and performance for 32 automobiles (1973–74 models).
In den Spalten sind folgende Informationen enthalten:
Noch bevor man deskriptive Statistiken anfertigt, sollte man sich den Datensatz stets genau anschauen um sicherzustellen, dass er vollständig ist und der Import in R korrekt funktioniert hat:
mtcars # Ganzer Datensatz
## mpg hp am cyl
## Mazda RX4 21.0 110 manu 6
## Mazda RX4 Wag 21.0 110 manu 6
## Datsun 710 22.8 93 manu 4
## Hornet 4 Drive 21.4 110 auto 6
## Hornet Sportabout 18.7 175 auto 8
## Valiant 18.1 105 auto 6
## Duster 360 14.3 245 auto 8
## Merc 240D 24.4 62 auto 4
## Merc 230 22.8 95 auto 4
## Merc 280 19.2 123 auto 6
## Merc 280C 17.8 123 auto 6
## Merc 450SE 16.4 180 auto 8
## Merc 450SL 17.3 180 auto 8
## Merc 450SLC 15.2 180 auto 8
## Cadillac Fleetwood 10.4 205 auto 8
## Lincoln Continental 10.4 215 auto 8
## Chrysler Imperial 14.7 230 auto 8
## Fiat 128 32.4 66 manu 4
## Honda Civic 30.4 52 manu 4
## Toyota Corolla 33.9 65 manu 4
## Toyota Corona 21.5 97 auto 4
## Dodge Challenger 15.5 150 auto 8
## AMC Javelin 15.2 150 auto 8
## Camaro Z28 13.3 245 auto 8
## Pontiac Firebird 19.2 175 auto 8
## Fiat X1-9 27.3 66 manu 4
## Porsche 914-2 26.0 91 manu 4
## Lotus Europa 30.4 113 manu 4
## Ford Pantera L 15.8 264 manu 8
## Ferrari Dino 19.7 175 manu 6
## Maserati Bora 15.0 335 manu 8
## Volvo 142E 21.4 109 manu 4
nrow(mtcars) # Anzahl Zeilen
## [1] 32
ncol(mtcars) # Anzahl Spalten
## [1] 4
names(mtcars) # Spaltennamen
## [1] "mpg" "hp" "am" "cyl"
str(mtcars) # Struktur des Datensatzes
## 'data.frame': 32 obs. of 4 variables:
## $ mpg: num 21 21 22.8 21.4 18.7 18.1..
## $ hp : num 110 110 93 110 175 105 24..
## $ am : Factor w/ 2 levels "auto","ma"..
## $ cyl: Factor w/ 3 levels "4","6","8"..
head(mtcars) # Erste 6 Zeilen
## mpg hp am cyl
## Mazda RX4 21.0 110 manu 6
## Mazda RX4 Wag 21.0 110 manu 6
## Datsun 710 22.8 93 manu 4
## Hornet 4 Drive 21.4 110 auto 6
## Hornet Sportabout 18.7 175 auto 8
## Valiant 18.1 105 auto 6
Natürlich gibt es in R mit mean()
das Gegenstück zu =MITTELWERT()
in Excel und wir könnten so Mittelwerte je Spalte berechnen und danach mit min()
, max()
usw. fortfahren. Dies und noch mehr wird allerdings auf einen Schlag mit der Funktion summary()
abgedeckt:
summary(mtcars$mpg) # Summary einer Spalte
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 10.40 15.43 19.20 20.09 22.80 33.90
summary(mtcars) # Summary des ganzen Datensatzes
## mpg hp am cyl
## Min. :10.40 Min. : 52.0 auto:19 4:11
## 1st Qu.:15.43 1st Qu.: 96.5 manu:13 6: 7
## Median :19.20 Median :123.0 8:14
## Mean :20.09 Mean :146.7
## 3rd Qu.:22.80 3rd Qu.:180.0
## Max. :33.90 Max. :335.0
Es fällt auf, dass die Funktion für die unterschiedlichen Spaltentypen auch unterschiedliche Infos ausgibt:
mpg
& hp
: Minimum, Erstes Quartil, Median, Mittelwert, Drittes Quartil, Maximumam
$ cyl
: Die Häufigkeit/Frequenz der jeweiligen FaktorstufenGerade für die Kombinationen aus Stufen mehrerer Faktoren ist es oft interessant die absolute/relative Häufigkeit zu betrachten. Dies geht mit table()
bzw. prop.table()
:
table(mtcars$am) # Absolut
##
## auto manu
## 19 13
table(mtcars$am, mtcars$cyl) # Absolut
##
## 4 6 8
## auto 3 4 12
## manu 8 3 2
prop.table(table(mtcars$am))
##
## auto manu
## 0.59375 0.40625
prop.table(table(mtcars$am, mtcars$cyl))
##
## 4 6 8
## auto 0.09375 0.12500 0.37500
## manu 0.25000 0.09375 0.06250
Oft soll die Deskriptive aber nicht nur über den ganzen Datensatz, sondern z.B. pro Faktorstufe erstellt werden, sodass Summary Statistics Tables erzeugt werden. Ein detaillierter Vergleich mehrerer packages zur Erzeugung solcher findet sich hier. Hier ist nur kurz das tab
package exemplarisch vorgestellt, welches die Deskriptive sowohl pro Gruppe, als auch über den gesamten Datensatz zusammen darstellt und standardmäßig Mittelwerte und Standardabweichungen berechnet:
library(tab)
tabmulti(data = mtcars,
xvarname = "am",
yvarnames = c("mpg", "hp"),
columns = c("overall", "xgroups"))
## Variable Overall auto manu
## 1 mpg, M (SD) 20.1 (6.0) 17.1 (3.8) 24.4 (6.2)
## 2 hp, M (SD) 146.7 (68.6) 160.3 (53.9) 126.8 (84.1)
Ich selbst nutze in der Regel aber keines der packages oben, sondern die Funktionen vom data.table
package. Das liegt nicht unbedingt daran, dass es das beste package für diesen speziellen Zweck der deskriptiven Statistik ist, sondern viel mehr daran, dass es diesen Zweck für meine Bedürfnisse vollständig erfüllt und ich es sowieso auch an vielen anderen Stellen benutze.
library(data.table)
mtcarsDT <- as.data.table(mtcars) # Umwandeln in data.table Format
# mpg MW insgesamt
mtcarsDT[, mean(mpg)]
## [1] 20.09062
# mpg MW pro "am"-Faktorstufe
mtcarsDT[, mean(mpg), by=am]
## am V1
## 1: manu 24.39231
## 2: auto 17.14737
# mpg MW pro "am"-"cyl"-Kombination
mtcarsDT[, mean(mpg), by=c("am", "cyl")]
## am cyl V1
## 1: manu 6 20.56667
## 2: manu 4 28.07500
## 3: auto 6 19.12500
## 4: auto 8 15.05000
## 5: auto 4 22.90000
## 6: manu 8 15.40000
Wie zu sehen, kann ein als data.table
formatiertes R-Objekt mittels der eckigen Klammern im Anschluss anders behandelt werden als die standardmäßigen data.frame
Objekte (hier das data.table Cheat Sheet). Wir nutzen es hier also so, dass wir vor dem ersten Komma nichts schreiben (Infos dazu weiter unten), zwischen dem ersten und dem zweiten Komma die gewünschte Funktion der gewünschten Spalte und nach dem zweiten Komma ein by=
statement um anzugeben nach welchen Faktorstufen sortiert werden soll.
Wir können mittels einer .()
(= Abkürzung für list()
) Klammer auch direkt mehrere Spalten auf einmal erzeugen und im gleichen Schritt die erstellte Spalte benennen, anstatt sie beim default Namen V1
zu belassen. Außerdem wollen wir noch den Mittelwert auf eine Stelle nach dem Komma runden:
# mpg MW, Min & Max insgesamt
mtcarsDT[, .(mw = round(mean(mpg),1),
min = min(mpg),
max = max(mpg))]
## mw min max
## 1: 20.1 10.4 33.9
# mpg MW pro "am"-Faktorstufe
mtcarsDT[, .(mw = round(mean(mpg),1),
min = min(mpg),
max = max(mpg)),
by=am]
## am mw min max
## 1: manu 24.4 15.0 33.9
## 2: auto 17.1 10.4 24.4
# mpg MW pro "am"-"cyl"-Kombination
mtcarsDT[, .(mw = round(mean(mpg),1),
min = min(mpg),
max = max(mpg)),
by=c("am", "cyl")]
## am cyl mw min max
## 1: manu 6 20.6 19.7 21.0
## 2: manu 4 28.1 21.4 33.9
## 3: auto 6 19.1 17.8 21.4
## 4: auto 8 15.1 10.4 19.2
## 5: auto 4 22.9 21.5 24.4
## 6: manu 8 15.4 15.0 15.8
In bestimmten Situationen kann es gewünscht sein die Deskriptive nur einen Teil der Daten durchzuführen. Hier könnte es z.B. von Interesse sein nur die Autos zu betrachten, die einen Verbrauch von unter 25 miles per gallon haben. Nun könnte natürlich standardmäßig z.B. mit dem Befehl subset(mtcarsDT, mpg<25)
ein neues R-Objekt erstellt (z.B. mtcars2
) und mit diesem dann die gleichen Befehle wie oben durchgeführt werden.
Mit einem data.table
Objekt geht das in dieser Situation allerdings noch leichter, nämlich mit dem Bereich vor dem ersten Komma:
# mpg MW, Min & Max insgesamt
# nur für Autos mit mpg < 25
mtcarsDT[mpg <25,
.(mw = round(mean(mpg),1),
min = min(mpg),
max = max(mpg))]
## mw min max
## 1: 17.8 10.4 24.4
# mpg MW pro "am"-Faktorstufe
# nur für Autos mit mpg < 25
mtcarsDT[mpg<25,
.(mw = round(mean(mpg),1),
min = min(mpg),
max = max(mpg)),
by=am]
## am mw min max
## 1: manu 19.5 15.0 22.8
## 2: auto 17.1 10.4 24.4
# mpg MW pro "am"-"cyl"-Kombination
# nur für Autos mit mpg < 25
mtcarsDT[mpg<25,
.(mw = round(mean(mpg),1),
min = min(mpg),
max = max(mpg)),
by=c("am", "cyl")]
## am cyl mw min max
## 1: manu 6 20.6 19.7 21.0
## 2: manu 4 22.1 21.4 22.8
## 3: auto 6 19.1 17.8 21.4
## 4: auto 8 15.1 10.4 19.2
## 5: auto 4 22.9 21.5 24.4
## 6: manu 8 15.4 15.0 15.8
Schließlich kann man auch mehrere Bedingungen und mehrere Spalten für die Deskriptive einbeziehen:
# mpg und hp MW nur für Autos mit mpg<25 und hp>90
mtcarsDT[mpg<25 & hp>90,
.(mw_mpg = round(mean(mpg),1),
mw_hp = round(mean(hp), 1)),
by=c("am", "cyl")]
## am cyl mw_mpg mw_hp
## 1: manu 6 20.6 131.7
## 2: manu 4 22.1 101.0
## 3: auto 6 19.1 115.2
## 4: auto 8 15.1 194.2
## 5: auto 4 22.1 96.0
## 6: manu 8 15.4 299.5
Bei Fragen kannst du mir gerne schreiben!
schmidtpaul@hotmail.de