Interaktive Übung: Datenmanagement mit dem tidyverse
Von Pipes bis Joins – Daten aufbereiten zum Selberbauen
In dieser interaktiven Übung bereitest du Daten mit dem tidyverse selbst auf – von der Pipe über Filtern, Auswählen und Neuberechnen bis zum Verknüpfen und Umformen von Datenquellen. Der gesamte R-Code läuft direkt im Browser; du musst nichts installieren.
Auf dieser Seite läuft ein komplettes R direkt in deinem Browser – ohne Installation, ohne Server. Beim ersten Laden dauert es ein paar Sekunden, bis unten “R is ready!” erscheint.
Jede Code-Zelle hat einen Run code-Knopf, und du kannst den Code verändern und erneut ausführen. Zu jeder Aufgabe gibt es einen aufklappbaren Tipp und eine Lösung – aber schau erst selbst, wie weit du kommst.
Warum Datenmanagement?
Ein oft zitierter Erfahrungswert: Der Großteil der Zeit in einem Datenprojekt geht nicht in die eigentliche Analyse, sondern ins Aufbereiten der Daten – filtern, umbenennen, neu berechnen, zusammenführen, umformen. Das tidyverse macht diese Schritte lesbar und verkettbar. Die Grundidee: wenige, klar benannte „Verben”, die jeweils einen data.frame hineinbekommen und einen data.frame zurückgeben – und die man mit der Pipe zu einem gut lesbaren Ablauf zusammensteckt.
Die Daten
Wir arbeiten mit zwei Tabellen. befragung enthält eine Zeile pro Person:
Und gruppen enthält Zusatzinformationen – eine Zeile pro Gruppe:
Beide Tabellen haben eine gemeinsame Spalte gruppe – die brauchen wir später zum Verknüpfen.
Die Pipe: %>% (bzw. |>)
Die Pipe nimmt das, was links steht, und setzt es als erstes Argument in die Funktion rechts ein. x %>% f(y) ist also dasselbe wie f(x, y). Lies das %>% einfach als „und dann”. Statt Funktionen tief zu verschachteln, liest sich der Code von oben nach unten wie ein Rezept.
Fang mit dem Datensatz an, den du „durchschickst”: befragung %>% .... Die innerste Funktion (filter) kommt zuerst, danach select.
Hinweis: Seit R 4.1 gibt es auch die eingebaute Pipe |>. Sie funktioniert hier fast identisch – im tidyverse ist %>% aber weiterhin sehr verbreitet.
Spalten auswählen: select()
select() behält (oder entfernt) Spalten. Praktisch sind die Hilfsfunktionen starts_with(), ends_with(), contains() sowie der Doppelpunkt a:c für Spaltenbereiche und das Minus -spalte zum Entfernen.
Beide Spalten beginnen mit "zufr_". Das erledigt starts_with("zufr") – also select(id, starts_with("zufr")).
contains("zufr") würde hier genauso funktionieren.
Zeilen filtern: filter()
filter() behält Zeilen, die eine Bedingung erfüllen. Nützliche Bausteine: ==, !=, <, >=, Verknüpfungen mit & (und) / | (oder), %in% für „ist in einer Menge” sowie is.na().
Zwei Bedingungen verbindest du mit & oder einfach mit einem Komma. Für „A oder B” ist gruppe %in% c("A", "B") am elegantesten.
Das Komma zwischen den Bedingungen wirkt wie ein logisches &.
Zeilen sortieren: arrange()
arrange() ordnet die Zeilen nach einer oder mehreren Spalten. desc() dreht die Reihenfolge um (absteigend).
Für absteigend: arrange(desc(zufr_nachher)).
Variablen (neu) berechnen: mutate()
mutate() fügt neue Spalten hinzu oder verändert bestehende. Der Rest der Tabelle bleibt erhalten (anders als bei summarise(), das gleich kommt). Zum Umkodieren sind ifelse() und – für mehrere Fälle – case_when() sehr nützlich.
Du kannst in einem mutate() mehrere Spalten anlegen (durch Komma getrennt) und dabei sogar auf gerade eben berechnete Spalten zugreifen: mutate(differenz = ..., verbesserung_proz = differenz / zufr_vorher * 100).
Bonus – Umkodieren mit case_when(): So legst du z.B. Altersgruppen an.
Verwandt: rename(neu = alt) benennt Spalten um.
Gruppieren & Zusammenfassen: group_by() + summarise()
Ein zentrales Muster ist split–apply–combine: die Daten nach einer Variable aufteilen, pro Gruppe eine Kennzahl berechnen und die Ergebnisse wieder zusammenführen. summarise() verdichtet dabei viele Zeilen zu einer pro Gruppe – mit Funktionen wie mean(), sd(), median() und n() (Anzahl).
In summarise() kannst du mehrere Kennzahlen anlegen: summarise(n = n(), m_vorher = mean(zufr_vorher), m_diff = mean(differenz)).
.groups = "drop" hebt die Gruppierung danach wieder auf – so vermeidest du Überraschungen bei nachfolgenden Schritten.
Datenquellen verknüpfen: Joins
Bisher hatten wir nur befragung. Jetzt kommt gruppen ins Spiel: Zu jeder Person wollen wir die Bedingung und den Standort ihrer Gruppe ergänzen. Das leisten die Join-Funktionen. Sie verbinden zwei Tabellen über eine gemeinsame Spalte (hier gruppe).
left_join(x, y)behält alle Zeilen vonxund ergänzt passende Infos ausy.inner_join(x, y)behält nur Zeilen, die in beiden vorkommen.full_join()behält alle Zeilen aus beiden Tabellen.anti_join()/semi_join()filternxdanach, ob es einen Partner inygibt.
Häng nach dem mutate() an: group_by(bedingung) %>% summarise(m_diff = mean(differenz), n = n(), .groups = "drop").
Umformen: pivot_longer() (Tidy Data)
Unsere Zufriedenheit steht in zwei Spalten (zufr_vorher, zufr_nachher). Das ist praktisch zum Anschauen, aber für Analysen und für ggplot2 sind Daten oft besser im langen Format: derselbe Wert (Zufriedenheit) in einer Spalte, und eine zweite Spalte, die den Zeitpunkt kennzeichnet. Das ist die Idee von tidy data – jede Beobachtung eine Zeile. pivot_longer() macht genau diese Umformung.
pivot_longer() braucht: welche Spalten (cols = starts_with("zufr")), den Namen der neuen Namensspalte (names_to = "zeitpunkt") und der neuen Werte-Spalte (values_to = "zufriedenheit"). Mit names_prefix = "zufr_" wird das „zufr_” aus den Namen entfernt.
Der umgekehrte Weg (lang → breit) geht mit pivot_wider().
🏆 Alles zusammen: die Capstone-Aufgabe
Jetzt verkettest du mehrere Verben zu einer durchgehenden Pipe – genau so sieht echtes Datenmanagement aus.
Bonus: die Belohnung – eine Abbildung
Sauber aufbereitete (tidy) Daten lassen sich sofort visualisieren. Hier fließt alles zusammen: Join, Umformen ins lange Format – und dann ggplot2 aus der ersten Übung.
Und dann?
Ein paar Dinge zum Weiterdenken:
across()wendet dieselbe Berechnung auf mehrere Spalten an, z.B.summarise(across(starts_with("zufr"), mean)).- Join-Schlüssel mit anderen Namen verbindest du mit
by = c("links" = "rechts"). - Fehlende Werte (
NA) behandelst du u.a. mitis.na(),drop_na()odermean(x, na.rm = TRUE).
Hilfreiche Anlaufstellen:
- dplyr: https://dplyr.tidyverse.org/
- tidyr: https://tidyr.tidyverse.org/
- „R for Data Science” (frei online): https://r4ds.hadley.nz/
- Cheat-Sheet: https://rstudio.github.io/cheatsheets/data-transformation.pdf
- Datenmanagement ist der größte – und unterschätzte – Teil der Analyse.
- Wenige Verben (
select,filter,mutate,summarise, Joins,pivot_*) decken erstaunlich viel ab. - Die Pipe macht aus verschachteltem Code ein lesbares Rezept.
- Ziel ist meist tidy data – die perfekte Grundlage für Analyse und Visualisierung.