Datenaufbereitung mit tidyverse:
Transformation und Anreicherung

Data Science 1 - Programmieren & Visualisieren

Saskia Otto

Universität Hamburg, IMF

Wintersemester 2022/2023

Datentransformation mit ‘dplyr’

Zur Erinnerung

Die 3 Komponenten des ‘Data Wrangling’

Datensatztransformation mit dplyr

Typische Manipulationen Kernfunktion in ‘dplyr’
Manipuliere Beobachtungen (Zeilen) filter(), arrange()
Manipuliere Variablen (Spalten) select(), rename(), mutate(), transmute(),
Fasse Beobachtungen zusammen summarise()
Gruppiere Beobachtungen group_by(), ungroup()
Kombiniere Tabellen bind_rows, bind_cols und join_ Funktionen

Eine Demonstration mit Wachstumsinformation von 5 Fischarten

fish_growth <- tibble(
  Species = c("Gadus morhua", "Platichthys flesus", "Pleuronectes platessa",
    "Merlangius merlangus", "Merluccius merluccius"),
  Linf = c(110, 40.8, 54.4, 41.3, 81.7),
  K = c(0.4, 0.4, 0.1, 0.2, 0.1)
)

(‘Linf’ = mittlere maximale Länge, ‘K’ = Rate in der sich der Fisch an ‘Linf’ annähert)

Mit freundlicher Genehmigung der Fotografen von fishbase.org (Konstantinos I. Stergiou, Jim Greenfield) und uwphoto.no(Rudolf Svensen).

Transformation: Zeilen- und Spaltenmanipulation

Zeilenmanipulation | Sortieren

arrange() → sortiert Zeilen (also Beobachtungen) nach spezifischen Variablen:

Zeilenmanipulation | Filtern

filter() → extrahiert Reihen, die ein logisches Kriterium erfüllen:

Zeilenmanipulation | Verknüpftes Filtern

Verknüpfte Abfragen in filter() werden mit Kommata aufgeführt (UND-Operator):

Spaltenmanipulation | Variablenauswahl

select() → extrahiert Spalten nach Namen oder mittels Helferfunktion:

Spaltenmanipulation | Helferfunktion 1

Übersicht der Helferfunktionen für select()

Quelle: ältere Version des sog. cheatsheets
Data Transformation with dplyr (lizensiert unter CC-BY-SA).

Spaltenmanipulation | Namensänderung

rename() → ändert die Namen einzelner Variablen (neuerName = alterName):

fish_growth2 <- rename(fish_growth, FishSpecies = Species)
fish_growth2
# A tibble: 5 × 3
  FishSpecies            Linf     K
  <chr>                 <dbl> <dbl>
1 Gadus morhua          110     0.4
2 Platichthys flesus     40.8   0.4
3 Pleuronectes platessa  54.4   0.1
4 Merlangius merlangus   41.3   0.2
5 Merluccius merluccius  81.7   0.1

Spaltenmanip. | Variablenerstellung

mutate() und transmute() → erstellen neue Variablen:

Spaltenmanipulation | Helferfunktion 2

Übersicht der Helferfunktionen für mutate() / transmute()

Du kannst jede Berechnung mit einer Variablen machen solange diese vektorisiert ist:

Quelle: ältere Version des sog. cheatsheets Data Transformation with dplyr (lizensiert unter CC-BY-SA).

Kombinieren von Befehlen

Hilfreiches Tool

Bevor wir jetzt in die Datenmanipulation starten, werden wir ein sehr hilfreiches Werkzeug für verknüpfte Operationen kennenlernen!!!

Der ‘pipe’ Operator

2 Varianten des ‘pipe’ Operators

Das Original: %>%

  • Wurde zunächst durch das Paket ‘magritr’ zur Verfügung gestellt.
  • Ist nun aber auch über alle ‘tidyverse’ Pakete zugänglich.
  • → D.h., es muss erst eines dieser Pakete geladen werden, um den Operator nutzen zu können.

Neuer nativer Pipe Operator: |>

  • Ab der R Version 4.1 gibt es diesen nützlichen Operator auch direkt in base R.
  • → D.h., es muss KEIN Paket extra geladen werden.
  • In diesem Modul (auch in den swirl-Kursen) werden wir NUR mit dem nativen Operator |> arbeiten!

Wozu ein solcher Operator?

Vereinfacht Operationen:

  • Mit|> können diverse Funktionsaufrufe sequenziell miteinander verknüpfen werden, ohne Zwischenobjekte zu erstellen.
  • |> leitet den Inhalt des Objekts auf der linken Seite in den Ausdruck auf der rechten Seite.
  • Weitere Schritte können einfach und überall der Sequenz an Operationen hinzugefügt, entfernt oder auskommentiert werden.

