Diese Lerneinheit widmet sich dem Management von Daten. Mit R können
Variablen rekodiert, neu erstellt, gelöscht, umbenannt werden -
Prozeduren, die zur Vorbereitung der Datenanalyse wichtig sind.
2. Bereinigen: Rekodieren
Eine Variable rekodieren heisst, einige ihrer Ausprägungen
mit neuen Werten zu belegen. Manchmal ist es z.B. sinnvoll, mehrere
Ausprägungen einer metrischen Variable in Klassen zusammenfassen. Dies
ist etwa der Fall, wenn ihr euch für Generationen statt einzelne
Altersstufen interessiert. Ihr würdet dann in der Altersvariable z.B.
die Ausprägungen 25 bis 40 mit dem Wert “Millenial” rekodieren.
Hier wollen wir zu Übungszwecken die Variable fach
mit neuen Werten belegen.
attributes(kursdata_anon$fach)
## $label
## [1] "studiertes hauptfach"
##
## $format.stata
## [1] "%10.0g"
##
## $class
## [1] "haven_labelled" "vctrs_vctr" "double"
##
## $labels
## Soziologie Sonstiges
## 1 2
table(kursdata_anon$fach)
##
## 1 2
## 47 7
Dabei soll die Ausprägung ‘2’ zur Ausprägung ‘0’ umkodiert werden.
Studierende mit Hauptfach Soziologie tragen dann weiterhin die
Ausprägung ‘1’, Studierende mit einem anderen Hauptfach sind dann aber
mit ‘0’ codiert.
Meistens ist es sinnvoll, nicht die ursprüngliche Variable, sondern
eine Kopie von ihr umzukodieren. Deshalb replizieren wir im ersten
Schritt zunächst die Ausgangsvariable:
kursdata_anon$fach_neu <- kursdata_anon$fach
Hier wurde die Variable fach_neu gebildet und mit
den Werten der Variable fach angereichert.
Nun nutzen wir den schon bekannten Pfeil
<- als Rekodierungsanweisung:
kursdata_anon$fach_neu <- 0
Hier wurde die neu gebildete Variable überschrieben - allerdings so,
dass alle Ausprägungen gleich ‘0’ sind. Das ist nicht in
unserem Sinne! Deshalb noch mal von vorn:
kursdata_anon$fach_neu <- kursdata_anon$fach
Der Clou ist nun, zusätzlich zur Rekodierungsanweisung
<-2 eine
Bedingung in den Befehl einzufügen, so dass
nur bestimmte Werte rekodiert bzw. überschrieben werden. Solche
Bedingungen werden in R über eckige Klammern
([…]) gesetzt:
kursdata_anon$fach_neu[kursdata_anon$fach == 2] <- 0
Die Ausprägung ‘2’ der Variable fach_neu wurde hier,
wie intendiert, mit dem Wert ‘0’ überschrieben. Genau genommen wurden in
all jenen Messreihen die Variablenkopie
fach_neu mit dem Wert ‘0’ belegt, in denen die
Originalvariable fach den Wert ‘2’ aufweist.
Wir hätten in diesem Beispiel innerhalb der Bedingungen auch auf die
Variablenkopie statt die Ursprungsvariable verweisen können
(kursdata_anon$fach_neu[kursdata_anon$fach_neu == 2] <- 0
führt zum exakt identischen Ergebnis), oder die Rekodierung direkt in
der Ausgangsvariable vornehmen können - allerdings führen solche
internen Rekodierungen (bei der Ausgangs- und
Bedingungsvariable identisch sind) leicht zu Zirkelrekodierungen und
entsprechenden Codierungsfehlern. Die kugelsichere, extern
bedingte Befehlsstruktur (bei der Ausgangs- und Bedingungsvariable
nicht identisch sind), die exakt dem oben eingeführten Vorgehen
entspricht, lautet daher:
Daten$Neu <-
Daten$Original
Daten$Neu[Daten$Original
== Alte Ausprägung] <- Neue
Ausprägung
Oft erstellen wir in der Praxis die neue Variable nicht vorab als
Kopie der Ausgangsvariable, sondern legen die neue, rekodierte Variable
im ersten Rekodierungsschritt direkt an. Die Befehlsstruktur ist dann
entsprechend:
Daten$Neu[Daten$Original
== Alte Ausprägung] <- Neue
Ausprägung
Für Rekodierungsoperationen gibt es wie angedeutet verschiedene
wichtige Anwendungen, z.B.:
2.1 Variablenwerte Rekodieren: Umpolung
Gelegentlich sind Variablen in Datensätzen nicht stimmig zur Polung
codiert: Höhere Werte stehen dann für niedrige Ausprägungen und kleinere
Werte für höhere Ausprägungen. Dies ist kontraintuitiv und erschwert die
Interpretation von Analyseergebnissen. In unserem Datensatz trifft dies
z.B. auf die beiden Interessensvariablen intbild und
intmig zu:
attributes(kursdata_anon$intmig)
## $label
## [1] "interesse: Migration und Integration"
##
## $format.stata
## [1] "%9.0g"
##
## $class
## [1] "haven_labelled" "vctrs_vctr" "double"
##
## $labels
## sehr etwas gar nicht
## 1 2 3
Daher nehmen wir hier - wiederum in einer neuen Variable, allerdings
ohne vorher eine Kopie anzulegen - eine Umpolung durch
Rekodierung vor:
kursdata_anon$intmig_neu[kursdata_anon$intmig == 1] <- 3
kursdata_anon$intmig_neu[kursdata_anon$intmig == 2] <- 2
kursdata_anon$intmig_neu[kursdata_anon$intmig == 3] <- 1
Hier wurde die Variable intmig zur Variablen
intmig_neu mit umgepolten Werten rekodiert. Der höchste
Wert (3) zeigt nun auch das grösste Interesse am Thema der Migration an,
während der tiefste Wert (1) das geringste Interesse ausdrückt.
Alternativ wäre es hier nicht möglich gewesen,
intern-bedingte Rekodierungen vorzunehmen, also dieselbe Variable für
Bedingung und Rekodierung, ohne Anlage einer neuen Variable, zu
verwenden. Grund: Innerhalb der Befehlsreihe gäbe es dann im dritten
Schritt einen Rückgriff auf eine nach dem ersten Schritt nicht mehr
existente Kategorie.
Achtung: Die Label der Variable gehen bei
solchen Rekodierungen verloren, manchmal werden sie sogar falsch
übertragen. Ihr solltet die neue Bedeutung der Variablenwerte mindestens
im Skript dokumentieren, besser aber noch die neue Variable neu
labeln.
attributes (kursdata_anon$intmig_neu)
## NULL
library(labelled)
val_labels(kursdata_anon$intmig_neu) <- c("gar nicht" = 1, "etwas" = 2, "sehr" = 3)
Checken ob’s passt:
attributes(kursdata_anon$intmig_neu)
## $labels
## gar nicht etwas sehr
## 1 2 3
##
## $class
## [1] "haven_labelled" "vctrs_vctr" "double"
2.2 Variablenwerte Rekodieren: Missings korrigieren
summary(kursdata_anon$lezufr)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -99.00 61.50 71.00 66.37 80.75 98.00
In R müssen fehlende Werte als NA kodiert sein,
damit sie in weiterführenden Befehlen und Analysen auch als solche
erkannt werden. Häufig allerdings sind fehlende Werte in
bereitgestellten Daten durch numerische Angaben kodiert. Dies ist ein
Problem, weil dann insb. der Durchschnittswert, sonstige Lagemasse und
Streuungsangaben verfälscht werden können.
kursdata_anon$lezufr[kursdata_anon$lezufr == -99] <- NA
summary(kursdata_anon$lezufr)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 10.00 63.00 71.00 69.49 81.00 98.00 1
Da es sich in diesem Fall um eine einfache Variablenbereinigung
handelt, haben wir auf die Anlage einer neuen Variable
verzichtet.
2.3 Variablenwerte Rekodieren: Klassifizieren
Eine Klassifizierung ergibt vor allem dann Sinn, wenn metrischen
Variablen gruppenbildende Grenzen aufweisen: Klassifizierungen erlauben
Gruppenvergleiche wischen “armen” und “nicht-armen” Haushalten, zwischen
Ländern mit über- oder unterdurchschnittlichem Wachstum oder zwischen
Studierenden mit eher links- oder rechtsorientierter politischer
Haltung. So könnte man die verschiedenen Werte der “leftright”-Variable
in die Kategorien “links”, “mitte” und “rechts” kodieren. Auch hier
nehmen wir die Kodierung nicht in der Ursprungsvariable vor, sondern
legen eine neue Variable an:
kursdata_anon$leftright_kat[kursdata_anon$leftright <= 33] <- "links"
kursdata_anon$leftright_kat[kursdata_anon$leftright >= 34 & kursdata_anon$leftright <= 66] <- "mitte"
kursdata_anon$leftright_kat[kursdata_anon$leftright >= 67] <- "rechts"
Hier wurde eine neue (kategoriale) Variable mit dem Namen
leftright_kat erstellt. Allen Personen mit
Selbsteinschätzungen von 0 bis einschliesslich 33 wurde in der neuen
Variable der Wert ‘links’ zugewiesen, von 34 bis einschliesslich 66 der
Wert ‘mitte’ und ab 67 der Wert ‘rechts’. Alternativ wäre es hier auch
möglich gewesen, wie im ersten Beispiel vorzugehen und zunächst die neue
Variable als Kopie der alten anzulegen, um dann anschliessend
sequentiell die Klassen zu definieren.
2.4 Variablenwerte Rekodieren: Zusammenfassen
attributes(kursdata_anon$rauchen)
## $label
## [1] "letzte Woche geraucht?"
##
## $format.stata
## [1] "%18.0g"
##
## $class
## [1] "haven_labelled" "vctrs_vctr" "double"
##
## $labels
## ja nein, aber früher nein, noch nie
## 1 2 3
Variablen werden auch dann rekodiert, wenn wir Kategorien gleicher
Tendenz zusammenfassen wollen. Dies ist beispielsweise der Fall, wenn
wir alle Personen, die jemals geraucht haben, in einer
Variablenkategorie vereinigen wollen - gleich, ob sie aktuell rauchen
oder dies in der Vergangenheit getan haben:
kursdata_anon$rauchen_binary[kursdata_anon$rauchen <= 2] <- "Smoker"
kursdata_anon$rauchen_binary[kursdata_anon$rauchen == 3] <- "NonSmoker"
Hier wurde eine neue Variable mit dem Namen
rauchen_binary erstellt. Allen Personen mit Werten bis
einschliesslich ‘2’ in der Ursprungsvariable wurde nun der Wert ‘Smoker’
zugewiesen, Personen mit Werten gleich ‘3’ der neue Wert
‘NonSmoker’.
2.5 Rekodierungen Protipps
- Das Klassifizieren und Zusammenfassen von Variablen führt immer auch
zu einem Informationsverlust. Deswegen wägt immer gut ab, ob dieser
durch den Gewinn der Klassifikation auch gerechtfertigt ist.
- Rekodierungsoperationen sind klassensensibel. Grade mit
Faktorvariablen funktionieren bestimmte logische Verknüpfungen nicht,
oft sind dann vorgelagerte Variablenklassenumwandlungen (zu Character
oder Numeric) notwendig.
- Checkt eure Rekodierungen im Anschluss sowohl in der Datenmatix
(bildet ggf. per select() - siehe unten - einen neuen
Teildatensatz mit ausschliesslich original und neuer Variable, so dass
ihr die Verteilungen nebeneinander inspizieren und abgleichen könnt).
Oder nutzt alternativ eine einfache Kreuztabelle:
table(kursdata_anon$rauchen_binary, kursdata_anon$rauchen, useNA = "ifany")
##
## 1 2 3
## NonSmoker 0 0 27
## Smoker 17 10 0
table(kursdata_anon$intmig_neu, kursdata_anon$intmig, useNA = "ifany")
##
## 1 2 3
## 1 0 0 1
## 2 0 22 0
## 3 31 0 0
5. Datenauswahl: Merkmalsträger/Fälle Filtern
Ebenfalls eine wichtige Operation: Den Datensatz auf bestimmte
Merkmalsträger beschränken bzw. ausprägungsabhängige Teilgruppen des
Datensatzes bilden:
smokers <- filter(kursdata_anon, rauchen_binary == "Smoker")
Mit filter() haben wir nun Merkmalsträger mit der
Ausprägung “Smoker” herausgefiltert und damit eine neue Teilstichprobe
namens “smokers” erstellt, die ausschliesslich Personen enthält die
aktuell rauchen oder früher geraucht haben.
Die “Gegenteil-Stichprobe” aller NichtraucherInnen ergibt sich
entsprechend durch:
no_smokers <- filter(kursdata_anon, rauchen_binary == "NonSmoker")
Übrigens: Anstatt mit ==
(gleich), könnten wir auch mit !=
(ungleich) alle Merkmalsträger, die nicht die entsprechende
Ausprägung haben, herausfiltern.
5.1 Filtern: Teilgruppenvergleich
Gruppierungen mit filter() werden häufig
vorgenommen, um Mittelwerte verschiedener Teilgruppen miteinander zu
vergleichen. Zum Beispiel um die Frage zu beantworten, ob RaucherInnen
oder NichtraucherInnen zufriedener mit ihrem Leben sind.
mean(smokers$lezufr, na.rm = TRUE)
## [1] 67.96296
mean(no_smokers$lezufr, na.rm = TRUE)
## [1] 71.07692
Die Variable Lebenszufriedenheit ist von ‘’0’ bis ‘100’ kodiert,
wobei ‘100’ für die höchste Lebenszufriedenheit steht. Die beiden
Durchschnittswerte lassen erkennen wie sich die Lebenszufriedenheit der
Raucher im Mittel von der der Nichtraucher unterscheidet.
5.2 Filtern: Missings eliminieren
Merkmalsträger mit Missings auf analyserelevanten Variablen werden
vor der Analyse in der Regel ausgeschlossen. Wir können die
NAs einzelner Variablen nun gezielt mit dem
filter() Befehl entfernen:
kursdata_noNA <- filter(kursdata_anon,!is.na(rauchen_binary),!is.na(lezufr))
Hier wurden Merkmalsträger mit NAs in den Variablen
rauchen_binary und lezufr entfernt. Du
siehst im Environment, dass das neu erstellte Objekt
kursdata_noNA nun weniger observations hat als
der Teildatensatz kursdata_anon.
Folgende Texte empfehlen wir euch zur Lektüre und Vertiefung:
BCP Kapitel 3: Beckerman,
A.P., Childs, D.Z., Petchey, O.L. (2017): Getting Started with R.
Oxford: University Press.
GW Kapitel 5: Wickham, Hadley
und Garrett Grolemund (2018): R for Data Science. Import, Tidy,
Transform, Visualize, and Model Data.