Einer Kreuztabelle Prozentwerte hinzufügen
Ich möchte eine Kreuztabelle ausgeben, die sowohl absolute Häufigkeiten als auch Prozentwerte enthält.
Ich erstelle folgende Kreuztabelle:
A <- rep (c ("A1" , "A2" , "A3" ), 10 )
B <- sample (1 : 5 , size= 30 , replace= TRUE )
C <- sample (c ("ja" , "nein" ), size= 30 , replace= TRUE )
df <- data.frame (rbind (table (B, A),
table (C, A)))
df
## A1 A2 A3
## 1 0 4 1
## 2 1 1 4
## 3 2 1 1
## 4 2 3 0
## 5 5 1 4
## ja 5 3 6
## nein 5 7 4
Die einzelnen Werte sollen nun mit den jeweiligen Prozentwerten ergänzt werden. Dies kann mit den Funktionen transmute()
und across()
erfolgen.
df %>%
# über jede Spalte
transmute (across (everything (),
# x ausgeben und " (x%)" anhängen
~ paste0 (.x, " (" , round (.x / sum (df), 2 ) * 100 , "%)" )
)
)
## A1 A2 A3
## 1 0 (0%) 4 (7%) 1 (2%)
## 2 1 (2%) 1 (2%) 4 (7%)
## 3 2 (3%) 1 (2%) 1 (2%)
## 4 2 (3%) 3 (5%) 0 (0%)
## 5 5 (8%) 1 (2%) 4 (7%)
## ja 5 (8%) 3 (5%) 6 (10%)
## nein 5 (8%) 7 (12%) 4 (7%)
Eine gemeinsame Kreuztabelle mit mehrere Variablen erstellen
Häufig erstellen wir verschiedene Kreuztabellen mit der selben “Gruppierungsvariable”, z.B. Geschlecht
oder Kontroll
- vs. Interventionsgruppe
.
Nehmen wir als Beispiel den Datensatz pf8
.
load (url ("https://www.produnis.de/R/data/pf8.RData" ))
# oder
pf8 <- jgsbook:: pf8
Möchten wir hinsichtlich der Variable Geschlecht
unterscheiden, würden wir die Kreuztabellen mit anderen Variablen einzeln per xtab()
oder table()
erstellen.
table (pf8$ Standort, pf8$ Geschlecht)
##
## männlich weiblich divers
## Rheine 90 112 1
## Münster 75 103 0
## Bahn 36 48 0
## Ladbergen 26 17 0
## Internet 60 157 0
table (pf8$ Bildung, pf8$ Geschlecht)
##
## männlich weiblich divers
## keinen 2 3 0
## Hauptschule 30 26 0
## mittlere Reife 46 53 0
## Ausbildung 10 19 0
## Fachabitur 23 42 0
## Abitur 64 76 0
## Hochschule 50 56 1
table (pf8$ Familienstand, pf8$ Geschlecht)
##
## männlich weiblich divers
## ledig 125 162 0
## Partnerschaft 56 98 0
## verheiratet 90 136 1
## geschieden 6 23 0
## verwitwet 5 13 0
## getrennt 4 4 0
Eine alternative Vorgehensweise besteht darin, mit der Funktion lapply()
eine list
der Kreuztabellen zu erstellen.
tbl.list <- lapply (pf8[, c ("Standort" , "Bildung" , "Familienstand" )],
function (x) xtabs (~ x + pf8$ Geschlecht))
tbl.list
## $Standort
## pf8$Geschlecht
## x männlich weiblich divers
## Rheine 90 112 1
## Münster 75 103 0
## Bahn 36 48 0
## Ladbergen 26 17 0
## Internet 60 157 0
##
## $Bildung
## pf8$Geschlecht
## x männlich weiblich divers
## keinen 2 3 0
## Hauptschule 30 26 0
## mittlere Reife 46 53 0
## Ausbildung 10 19 0
## Fachabitur 23 42 0
## Abitur 64 76 0
## Hochschule 50 56 1
##
## $Familienstand
## pf8$Geschlecht
## x männlich weiblich divers
## ledig 125 162 0
## Partnerschaft 56 98 0
## verheiratet 90 136 1
## geschieden 6 23 0
## verwitwet 5 13 0
## getrennt 4 4 0
Wir haben Zugriff auf die einzelnen Kreuztabellen per tbl.list[[1]]
oder tbl.list[[2]]
.
## pf8$Geschlecht
## x männlich weiblich divers
## ledig 125 162 0
## Partnerschaft 56 98 0
## verheiratet 90 136 1
## geschieden 6 23 0
## verwitwet 5 13 0
## getrennt 4 4 0
Zeilen- und Spaltensummen
Mit der Liste können wir nun weiterarbeiten. Zum Beispiel können wir Spalten- und Zeilensummen hinzufügen…
lapply (tbl.list, addmargins)
## $Standort
## pf8$Geschlecht
## x männlich weiblich divers Sum
## Rheine 90 112 1 203
## Münster 75 103 0 178
## Bahn 36 48 0 84
## Ladbergen 26 17 0 43
## Internet 60 157 0 217
## Sum 287 437 1 725
##
## $Bildung
## pf8$Geschlecht
## x männlich weiblich divers Sum
## keinen 2 3 0 5
## Hauptschule 30 26 0 56
## mittlere Reife 46 53 0 99
## Ausbildung 10 19 0 29
## Fachabitur 23 42 0 65
## Abitur 64 76 0 140
## Hochschule 50 56 1 107
## Sum 225 275 1 501
##
## $Familienstand
## pf8$Geschlecht
## x männlich weiblich divers Sum
## ledig 125 162 0 287
## Partnerschaft 56 98 0 154
## verheiratet 90 136 1 227
## geschieden 6 23 0 29
## verwitwet 5 13 0 18
## getrennt 4 4 0 8
## Sum 286 436 1 723
Prozenttabellen
… oder Prozenttabellen erstellen. Um die Prozentwerte zeilenweise zu bilden, muss der Parameter margin=1
angegeben werden. Für spaltenweises Vorgehen gilt margin=2
.
lapply (tbl.list, prop.table, margin= 1 )
## $Standort
## pf8$Geschlecht
## x männlich weiblich divers
## Rheine 0.443349754 0.551724138 0.004926108
## Münster 0.421348315 0.578651685 0.000000000
## Bahn 0.428571429 0.571428571 0.000000000
## Ladbergen 0.604651163 0.395348837 0.000000000
## Internet 0.276497696 0.723502304 0.000000000
##
## $Bildung
## pf8$Geschlecht
## x männlich weiblich divers
## keinen 0.400000000 0.600000000 0.000000000
## Hauptschule 0.535714286 0.464285714 0.000000000
## mittlere Reife 0.464646465 0.535353535 0.000000000
## Ausbildung 0.344827586 0.655172414 0.000000000
## Fachabitur 0.353846154 0.646153846 0.000000000
## Abitur 0.457142857 0.542857143 0.000000000
## Hochschule 0.467289720 0.523364486 0.009345794
##
## $Familienstand
## pf8$Geschlecht
## x männlich weiblich divers
## ledig 0.435540070 0.564459930 0.000000000
## Partnerschaft 0.363636364 0.636363636 0.000000000
## verheiratet 0.396475771 0.599118943 0.004405286
## geschieden 0.206896552 0.793103448 0.000000000
## verwitwet 0.277777778 0.722222222 0.000000000
## getrennt 0.500000000 0.500000000 0.000000000
Signifikanztests
Zudem können wir Signifikanztests rechnen.
lapply (tbl.list, chisq.test)
## $Standort
##
## Pearson's Chi-squared test
##
## data: X[[i]]
## X-squared = 26.296, df = 8, p-value = 0.0009347
##
##
## $Bildung
##
## Pearson's Chi-squared test
##
## data: X[[i]]
## X-squared = 9.4526, df = 12, p-value = 0.6639
##
##
## $Familienstand
##
## Pearson's Chi-squared test
##
## data: X[[i]]
## X-squared = 10.503, df = 10, p-value = 0.3975
Wenn wir die Liste in ein Objekt speichern, können wir uns nur die p-Werte ausgeben lassen.
chi.list <- lapply (tbl.list, chisq.test)
chi.list[[1 ]]$ p.value
eine große Kreuztabelle
Zu guter Letzt können wir die einzelnen Kreuztabellen zu einer “großen” Tabelle vereinen.
rbind (tbl.list[[1 ]],
tbl.list[[2 ]],
tbl.list[[3 ]])
## männlich weiblich divers
## Rheine 90 112 1
## Münster 75 103 0
## Bahn 36 48 0
## Ladbergen 26 17 0
## Internet 60 157 0
## keinen 2 3 0
## Hauptschule 30 26 0
## mittlere Reife 46 53 0
## Ausbildung 10 19 0
## Fachabitur 23 42 0
## Abitur 64 76 0
## Hochschule 50 56 1
## ledig 125 162 0
## Partnerschaft 56 98 0
## verheiratet 90 136 1
## geschieden 6 23 0
## verwitwet 5 13 0
## getrennt 4 4 0
dummy <- rbind (tbl.list[[1 ]],
tbl.list[[2 ]],
tbl.list[[3 ]])
# erzeuge ein Datenframe aus den Zeilennamen und den Werten
dummy <- data.frame ( row.names (dummy), dummy )
# lösche die alten Rownames
rownames (dummy) <- NULL
dummy
## row.names.dummy. männlich weiblich divers
## 1 Rheine 90 112 1
## 2 Münster 75 103 0
## 3 Bahn 36 48 0
## 4 Ladbergen 26 17 0
## 5 Internet 60 157 0
## 6 keinen 2 3 0
## 7 Hauptschule 30 26 0
## 8 mittlere Reife 46 53 0
## 9 Ausbildung 10 19 0
## 10 Fachabitur 23 42 0
## 11 Abitur 64 76 0
## 12 Hochschule 50 56 1
## 13 ledig 125 162 0
## 14 Partnerschaft 56 98 0
## 15 verheiratet 90 136 1
## 16 geschieden 6 23 0
## 17 verwitwet 5 13 0
## 18 getrennt 4 4 0
Zeilen und Spalten tauschen
Ich möchte bei meinem Datensatz Zeilen und Spalten vertauschen.
Dies kann mit der Funktion apply()
gemacht werden. Angenommen das Datenframe datensatz
sieht wie folgt aus …
# lade Testdatensatz datensatz
datensatz <- read.table (url ("http://www.produnis.de/R/data/DieDaten.csv" ), sep= ";" , header= TRUE )
# zeige "datensaz" an
datensatz
## Name Geschlecht Lieblingsfarbe Einkommen
## 1 Hans maennlich gruen 1233
## 2 Caro weiblich blau 800
## 3 Lars intersexuell gelb 2400
## 4 Ines weiblich schwarz 4000
## 5 Samira weiblich gelb 899
## 6 Peter maennlich gruen 1100
## 7 Sarah weiblich blau 1900
…so tauschen wir Zeilen und Spalten mittels
# vertausche Spalten und Zeilen
apply (datensatz, MARGIN= 1 , FUN= function (x) {x})
## [,1] [,2] [,3] [,4] [,5]
## Name "Hans" "Caro" "Lars" "Ines" "Samira"
## Geschlecht "maennlich" "weiblich" "intersexuell" "weiblich" "weiblich"
## Lieblingsfarbe "gruen" "blau" "gelb" "schwarz" "gelb"
## Einkommen "1233" " 800" "2400" "4000" " 899"
## [,6] [,7]
## Name "Peter" "Sarah"
## Geschlecht "maennlich" "weiblich"
## Lieblingsfarbe "gruen" "blau"
## Einkommen "1100" "1900"
Da die Funktion apply()
eine Typkonversion in die Klasse matrix
vornimmt, (und somit alle Datentypen auf den kleinsten gemeinsamen Nenner character
zurückfallen, siehe die Anführungszeichen im Output) muss bei Bedarf zurück in die Klasse data.frame
konvertiert werden.
# vertausche Spalten und Zeilen
as.data.frame (apply (datensatz, MARGIN= 1 , FUN= function (x) {x}))
## V1 V2 V3 V4 V5 V6
## Name Hans Caro Lars Ines Samira Peter
## Geschlecht maennlich weiblich intersexuell weiblich weiblich maennlich
## Lieblingsfarbe gruen blau gelb schwarz gelb gruen
## Einkommen 1233 800 2400 4000 899 1100
## V7
## Name Sarah
## Geschlecht weiblich
## Lieblingsfarbe blau
## Einkommen 1900
binäre Dummy-Variablen zusammenführen
Manchmal liegen Daten in Dummy-Variablen vor. So wird beispielsweise der Beruf einer Person nicht als Ausprägung der Variable Beruf
gespeichert, sondern es gibt für jeden Beruf eine Dummy-Variable, die “Ja
” oder “Nein
” enthält, je nachdem, welchen Beruf die Person ausübt.
# erzeuge Testdaten
df <- data.frame (
id = 1 : 5 ,
Busfahrer_in = factor (c ("ja" , "nein" , "nein" , "ja" , "nein" )),
Aerztin = factor (c ("nein" , "ja" , "nein" , "nein" , "nein" )),
Lehrer_in = factor (c ("nein" , "nein" , "ja" , "nein" , "nein" )),
Ingenieur_in = factor (c ("nein" , "nein" , "nein" , "nein" , "ja" ))
)
# anzeigen
df
## id Busfahrer_in Aerztin Lehrer_in Ingenieur_in
## 1 1 ja nein nein nein
## 2 2 nein ja nein nein
## 3 3 nein nein ja nein
## 4 4 ja nein nein nein
## 5 5 nein nein nein ja
Die Aufteilung in solche Dummy-Variablen wird beispielsweise gemacht, um logistische Regression zu berechnen.
In manchen Fällen kann es unerwünscht sein, solche Dummys im Datensatz zu haben.
Mit den Funktionen mutate()
und case_when()
können die Dummyeinträge in einer neuen Variable vereinigt werden. Das klappt allerdings nur, wenn sich die Dummyeinträge gegenseitig ausschließen (also keine Mehrfachauswahl).
# führe Dummys in "Beruf" zusammen
df %>%
mutate (Beruf = case_when (
Busfahrer_in == "ja" ~ "Busfahrer_in" ,
Aerztin == "ja" ~ "Arzt/Ärztin" ,
Lehrer_in == "ja" ~ "Lehrer/in" ,
Ingenieur_in == "ja" ~ "Ingenieur/in" )
)
## id Busfahrer_in Aerztin Lehrer_in Ingenieur_in Beruf
## 1 1 ja nein nein nein Busfahrer_in
## 2 2 nein ja nein nein Arzt/Ärztin
## 3 3 nein nein ja nein Lehrer/in
## 4 4 ja nein nein nein Busfahrer_in
## 5 5 nein nein nein ja Ingenieur/in
große Schlarmann, J. (2024b).
Statistik mit R und RStudio - Ein Nachschlagewerk für Gesundheitsberufe . Hochschule Niederrhein.
https://www.produnis.de/R
große Schlarmann, J. (2024a).
Statistik mit R und RStudio - Ein Nachschlagewerk für Gesundheitsberufe . Hochschule Niederrhein.
https://www.produnis.de/R