link zum pdf

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.

Wir arbeiten wiederum mit dem Datensatz kursdata_anon, der im Kurs erhoben wurde. Die Übung basiert dann auf Daten des European Social Surveys.

# Statistik 1: R Tutorat
# Übungsskript zum Datenmanagement
# Datum: 24.10.2024
# AutorIn: XXX

Vorbereitung: Einlesen der Daten und Aktivieren der nötigen Packages

…alternativ könnt ihr wieder über “Import Dataset” im Environment gehen. Oder einfach den Syntaxfile mit Importcode aus der vorherigen Session verwenden!

# Working directory setzen
setwd("C:/mein_laufwerk/mein_datenverzeichnis")
# oder bei Mac usern: 
setwd("~/daten") 
# Daten einlesen
library(haven)
kursdata_anon <- read_dta("kursdata_anon.dta")
# install.packages("tidyverse")
library(tidyverse)

 

1. Bereinigen: Aufräumen

Mit remove() können einzelne Objekte aus dem Environment gelöscht werden:

remove(irrelevantes_objekt) # löscht Objekt "irrelevantes Objekt"

Mit rm() werden alle Objekte aus dem Environment gelöscht:

rm(list = ls())

Alternativ kann im Environment auch das Besen-Symbol zum Löschen sämtlicher Objekte angeklickt werden.

Das Entfernen von Objekten, die im Arbeitsprozess nicht mehr benötigt werden, dient der Übersichtlichkeit. Wenn ein Objekt entfernt wurde, kann es über erneutes Einlesen des Datensatzes bzw. erneuter Ausführung des Befehls wieder eingefügt/erstellt werden.

 

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
# Alle Einheiten, die in der Ausgangsvariable die Werte 1 oder 2 aufweisen, tragen in der recodierten Variable den Wert "Smoker" - korrekt!
# Alle Einheiten, die in der Ausgangsvariable den Wert 3 aufweisen, tragen in der recodierten Variable den Wert "Non-Smoker" - korrekt
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
# Die ausschliesslich in der Nebendiagonalen besetzte Kreuztabelle zeigt an, dass sämtliche Werte umgepoolt wurden
# Die Option "useNA = "ifany"" stellt sicher, dass auch ggf. vorhande Missings in der Kreuztabelle als Kategorie auftauchen und so in den Check der Rekodierung einbezogen werden können.

 

3. Bereinigen: Variablen Umbenennen

library(dplyr)
kursdata_anon <- rename(kursdata_anon, "soz_hf" = "fach_neu")

Mittels rename() aus dplyr lassen sich die Namen der Variablen verändern. Dies kann hilfreich sein, wenn die Namen inhaltlich nicht interpretierbar oder zu lang sind. Bei der neu benannten Variable soz_hf ist nun am Namen erkennbar, dass gefragt wird, ob man Soziologie oder ein anderes Fach als Hauptfach hat.

 

4. Datenauswahl: Variablen Selektieren

Eine typische analysevorbereitende Operation ist die Reduktion des Datensatzes auf die für die Analyse wichtigen Variablen:

kursdata_anon <- select(kursdata_anon, id, rauchen_binary, lezufr)  

Hier wurde, mithilfe des select()-Befehls, ein Teildatensatz mit den Variablen rauchen_binary und lezufr sowie - immer dabei - der ID erstellt. Der Datensatz ist nun auf die akut relevanten Variablen begrenzt und übersichtlich.

Da die ausgeschlossen Variablen üblicherweise in den weiteren Operationen der Syntax nicht mehr aufgegriffen werden, wird bei Anwendung von “select” meist kein neuer Datensatz angelegt, sondern einfach der Ausgangsdatensatz reduziert

 

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.

 

Hier gehts weiter zur Übung II