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).

  • Within the former, you’ll look deeply at the data and, in combination with your subject knowledge, generate many interesting hypotheses to help explain why the data behaves the way it does.
  • The complement of hypothesis generation is hypothesis confirmation. Hypothesis confirmation is hard for two reasons:
    1. You need a precise mathematical model in order to generate falsifiable predictions. This often requires considerable statistical sophistication.
    2. You can only use an observation once to confirm a hypothesis. As soon as you use it more than once you’re back to doing exploratory analysis. This means to do hypothesis confirmation you need to “preregister” (write out in advance) your analysis plan, and not deviate from it even when you have seen the data.

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.

Beispieldatensatz

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:

  • mpg: Miles/(US) gallon
  • hp: Gross horsepower
  • am: Transmission (automatic, manual)
  • cyl: Number of cylinders

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

Gesamtstatistiken

summary

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:

  • Für die numerischen mpg & hp: Minimum, Erstes Quartil, Median, Mittelwert, Drittes Quartil, Maximum
  • Für die Faktoren am $ cyl: Die Häufigkeit/Frequenz der jeweiligen Faktorstufen

table

Gerade 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

Summary Statistics Tables

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)

data.table

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.

Das by= statement

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.

Mehrere Spalten erzeugen

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

Bestimmte Werte ausschließen

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