Kapitel 72 Beschreibende Statistik

Computer und Statistik
Wir werden R oft benutzen, um Daten beschreibend zusammenzufassen. Manchmal möchten wir das für jede Statistik (z.B. Mittelwert, Standardabweichung) separat tun, manchmal möchten wir Befehle benutzen, die automatisch eine Tabelle mit allen gewünschten Statistiken erstellen.
72.1 Pakete für dieses Kapitel
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
72.2 Daten für dieses Kapitel
Wir benutzen in diesem Kapitel Daten aus einem in der Zeitschrift Plos One veröffentlichten Artikel hier klicken.
<-rio::import("https://ndownloader.figstatic.com/files/37930989")
data::datatable(data, filter='top', options=list(pageLength=5)) DT
72.3 Statistik über Gruppen
Im ersten Beispiel benutzen wir die Funktion tapply, doch beim ersten Versuch ergibt R NA als Resultat. Dieser Fehler passiert mir immer wieder. Was ist passiert? Es gibt fehlende Werte in der Variable bmi und R sagt: Hey, es gibt fehlende Werte, also ist das Resultat auch ein fehlender Wert. Excel geht da anders vor und rechnet einfach den Mittelwert der restlichen Werte.
tapply(data$bmi, data$sex, mean)
## female male
## NA NA
Wir müssen also R sagen: Rechne den Mittelwert der nicht-fehlenden Werte. Das tun wir mit dem Argument na.rm=TRUE.
tapply(data$bmi, data$sex, mean, na.rm=TRUE)
## female male
## 27.18487 28.14849
Möchten wir mehr als nur den Mittelwert, können wir das auch haben Dank an https://stackoverflow.com/questions/16546630/easy-way-to-combine-mean-and-sd-in-one-table-using-tapply.
<- function(x) c(mean = mean(x, na.rm=TRUE), sd = sd(x, na.rm=TRUE))
mean.sd simplify2array(tapply(data$bmi, data$sex, mean.sd))
## female male
## mean 27.184872 28.148487
## sd 5.644268 4.798799
Wollen wir noch die Anzahl Personen dazurechnen, wird es etwas schwieriger. Wir müssen die Funktion length anpassen, damit sie die fehlenden Werte richtig berücksichtig. Dank an http://www.cookbook-r.com/Graphs/Plotting_means_and_error_bars_(ggplot2)/.
# New version of length which can handle NA's: if na.rm==T, don't count them
<- function (x, na.rm=FALSE) {
length2 if (na.rm) sum(!is.na(x))
else length(x)
}
Benutzen wir diese Funktion nicht, wird n nicht stimmen.
<- function(x) c(n = length(x), mean = mean(x, na.rm=TRUE), sd = sd(x, na.rm=TRUE))
mean.sd simplify2array(tapply(data$bmi, data$sex, mean.sd))
## female male
## n 1545.000000 1169.000000
## mean 27.184872 28.148487
## sd 5.644268 4.798799
<- function(x) c(n = length(x, na.rm=TRUE), mean = mean(x, na.rm=TRUE), sd = sd(x, na.rm=TRUE))
mean.sd simplify2array(tapply(data$bmi, data$sex, mean.sd))
## Error in length(x, na.rm = TRUE): 2 arguments passed to 'length' which requires 1
Mit der Funktion lenght2 stimmt es, jetzt werden nur die Personen gezählt, die keine fehlenden werte in der Variable BMI haben.
<- function(x) c(n = length2(x, na.rm=TRUE), mean = mean(x, na.rm=TRUE), sd = sd(x, na.rm=TRUE))
mean.sd simplify2array(tapply(data$bmi, data$sex, mean.sd))
## female male
## n 1475.000000 1112.000000
## mean 27.184872 28.148487
## sd 5.644268 4.798799
Wir können dies mit summary Funktionen überprüfen.
summary(data$bmi)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 14.75 23.73 26.85 27.60 30.55 47.55 127
Wir sehen, dass wir 127 fehlende Werte haben. Das ist genau die Differenz der beiden length und length2 Versionen (siehe oben).
1545-1475
## [1] 70
# = 70
1169-1112
## [1] 57
# = 57
70+57
## [1] 127
# = 127
Wir könnten die Resultate auch in eine Tabelle speichern.
<- function(x) c(n = length2(x, na.rm=TRUE), mean = mean(x, na.rm=TRUE), sd = sd(x, na.rm=TRUE))
mean.sd <-data.frame(simplify2array(tapply(data$bmi, data$sex, mean.sd)))
table::export(table, "table.xlsx") rio
Wir könnten diese auch mit dem tidyverse (dplyr) approach tun.
<-data %>%
summary_tablegroup_by(sex) %>%
summarise(n_bmi=length2(bmi, na.rm=TRUE),
mean_bmi=mean(bmi, na.rm=TRUE),
sd_bmi=sd(bmi, na.rm=TRUE))
Dieser Weg ist vor allem dann sehr attraktiv, wenn wir mehrere Variablen zusammenfassen möchten.
Im folgenden Beispiel wollen wir alle numerischen Variablen zusammenfassen.
<-data %>%
summary_table2group_by(sex) %>%
summarise(across(where(is.numeric),.fns=list(mean=mean, sd=sd, n=length2), na.rm=TRUE,
.names="{col}_{fn}"))
Hier wählen wir ein paar einzelne Variablen aus:
<-data %>%
summary_table3group_by(sex) %>%
summarise(across(c(start_age, bmi, VASscore, ODIscore),.fns=list(mean=mean, sd=sd, n=length2), na.rm=TRUE,
.names="{col}_{fn}"))