Skip to content

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 verbPurposeSQL analogyQuick note
select()Spalten behalten oder umbenennenSELECT col1, col2Verwende everything(), um schnell neu zu ordnen.
filter()Zeilen-SubsetWHERE conditionIn Kombination mit %in% für mehrere Werte nutzen.
mutate()Spalten hinzufügen/transformierenSELECT col1, col2*2 AS col2xBevorzuge if_else() für typstabile Logik.
summarise() + group_by()gruppierte KennzahlenGROUP BY ...Füge .groups = "drop" hinzu, um zu entgruppieren.
arrange()Zeilen sortierenORDER BYVerwende desc() für absteigende Sortierung.
left_join()mit Lookup-Daten anreichernLEFT JOINJoin-Keys im gleichen Typ halten (character vs factor).
bind_rows() / bind_cols()Tabellen stapeln oder verbreiternUNION ALL / SpaltenkonkatenationBeim 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_trim und tolower vor 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