13 Daten säubern
Nicht immer sind Datensätze eins zu eins verwendbar für statistische Auswertungen. Meist - wie auch beim Voto-Datensatz - müssen wir zuerst Variablen recodieren, um diese besser auswerten zu können, oder wollen neue Variablen bilden. Ein paar wichtige Befehle dafür werden in diesem Kapitel kurz vorgestellt.
Dieses Kapitel folgt in etwa Chapter 3 des Buches R for Data Science
13.1 Datensätze laden
Beginnen wir mit der Frage, wie wir überhaupt Daten in R reinladen können. Die Daten für die Grafiken wurden mit dem Befehl read.table()
reingeladen, weil diese als .csv
-File zur Verfügung standen. Teilweise müssen wir aber Textdateien, Excel-Files, Stata-Daten und viele weitere Varianten in R reinladen. Für fast alle Möglichkeiten gibt es auch spezifische Funktionen (beispielsweise ein read.dta()
für Stata-Daten in der Package foreign
), die mit einer Google-Suche zu finden sind.
Bleiben wir aber bei der generelleren Variante, einer Tabelle mit Daten, wobei die Zellen beispielsweise mit Kommas, Strichpunkte oder Tabs getrennt sind. In diesem Fall können wir die Grundfunktion read.table()
verwenden.
voto <- # vor dem Pfeil kommt wie üblich der Name des Objekts
read.table("voto855_sample.csv", # Pfad zur Datei
header = T, # falls im csv-File Variablennamen drin sind: T/TRUE
sep = ";", # wie sind die Zellen getrennt (separated)?
stringsAsFactors = F, # Texte als Faktoren: F/FALSE
fileEncoding="UTF-8" # welche Textkodierung
) # Klammer nicht vergessen!
Mit demselben Befehl können unterschiedlichste Datenfiles geöffnet werden. Grundsätzlich, falls unbekannt, lohnt es sich, den Datensatz zuerst mit einem Texteditor zu öffnen, um die Struktur zu sehen.
Haben wir mit R gearbeitet und einen Datensatz so bearbeitet, wie wir ihn gebrauchen können, lohnt es sich, diese Daten auch neu abzuspeichern. Einerseits können wir wiederum ein csv-File abspeichern, wobei wir simultan mit write.table()
vorgehen. Die andere Möglichkeit ist, alle Objekte, Funktionen etc., also die aktuelle Arbeitsumgebung wie in der Kachel “Environment” angezeigt, abzuspeichern. Dafür speichern wir die Daten als .RData
-File ab.
# csv-File schreiben, sodass dieses in Tabellenprogrammen geöffnet werden kann
write.table( # da wir das ja extern machen, müssen wir kein Objekt bilden mit <-
voto, # welches Objekt soll abgespeichert werden?
file="sample.csv", # wo soll das Objekt abgespeichert werden?
sep=";", # wie sollen die Zellen getrennt werden?
fileEncoding="UTF-8" # welche Textkodierung
) # Klammer nicht vergessen!
# .RData-Image speichern
# speichert alles ab, nicht nur ein Objekt
save.image("sample.RData")
13.2 Beobachtungen und Variablen auswählen
Nicht immer wollen wir alle Beobachtungen oder alle Variablen in einem Datensatz anschauen - wie bei den Grafiken, wo wir uns für vier Variablen interessiert haben. In dplyr
gibt es mit den Befehlen filter()
und select()
intuitive Funktionen, um das durchzuführen.
# filter() wählt Daten nach Bedingungen aus (rows)
voto.frauen <- filter(voto, sex=="2 woman")
voto.jungefrauen <- filter(voto, sex=="2 woman", birthyear>1979)
# select() wählt Variablen aus (cols)
voto.partic <- select(voto, personid_4, part, part2)
# Variablen löschen
voto.red <- select(voto, -trust_1, -importance1, -value3, -value11)
Dabei gibt es einige Operatoren, die wohl nicht unbekannt sind:
>
ist grösser als, sowie>=
grösser gleich,<
ist kleiner als, sowie<=
kleiner gleich,==
steht für “entspricht”,!=
wiederum steht für “enspricht nicht”.
Kombiniert werden Bedingungen ebenfalls mit &
(und) sowie |
(oder). Zuletzt gibt es noch eine spezielle Funktion, um NA
, also Missings, zu finden. Mit is.na()
und der Umkehrung !is.na()
können wir fehlende Werte finden. Haben wir in einer Variable viele fehlende Beobachtungen (z.B. das Einkommen), können wir diese Beobachtungen ausschliessen, und dann Auswertungen mit den neuen, vollständigen Daten machen.
Details könnt ihr rausfinden, indem ihr ?filter
und ?select
tippt.
13.3 Variablen bilden und recodieren
Oft wollen wir Variablen so haben, dass sie für uns besser ausgewertet werden können. Beim Einstieg haben wir beispielsweise die Partizipation an zehn Abstimmungen als Zahlenwerte abgespeichert, damit wir diese in der Grafik einbinden können.
Zusätzliche Beispiele, wieso Variablen recodiert oder neu gebildet werden, sind:
- eine Dummy-Variable mit ist/ist nicht, z.B. eine Variable für Frauen, die 1 ist, wenn die Beobachtung von einer Frau stammt, oder 0, wenn es ein Mann ist;
- eine Variable, welche das Alter anzeigt, statt das Geburtsjahr;
- eine Variable mit Alterskategorien, statt einem fortlaufenden Alter;
- weil wir andere Labels haben wollen, als solche, die in den Daten drin sind;
- und viele weitere Möglichkeiten.
R bietet für jeden Geschmack Möglichkeiten, wie Variablen gebildet und recodiert werden können. Einige zentrale Beispiele sind im nächsten Code aufgezeigt:
# Dummy-Variablen
# Frau == 1 und Mann == 0
voto$frau <- as.numeric(voto$sex == "2 woman")
# alle Frauen, welche mind. 7 Mal teilgenommen haben
voto$frau.part <- as.numeric(voto$sex == "2 woman" & voto$part10 >= 7)
# oder wir wollen voto$part einfacher verwendbar machen, hat partizipiert == 1
voto$participated <- as.numeric(voto$part == "1 participated")
# Berechnungen machen
# Alter statt Geburtsjahr (präziser wäre, auch den Monat zu berücksichtigen)
voto$age <- 2017 - voto$birthyear
# Grundsätzlich funktioniert R wie Algebra mit Platzhaltern,
# das wäre also so etwas wie y = 2017 - x,
# nur das y und x nicht nur einzelne Werte sind, sondern Vektoren mit n Werten
# Kategorien bilden
# per logische Bedingung
voto$agecat <- NA
voto$agecat[voto$age >= 18] <- 1
voto$agecat[voto$age > 35] <- 2
voto$agecat[voto$age > 50] <- 3
voto$agecat[voto$age > 65] <- 4
# Variable per recode-Befehl neu formulieren
voto$income <- recode(voto$income,
"01 less than 2'000 CHF" = "<4'000 CHF",
"02 2'001-3'000 CHF" = "<4'000 CHF",
"03 3'001-4'000 CHF" = "<4'000 CHF",
"04 4'001-5'000 CHF" = "4'001-8'000 CHF",
"05 5'001-6'000 CHF" = "4'001-8'000 CHF",
"06 6'001-7'000 CHF" = "4'001-8'000 CHF",
"07 7'001-8'000 CHF" = "4'001-8'000 CHF",
"08 8'001-9'000 CHF" = "8'001-12'000 CHF",
"09 9'001-10'000 CHF" = "8'001-12'000 CHF",
"10 10'001-11'000 CHF" = "8'001-12'000 CHF",
"11 11'001-12'000 CHF" = "8'001-12'000 CHF",
"12 12'001-13'000 CHF" = ">12'001 CHF",
"13 13'001-14'000 CHF" = ">12'001 CHF",
"14 14'001-15'000 CHF" = ">12'001 CHF",
"15 more than 15'000 CHF" = ">12'001 CHF",
"98 don't know" = NA_character_,
"99 no answer" = NA_character_
)
Wenn wir jetzt die Variablen im Datensatz noch einmal anschauen, sehen wir auch, dass diese unterschiedliche “Typen” haben. Per str(voto)
sehen wir nach den Variablennamen jeweils eine Abkürzung, welche uns angibt, was das für Variablen sind. Wichtige Abkürzungen sind:
int
für Integer,num
für Numerisch, sowiedbl
für reale Zahlen, was also jeweils Zahlen repräsentieren,chr
steht für Textstrings,fctr
für Faktoren mit verschiedenen Levels, also im Hintergrund eine Zahl, die ein Label hat,- und viele weitere, beispielsweise für Daten, Zeit, und logische Werte, also TRUE und FALSE.
Viele weitere Möglichkeiten bildet in dplyr
der Befehl mutate()
, auf den wir hier aber nicht näher eingehen werden. Mehr über ?mutate
verrät die Hilfeseite.
13.4 Daten gruppieren und zusammenfassen
Neben den bereits kennengelernten Möglichkeiten, Daten zusammenzufassen, bietet dplyr
auch die Möglichkeit, mit dem Befehl summarize()
zu Werten wie Mittelwert, Median, Quantile etc. zu kommen. Insbesondere in Zusammenarbeit mit group_by()
ist dies ein sehr schneller Ansatz, um zu wichtigen deskriptiven Werten zu kommen.
Hier kommen neu Ketten ins Spiel. Anstatt immer alle Zwischenschritte abzuspeichern, können wir die Resultate einer Berechnung direkt weiter verwenden. Um dies zu machen, verwenden wir die sogenannte Pipe, %>%
. Diese kann übrigens per Ctrl+Shift+M eingefügt werden.
Grundsätzlich entspricht eine Pipe %>% im Code etwa einem “und dann”. Zuerst gruppieren wir Daten, und dann werden diese zusammengefasst. In mathematischer Notation entsprechen x %>% f(y)
sowie f(x, y)
, wobei das Spiel noch weiter geführt werden kann. Aber direkt ein Beispiel:
# Partizipation pro Altersgruppe und Geschlecht
voto %>% # nimm das Objekt voto und reiche es weiter zur nächsten Funktion
group_by(agecat, frau) %>% # gruppiere nach Alterskategorie, dann nach Frau
summarize(mean=mean(participated)) # bilde ein Mittelwert der Partizipation
## # A tibble: 8 x 3
## # Groups: agecat [?]
## agecat frau mean
## <dbl> <dbl> <dbl>
## 1 1 0 0.5000000
## 2 1 1 0.6666667
## 3 2 0 0.6521739
## 4 2 1 0.4800000
## 5 3 0 0.5416667
## 6 3 1 0.5862069
## 7 4 0 0.8529412
## 8 4 1 0.7500000
So haben wir jetzt den Mittelwert pro Alterskategorie nach Geschlecht, da wir zwei Funktionen miteinander verbinden konnten. Wenn wir möchten, können wir diese Werte auch als neues Objekt abspeichern und später weiterverwenden, beispielsweise in einer Grafik. Dann würden wir in der ersten Zeile einfach meanpart <- voto %>%
ergänzen.
Im summarize()
-Befehl können wir auch mehrere Werte gleichzeitig berechnen.
partsum <- voto %>%
group_by(agecat, frau) %>%
summarize(mean=mean(participated),
var=var(participated),
cases=n())
partsum
## # A tibble: 8 x 5
## # Groups: agecat [?]
## agecat frau mean var cases
## <dbl> <dbl> <dbl> <dbl> <int>
## 1 1 0 0.5000000 0.2727273 12
## 2 1 1 0.6666667 0.2333333 21
## 3 2 0 0.6521739 0.2371542 23
## 4 2 1 0.4800000 0.2600000 25
## 5 3 0 0.5416667 0.2590580 24
## 6 3 1 0.5862069 0.2512315 29
## 7 4 0 0.8529412 0.1292335 34
## 8 4 1 0.7500000 0.1935484 32
13.5 Deskriptive Statistik
Neben der grafischen Auswertung von Variablen ist es in R natürlich auch möglich, statistische Masszahlen zu erhalten. Neben summarize()
bietet uns R aber auch die Möglichkeit an, einzelne Zahlen direkt zu erhalten.
# Mittelwert der Partizipation (=Stimmbeteiligung)
mean(voto$participated, na.rm=T)
## [1] 0.65
# Median des Geburtsjahr
median(voto$birthyear)
## [1] 1962
# Max und Min
max(voto$birthyear)
## [1] 1999
min(voto$birthyear)
## [1] 1927
# Quantile
quantile(voto$part10, c(0.1, 0.9), na.rm=T)
## 10% 90%
## 3 10
# Varianz und Standardabweichung
var(voto$part10, na.rm=T)
## [1] 7.915985
sd(voto$part10, na.rm=T)
## [1] 2.813536
13.6 Übung
Um die neu kennengelernten Befehle anzuwenden, wird folgende kurze Übung vorgeschlagen, welche den Start für die eigene Datenauswertung darstellt.
Dabei kann auf die Unterlagen von der Einführung zurückgegriffen werden, wo alle notwendigen Befehle aufgeführt sind.
-
Erstelle ein R-Script, in dem du alle Befehle dokumentierst und falls nötig auch kommentierst (mit einem # am Anfang der Linie). Hinweis: in RStudio oben links auf das Symbol mit dem weissen Papier und dem grünen Plus klicken.
-
Von ILIAS den voto-Datensatz vom 21. Mai 2017 runterladen. In einem Ordner, das als ‘working directory’ dient abspeichern, und anschliessend in R laden. Hinweis:
setwd()
undread.table()
. -
Anschliessend den Datensatz erkunden und gleichzeitig im Fragebogen (ebenfalls auf ILIAS) die Ausprägungen der Variablen überprüfen. Eine Variable auswählen, die genauer betrachtet werden soll.
-
Den Datensatz auf die Variablen reduzieren, die wirklich interessieren, also die ausgewählte Variable und z.B. Abstimmungsentscheid, Partizipation, Alter oder Kanton, falls gewünscht auch eine Untergruppe definieren, die angeschaut werden soll.
-
Eine Dummy- oder kategorielle Variable erstellen.
-
Versuchen, diese Variable grafisch darzustellen, nach Möglichkeit auch mit einer zweiten Variable kombiniert. Kurz beantworten: wie könnte diese Grafik verbessert werden? Tipp: orientiere dich an den vorgestellten Grafiken.
-
R-Script abspeichern, testen ob dieser ohne Fehler durchläuft.
Wer auf der Suche nach noch mehr Möglichkeiten zum Einlesen von Daten ist, soll sich mit der Package
tidyr
vertraut machen. In dieser sind auch moderne Befehle drin, um Datensätze umzuformen/reshapen.