7 Einführung in das Datenhandling
Das Paretoprinzip – 80% der Ergebnisse werden mit 20% des Aufwands, 20% der Ergebnisse mit 80% des Aufwands erreicht – behält auch im datenanalytischen Kontext seine Gültigkeit: ein Großteil der Arbeitszeit wird darauf verwendet, Daten zu finden, zu importieren, zu säubern, zu transformieren, zu modifizieren und zu explorieren; die tatsächliche Analyse der Daten hingegen ist dann verhältnismäßig schnell erledigt. Wir fassen diese Schritte unter dem Begriff des Datenhandlings zusammen.
7.1 Daten- und Dateiformate tabellarischer Daten
Wenn wir von Datensätzen sprechen, denken wir zumeist direkt an tabellarische Daten. In den kommenden Kapiteln werden wir auch zunächst lediglich mit tabellarischen Daten arbeiten. Daten können und werden aber auch in anderen Datenformaten repräsentiert, zum Beispiel als verschachtelte und hierarchisch strukturierte Daten (dieses Datenformat wird uns u.a. bei der Arbeit mit APIs begegnen) oder als unstrukturierte Textdokumente – dazu an gegegeber Stelle mehr.
7.1.1 Tidy data
Dieselben Daten können in Tabellen unterschiedlich repräsentiert werden. Schauen wir uns dazu einen Datensatz an – was könnten hier Probleme sein?
## # A tibble: 8 x 3
## name variable value
## <chr> <chr> <dbl>
## 1 Anakin Skywalker height 188
## 2 Anakin Skywalker mass 84
## 3 Leia Organa height 150
## 4 Leia Organa mass 49
## 5 Luke Skywalker height 172
## 6 Luke Skywalker mass 77
## 7 Obi-Wan Kenobi height 182
## 8 Obi-Wan Kenobi mass 77
Diese Datenanordnung ist in dreierlei Hinsicht nicht optimal, wobei alle Probleme miteinander verbunden sind:
- Zwei Variablen sind in einer Spalte hinterlegt:
value
enthält sowohl Werte, die sich auf die Körpergröße als auch auf das Gewicht beziehen. - Entsprechend ist die Spalte
value
abhängig von der Spaltevariable
– allein anhand der Werte188
,84
,150
etc. wissen wir nicht, ob diese sich auf die Größeheight
oder das Gewichtmass
beziehen. - Daraus folgt, dass wir Probleme mit vektorisierten Funktionen – wir erinnern uns, in R sind Spalten in Datensätzen Vektoren – bekommen: wir können beispielsweise nicht einfach die
mean()
-Funktion auf die Spaltevalue
anwenden, um das Durchschnittsgewicht der Star-Wars-Charaktere zu berechnen, da dort auch die Werte für die Körpergröße enthalten wären.
Schauen wir uns eine zweite Version derselben Daten an:
## # A tibble: 4 x 2
## name height_and_mass
## <chr> <chr>
## 1 Anakin Skywalker 188;84
## 2 Leia Organa 150;49
## 3 Luke Skywalker 172;77
## 4 Obi-Wan Kenobi 182;77
Auch hier ergeben sich zwei miteinander verbundene Probleme:
- In einer Zelle stehen zwei Werte, die je eine unterschiedliche Variable abbilden.
- Sowohl bei Körpergröße als auch Gewicht handelt es sich um numerische Werte, sie werden aber hier als
character
gespeichert, wodurch wir keine Berechnungen durchführen können.
Dieselben Daten können wir jedoch auch besser tabellarisch abbilden:
## # A tibble: 4 x 3
## name height mass
## <chr> <int> <dbl>
## 1 Anakin Skywalker 188 84
## 2 Leia Organa 150 49
## 3 Luke Skywalker 172 77
## 4 Obi-Wan Kenobi 182 77
Daten, die so aufbereitet, werden als tidy data bezeichnet. Sie befolgen drei Regeln:
- Jede Variable steht in einer eigenen Spalte
- Jede Beobachtung/jeder Fall steht in einer eigenen Zeile
- Jeder Wert steht in einer Zelle
Im Umkehrschluss bedeutet dies, dass Daten die nicht diesen Regeln folgen, als messy data vorliegen und entsprechend aufbereitet werden sollten. Tidy data hat zwei entscheidende Vorteile:
- Konsistent aufbereitete Daten sind leichter zu lesen, zu verarbeiten, zu laden und zu speichern.
- Viele Verfahren (bzw. die zugehörigen Funktionen) in R setzen diese Art der Daten voraus.
Wenn Sie bisher vor allem mit Daten aus Befragungssoftware o.ä. gearbeitet haben, dann werden Ihnen diese Grundprinzipien bereits vertraut sein, da der Datenexport aus Befragungssoftware in der Regel diesen Prinzipien folgt. Tatsächlich liegen in der “Realität” Daten aber häufig nicht in dieser Form vor, beispielsweise weil die Eingabe oder Speicherung der Daten anderen Prinzipien als einer möglichst einfachen Analyse folgt (z. B. möglichst einfache Dateneingabe; Abruf von bestimmten Werten).
7.1.2 Dateiformate
Sie kennen vermutlich bereits eine Vielzahl an Dateiformaten, in denen tabellarische Daten gespeichert werden können. Einige Beispiel sind Excel-Dateien mit den Endungen .xls
bzw. .xlsx
oder SPSS-Dateien mit der Endung .sav
. Hierbei handelt es sich um sogenannte proprietäre Dateiformate, sich im Eigentum von Unternehmen befindliche und oft softwarespezifische Dateiformaten. Ein Vorteil dieser Formate ist es, dass oft relevante Zusatzinformationen für die jeweilige Software mitgespeichert werden, etwa Formatierungen in Excel oder Wertebeschriftungen in SPSS. Zugleich entsteht hierbei der große Nachteil, dass der Austausch der Daten zwischen verschiedenen Programmen oft recht kompliziert, nur durch Zusatzpakete oder Zwischenschritte möglich ist.
Ein offenes und sehr simples Dateiformat ist .csv
(für comma-separated values), das tabellarische Daten als Klartext abspeichert, von so gut wie jedem Programm auf jedem Computer der Welt gelesen werden kann und daher das Standardformat für tabellarische Daten ist. Dabei werden Kommas zu Trennung von Spalten und Zeilenumbrüche zur Trennung von Zeilen genutzt, wobei in der ersten Zeile optional Spaltenüberschriften stehen können. Die Daten aus obigen Beispiel sähen als .csv
also so aus:
name,height,mass
Anakin Skywalker,188,84
Leia Organa,150,49
Luke Skywalker,172,77
Obi-Wan Kenobi,182,77
Soll das Trennzeichen in den einzelnen Text-Werten vorkommen (beispielsweise als Komma in einem Satz), werden Textbegrenzungszeichen, häufig doppelte Anführungszeichen "
verwendet:
name,height,mass
"Skywalker, Anakin",188,84
"Organa, Leia",150,49
"Skywalker, Luke",172,77
"Kenobi, Obi-Wan",182,77
In verallgemeinerter Form kann letztlich jedes Zeichen als Trennzeichen genutzt werden; im deutschsprachigen Raum wird in .csv
-Dateien häufig ein Semikolon ;
statt einem Komma genutzt ,
(z. B. wenn Sie Daten aus SPSS oder Excel als .csv
exportieren):
name;height;mass
Anakin Skywalker;188;84
Leia Organa;150;49
Luke Skywalker;172;77
Obi-Wan Kenobi;182;77
Zwar kann R mittels unterschiedlicher Packages inzwischen auch relativ komfortabel Excel- und SPSS-Dateien einlesen; aus oben genannten Gründen werden wir zum Laden und Speichern jedoch vorrangig .csv
-Dateien nutzen.
7.2 Willkommen im Tidyverse
Die Idee, Datenhandling komplett codebasiert durchzuführen, erscheint zunächst vielleicht wenig komfortabel – vor allem wenn wir daran denken, dass das Auswählen und Verarbeiten von Dataframes bisher wenig intuitiv ablief (oder wissen Sie auf Anhieb noch, was der Unterschied zwischen iris[, "Sepal.Width"]
, iris$Sepal.Width
und iris[["Sepal.Width"]]
ist?).10
Seit einigen Jahren hat sich jedoch das Tidyverse als Standard des Datenhandlings in R durchgesetzt, was die mit dem Datenhandling verbundenen Schritte deutlich vereinfacht. Dabei handelt es sich um ein sogenanntes Meta-Package, also eine Sammlung von verschiedenen Packages, die allesamt den gleichen Designprinzipien folgen, um Datenhandling zu vereinfachen und den zugehörigen Code möglichst lesbar (für Menschen) zu machen. So haben beispielsweise Funktionen im Tidyverse in der Regel Verben als Namen, die genau das beschreiben, was die Funktion macht.
The tidyverse is an opinionated collection of R packages designed for data science. All packages share an underlying design philosophy, grammar, and data structures.
Das Tidyverse umfasst hierzu unter anderem Pakete für:
- Datenstrukturen (
tibble
) - Einlesen von Daten (z. B.
readr
für CSV,haven
für SPSS, Stata und SAS,readxl
für Excel) - Datentransformation und -modifikation (
tidyr
,dplyr
) - Spezielle Objekttypen (z. B.
stringr
für die Arbeit mit Textobjekten,forcats
für Faktoren,lubridate
für Zeitdaten) - Programmieren mit R (
purrr
) - Grafik-/Diagrammerstellung (
ggplot2
)
Alle Pakete lassen sich gesammelt installieren und laden11:
Die Standard-Datenstruktur des Tidyverse ist das Tibble, das wir bereits aus Kapitel 5.2 kennen. Zur Erinnerung, dabei handelt es sich im Wesentlichen um Dataframes mit einigen technischen und kosmetischen Verbesserungen:
## # A tibble: 150 x 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <fct>
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## 7 4.6 3.4 1.4 0.3 setosa
## 8 5 3.4 1.5 0.2 setosa
## 9 4.4 2.9 1.4 0.2 setosa
## 10 4.9 3.1 1.5 0.1 setosa
## # ... with 140 more rows
Im folgenden Kapitel werden wir uns nun ansehen, wie wir mittels Tidyverse-Funktionen Datensätze laden und modifizieren können.
Die erste Variante resultiert in einem Dataframe, der lediglich
Sepal.Width
enthält, Varianten zwei und drei extrahieren diese Spalte als Vektor.↩︎library(tidyverse)
lädt dabei genauer gesagt die Kernpakete des Tidyverse, die die alltäglich am häufigsten genutzten Funktionen bereitstellen. Tidyverse-Packages für eher spezifische Anwendungsgebiete – z. B.lubridate
für Zeitdaten oderhaven
für SPSS-Datensätze – müssen einzeln über denlibrary()
-Befehl geladen werden.↩︎