‘Piping’ mit |> | Wie?

‘Piping’ mit |> | Interpretation

Erinnert doch fast an ein Kochrezept, oder?

Shortcut für |>

Kleiner Tipp:

Der Pipe-Operator lässt sich mit dem Shortcut strg (bzw. cmd) + shift + m automatisch schreiben.

Um den nativen Operator standardmäßig zu nutzen, muss vorweg unter

  • ‘Preferences > Code’ bzw.
  • ‘Tools > Global Options..’ > Code
  • bei ‘Use native pipe operator, |> (requires R 4.1+)’

ein Häkchen gesetzt werden!

Your turn …

Quiz 1-3

Transformation: Daten aggregieren

Datenaggregation | Zusammenfassung

summarise() → reduziert Variablen zu Einzelwerten:

Datenaggregation | Helferfunktion

Hilfreiche Funktionen, die zusammenfassen

Quelle: ältere Version des sog. cheatsheets
Data Transformation with dplyr (lizensiert unter CC-BY-SA).

Datenaggregation | ‘Shortcuts’

Es gibt 2 sehr nützliche Funktionen, die man anstelle von summarise() nutzen kann:

  • count() → zur Berechnung der Anzahl an Zeilen
  • distinct() → zum Entfernen von Duplikaten (Zeilen mit komplett gleichem Inhalt in den jeweiligen Spalten)
count()
iris |>
  summarise(n = n())
    n
1 150
# vs.
iris |>
  count()
    n
1 150
distinct()
iris |>
  filter(Species == "setosa") |>
  select(Species, Sepal.Length) |>
  distinct() |>
  as_tibble() # nur zur Anzeige hier
# A tibble: 15 × 2
   Species Sepal.Length
   <fct>          <dbl>
 1 setosa           5.1
 2 setosa           4.9
 3 setosa           4.7
 4 setosa           4.6
 5 setosa           5  
 6 setosa           5.4
 7 setosa           4.4
 8 setosa           4.8
 9 setosa           4.3
10 setosa           5.8
11 setosa           5.7
12 setosa           5.2
13 setosa           5.5
14 setosa           4.5
15 setosa           5.3

→ Wie Sie sehen, wurden die 50 Zeilen auf 15 reduziert.

Datenaggregation | Beispiel iris 1

Berechnung einer Statistik für mehrere Variablen gleichzeitig:

iris |>
  summarise(
    SL_mean = mean(Sepal.Length),
    SW_mean = mean(Sepal.Width),
    PL_mean = mean(Petal.Length),
    PW_mean = mean(Petal.Width)
  )
   SL_mean  SW_mean PL_mean  PW_mean
1 5.843333 3.057333   3.758 1.199333

Viel Schreibarbeit wenn mehr als nur der Mittelwert berechnet werden soll…

Lösung: Die Helferfunktion across()

Berechnung einer Statistik für mehrere Variablen gleichzeitig:

iris |> 
  summarise(
    across(
    .cols = Sepal.Length:Petal.Width, 
    .fns = mean
    )
  )
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.843333    3.057333        3.758    1.199333

Lösung: Die Helferfunktion across() | 2

Berechnung mehrerer deskriptiver Statistiken für alle kontinuerlichen Variablen → hier muss eine Liste dem .fns Argument übergeben werden:

iris |> 
  summarise(
    across(
    .cols = Sepal.Length:Petal.Width, 
    .fns = list(mean = mean, median = median, sd = sd)
    )
  )
  Sepal.Length_mean Sepal.Length_median Sepal.Length_sd Sepal.Width_mean
1          5.843333                 5.8       0.8280661         3.057333
  Sepal.Width_median Sepal.Width_sd Petal.Length_mean Petal.Length_median
1                  3      0.4358663             3.758                4.35
  Petal.Length_sd Petal.Width_mean Petal.Width_median Petal.Width_sd
1        1.765298         1.199333                1.3      0.7622377

Aber moment mal…

…was ist, wenn wir die Statistiken für bestimmte Gruppen (wie hier die Arten) getrennt bestimmen wollen????


Lösung: Operationen gruppenweise durchführen

  • group_by() nimmt eine existierende Tabelle und konvertiert sie in eine gruppierte Tabelle, in der Operationen gruppenweise durchgeführt werden können.
  • ungroup() entfernt Gruppierungen (bei summarise() nicht nötig, aber bei z.B. count()).

Prinzipien der gruppenweisen Operationen

