R dplyr Data Wrangling Pipeline: Von Rohdaten zu sauberen Tabellen
Problem
Analysten verlieren Zeit mit dem Schreiben repetitiver R-Schleifen zur Bereinigung von Datensätzen. Das Ergebnis sind fragile Skripte, uneinheitliche Spalten und langsame Iterationen, sobald eine neue Datei eintrifft.
Agitate
Manuelle Schritte summieren sich: falsche Spalten auswählen, Transformationen in der falschen Reihenfolge anwenden oder vergessen, Faktoren gegenüber Zeichenketten korrekt zu behandeln. Jeder Fehler erzwingt einen erneuten Lauf und birgt das Risiko, falsche Kennzahlen an nachgelagerte Dashboards weiterzugeben.
Solution
Nutze eine konsistente dplyr-Pipeline, die der SQL-Logik ähnelt und jede Transformation lesbar hält. Die folgenden Verben decken Spaltenauswahl, Zeilenfilter, neue Features, Aggregationen, Sortierung und sichere Joins ab, sodass Daten vor dem Modeling oder der Visualisierung ordentlich (tidy) sind.
Core pipeline in action
library(dplyr)
clean_sales <- raw_sales %>%
mutate(
region = as.character(region), # avoid accidental factor levels
revenue = price * quantity
) %>%
filter(!is.na(revenue), revenue > 0) %>%
select(order_id, region, revenue, channel, order_date) %>%
arrange(desc(revenue)) %>%
group_by(region, channel) %>%
summarise(
orders = n(),
revenue = sum(revenue),
avg_order = mean(revenue),
.groups = "drop"
)dplyr verbs and SQL equivalents
| dplyr verb | Purpose | SQL analogy | Quick note |
|---|---|---|---|
select() | Spalten behalten oder umbenennen | SELECT col1, col2 | Verwende everything(), um schnell neu zu ordnen. |
filter() | Zeilen-Subset | WHERE condition | In Kombination mit %in% für mehrere Werte nutzen. |
mutate() | Spalten hinzufügen/transformieren | SELECT col1, col2*2 AS col2x | Bevorzuge if_else() für typstabile Logik. |
summarise() + group_by() | gruppierte Kennzahlen | GROUP BY ... | Füge .groups = "drop" hinzu, um zu entgruppieren. |
arrange() | Zeilen sortieren | ORDER BY | Verwende desc() für absteigende Sortierung. |
left_join() | mit Lookup-Daten anreichern | LEFT JOIN | Join-Keys im gleichen Typ halten (character vs factor). |
bind_rows() / bind_cols() | Tabellen stapeln oder verbreitern | UNION ALL / Spaltenkonkatenation | Beim Stapeln auf übereinstimmende Schemata achten. |
Joins vs. binds at a glance
# Join: add columns from a lookup table
sales_with_regions <- sales %>%
left_join(region_lookup, by = "region_id")
# Bind: stack identical schemas
all_sales <- bind_rows(sales_2023, sales_2024)Avoid factor and encoding pitfalls
- Konvertiere Identifikatoren vor Joins zu
character, um nicht passende Faktorstufen zu vermeiden. - Verwende
mutate(across(where(is.factor), as.character)), wenn eine CSV mit impliziten Faktoren eingelesen wurde. - Standardisiere Text mit
stringr::str_trimundtolowervor dem Gruppieren, um doppelte Kategorien zu vermeiden.
Quick starter template
prep_data <- function(df) {
df %>%
mutate(across(where(is.factor), as.character)) %>%
filter(!is.na(key_id)) %>%
distinct() %>%
select(key_id, everything())
}Checklist before saving
- Spalten sind explizit ausgewählt und geordnet.
- Wichtige Joins verwenden passende Typen und bei Bedarf klare Suffixe (
suffix = c(".src", ".lkp")). - Aggregationen entfernen Gruppierungen, um Überraschungen in späteren Schritten zu vermeiden.
- Outputs enthalten nur saubere, menschenlesbare Spalten, die für Plots oder Modelle bereit sind.
Related guides
- Saubere Tabellen von Grund auf erstellen: Creating Dataframe in R
- Daten für Aggregationen gruppieren: Grouping in R with group_by()
- Vorbereitung fürs Plotten: R ggplot2 Quickstart