Gruppierte Datenaggregation | iris

iris |>
  group_by(Species) |> # einfach diesen Befehl einschieben 
  summarise(
    across(
    .cols = Sepal.Length:Petal.Width, 
    .fns = mean
    )
  )
# A tibble: 3 × 5
  Species    Sepal.Length Sepal.Width Petal.Length Petal.Width
  <fct>             <dbl>       <dbl>        <dbl>       <dbl>
1 setosa             5.01        3.43         1.46       0.246
2 versicolor         5.94        2.77         4.26       1.33 
3 virginica          6.59        2.97         5.55       2.03 

Gruppierung zeitweise entfernen | iris

iris |>
  # group_by(Species) |> # Befehl auskommentieren
  summarise(
    across(
    .cols = Sepal.Length:Petal.Width, 
    .fns = mean
    )
  )
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.843333    3.057333        3.758    1.199333

Kontrollparameter einbauen | iris

  • Kontrollieren Sie jeden Zwischenschritt zwei-oder dreimal!
  • Überprüfen Sie bei Aggregationen und numerischen Zusammenfassungen immer, ob die richtige Anzahl an Datenpunkten auch eingeflossen ist. Denn dies kann ein Hinweis auf fehlerhaftes Aggregieren sein:
Mit n() die Zeilenzahl anzeigen
iris |>
  group_by(Species) |> 
  summarise(
    PL_median = median(Petal.Length),
    N = n()  # Klammer leer lassen
  )
# A tibble: 3 × 3
  Species    PL_median     N
  <fct>          <dbl> <int>
1 setosa          1.5     50
2 versicolor      4.35    50
3 virginica       5.55    50

Your turn …

Quiz 4-5

Transformation: Datensätze kombinieren

Kombination von Tabellen | 1

Zeilenweise nach Position

bind_rows() → hängt 2 oder mehr Tabellen zeilenweise aneinander:

  • Spalten werden nach Namen abgeglichen und fehlende Spalten werden mit NA aufgefüllt.
  • Weitere Funktionen die zeilenweise verbinden: intersect(), union(), setdiff()

Kombination von Tabellen | 2

Spaltenweise nach Position

bind_cols() → hängt 2 oder mehr Tabellen spaltenweise aneinander:

  • Zeilen werden hier entsprechend ihrer Position verknüpft → für ein Verknüpfung über die Werte nutzen Sie eine der folgenden XXX_join() Funktionen!

Kombination von Tabellen | 3

Zusammenfügung über Werte

XXX_join() → Die Funktionsgruppe verbindet Tabellen basierend auf gleichen Werten in übereinstimmenden Spalten:

  • Je nach übereinstimmenden Tabelleninhalten können dabei nur Spalten, nur Zeilen oder beides aneinander gehängt werden.

Übungsaufgabe

Zu bearbeitende Swirl-Lektionen

Kurs DS1-03-Datenaufbereitung oder per Anleitung durchs Tidyversum

  • L05-Transformation mit dplyr: Manipulation von Zeilen und Spalten
  • L06-Transformation mit dplyr: Gruppierte Aggregation
  • L07-Transformation mit dplyr: Datensätze kombinieren

Lernziele

Am Ende dieser Übungseinheit sollten Sie …

  • … die grundlegenden Kenntnisse der Datensatztransformation entsprechend einer Fragestellung beherrschen.
  • Dazu gehört
    • das Sortieren und Filtern von Zeilen,
    • das Auswählen und die Neuerstellung von Variablen,
    • das Aggregieren und die (Gruppen-spezifische) Erstellung von deskriptiven Statistiken und
    • das Kombinieren von relationalen Daten.

Wie fühlen Sie sich jetzt…?

Total konfus?


Lesetipps

  • Kapitel 5 Data transformation zur Datentransformation und
  • Kapitel 18 Pipes zum ‘pipe’ Operator in ‘R for Data Science’
  • Posit und DSB Cheatsheets

Posit Cheatsheet

Überblick an Funktionen im dplyr Paket

Cheatsheet zum tidyr Paket frei verfügbar unter diesem Link.

DSB Cheatsheet: Basic R functions

Enthält wichtigste Funktionen der Datenaufbereitung

Total gelangweilt?

Dann testen Sie doch Ihr Wissen in folgendem Abschlussquiz…

Abschlussquiz

Bei weiteren Fragen: saskia.otto(at)uni-hamburg.de

Creative Commons License
Diese Arbeit is lizenziert unter einer Creative Commons Attribution-ShareAlike 4.0 International License mit Ausnahme der entliehenen und mit Quellenangabe versehenen Abbildungen.