Menu

Data Frames in R zusammenführen und joinen (merge, left_join)

Data Frames über einen gemeinsamen Schlüssel kombinieren: merge() für Inner-, Left-, Right- und Full-Joins, unterschiedliche Schlüsselnamen mit by.x/by.y, die Join-Familie von dplyr und rbind() zum Stapeln von Zeilen.

Diese Seite enthält ausführbare Editoren. Bearbeiten, ausführen und Ausgabe sofort sehen.

Zwei Tabellen, ein Schlüssel

Echte Daten leben selten in einer Tabelle. Kunden sitzen in einem Data Frame, ihre Bestellungen in einem anderen, und die Frage - "Wie viel hat jede Kundin ausgegeben?" - braucht beide. Was sie verbindet, ist ein Schlüssel: eine Spalte, die in jeder Tabelle vorhanden ist und dieselbe Entität identifiziert. Tabellen über einen Schlüssel zu kombinieren ist ein Join (SQL-Wort) oder ein Merge (Base-R-Wort); dieselbe Operation.

Hier ist das Tabellenpaar, das der Rest dieser Seite verwendet. Beachte, dass Kunde 5 eine Bestellung aufgegeben hat, aber nicht in der Kundentabelle steht, und dass die Kunden 2 und 4 nie bestellt haben:

Die Unstimmigkeiten sind Absicht - was ein Join mit unpassenden Zeilen macht, ist genau das, was die Join-Typen unterscheidet.

merge(): standardmäßig ein Inner-Join

merge(x, y, by = "key") gleicht Zeilen mit gleichen Schlüsseln ab und klebt ihre Spalten zusammen. Standardmäßig behält es nur die Schlüssel, die in beiden Tabellen vorkommen - einen Inner-Join:

Drei Zeilen kommen zurück. Ana erscheint zweimal - sie hat zwei Bestellungen, und ein Join erzeugt eine Ausgabezeile pro passendem Paar. Ben und Dana sind weg (keine Bestellungen), ebenso die rätselhafte Bestellung von Kunde 5 (kein Kunde). Ein Inner-Join verwirft nicht passende Zeilen aus beiden Tabellen still - genau richtig, wenn dich nur vollständige Paare interessieren, und ein stiller Datenverlust-Bug, wenn nicht.

Left-, Right- und Full-Joins: all.x, all.y, all

Um nicht passende Zeilen zu behalten, sag, welche Tabelle heilig ist. all.x = TRUE behält jede Zeile der ersten Tabelle - der Left-Join, der in der Praxis meistgenutzte Join:

Nun überleben Ben und Dana, mit NA in amount - "diese Kundin existiert; keine Bestellung passte". Diese NAs sind informativ, kein Müll: is.na(result$amount) ist genau die Liste der Kunden, die nie bestellt haben (die Doku zu fehlenden Werten behandelt den Umgang damit). Die übrigen Varianten sind dieselbe Idee, anders ausgerichtet: all.y = TRUE behält jede Zeile der zweiten Tabelle (Right-Join - die Bestellung des unbekannten Kunden 5 überlebte mit NA in name), und all = TRUE behält alles von beiden Seiten (Full-Join).

Wähle, indem du fragst: Wessen Zeilen darf ich nicht verlieren? Eine Stammtabelle mit Nachschlagedaten anreichern - Left-Join, Stammtabelle zuerst. Beide Richtungen prüfen - Full-Join.

Unterschiedliche Schlüsselnamen: by.x und by.y

Tabellen sind sich bei der Benennung selten einig - id in der einen, customer_id in der anderen. Benenne nicht um; nenne merge() beide Namen:

Die Ausgabe behält für den Schlüssel den Namen der ersten Tabelle. Verwandt: Teilen sich die beiden Tabellen Nicht-Schlüssel-Spaltennamen (beide haben etwa ein date), hängt merge die Suffixe date.x und date.y an - benenne sie zügig um, sie lesen sich furchtbar.

Die dplyr-Joins

dplyr gibt jedem Join-Typ ein eigenes Verb, sodass die Absicht im Funktionsnamen statt in Flag-Argumenten steckt (statisch; die Sandbox führt nur Base R aus):

library(dplyr)

left_join(customers, orders, by = "id")
inner_join(customers, orders, by = "id")
full_join(customers, orders, by = "id")
left_join(customers, orders, by = c("id" = "customer_id"))  # different names

Neben der Lesbarkeit erhält left_join() die Zeilenreihenfolge der ersten Tabelle (merge() sortiert nach Schlüssel um) und warnt deutlich bei Many-to-many-Treffern - siehe die dplyr-Einführung für die Verbfamilie.

Das unterschätzte Mitglied ist anti_join(): Es gibt die Zeilen der ersten Tabelle zurück, die keinen Treffer in der zweiten haben - keine Spalten ergänzt, nur die Übriggebliebenen:

anti_join(customers, orders, by = "id")   # customers who never ordered

Diese Frage - "Welche Zeilen fanden keinen Treffer?" - taucht in der Datenbereinigung ständig auf (nicht zuordenbare IDs, verwaiste Datensätze, gescheiterte Nachschlagevorgänge), und anti_join() beantwortet sie in einem Aufruf, wo Base R customers[!(customers$id %in% orders$id), ] braucht.

Zeilen stapeln: rbind()

Joinen kombiniert Spalten zweier Tabellen. Hast du stattdessen zwei Chargen derselben Art von Zeilen - Januarbestellungen und Februarbestellungen -, stapelst du sie mit rbind():

Die Anforderung ist streng: Beide Data Frames müssen dieselben Spaltennamen haben (beliebige Reihenfolge - rbind gleicht über Namen ab). Eine fehlende oder zusätzliche Spalte ist ein Fehler, keine NA-Füllung. Sind die Spalten der Chargen auseinandergedriftet, ist dplyrs bind_rows() nachsichtiger - es richtet über Namen aus und füllt Lücken mit NA.

Die Doppelschlüssel-Explosion

Der klassische Join-Unfall: Schlüssel, die du für eindeutig hieltest, sind es nicht - und zwar in beiden Tabellen. Jeder Treffer paart sich mit jedem Treffer und vervielfacht die Zeilen:

Zwei Zeilen mit zwei Zeilen gejoint ergeben vier - jedes x gepaart mit jedem y. Bei echten Daten wird so aus einer 10.000-Zeilen-Tabelle eine mit 3 Millionen Zeilen und einem verdoppelten Umsatztotal. merge() tut das still. Die Verteidigung ist eine Gewohnheit: Prüfe vor dem Joinen den Schlüssel, den du für eindeutig hältst - anyDuplicated(customers$id) sollte 0 sein -, und kontrolliere nach dem Joinen nrow() gegen das, was du erwartet hast.

Was du mitnimmst

  • merge(x, y, by = "key") ist ein Inner-Join - nicht passende Zeilen verschwinden still.
  • all.x = TRUE (left), all.y = TRUE (right), all = TRUE (full) behalten nicht passende Zeilen und füllen mit NA.
  • Unterschiedliche Schlüsselnamen: by.x / by.y in Base, by = c("a" = "b") in dplyr.
  • dplyr benennt jeden Join; anti_join() - die Zeilen, die nicht passten - ist das unterschätzte.
  • rbind() stapelt gleich geformte Tabellen; die Spalten müssen über Namen übereinstimmen.
  • Doppelte Schlüssel vervielfachen Zeilen still - prüfe vorher anyDuplicated(), hinterher nrow().

Als Nächstes: das Umformen zwischen breiten und langen Formaten mit pivot_longer() und pivot_wider().

Häufig gestellte Fragen

Wie führe ich zwei Data Frames in R zusammen?

Nutze merge(x, y, by = "key") mit der gemeinsamen Schlüsselspalte. Standardmäßig führt es einen Inner-Join aus - nur Zeilen, deren Schlüssel in beiden Data Frames vorkommt, überleben. Ergänze all.x = TRUE für einen Left-Join, all.y = TRUE für einen Right-Join oder all = TRUE für einen Full-Join.

Wie mache ich einen Left-Join in R?

Base R: merge(x, y, by = "key", all.x = TRUE) behält jede Zeile von x und füllt die y-Spalten mit NA, wo es keinen Treffer gibt. dplyr: left_join(x, y, by = "key") - gleiches Ergebnis, und es erhält zusätzlich die ursprüngliche Zeilenreihenfolge von x, was merge() nicht tut.

Wie führe ich Data Frames zusammen, wenn die Schlüsselspalten unterschiedlich heißen?

Nenne merge() beide Namen: merge(x, y, by.x = "id", by.y = "customer_id"). In dplyr lautet das Äquivalent left_join(x, y, by = c("id" = "customer_id")) oder mit dem modernen Helfer by = join_by(id == customer_id).

Was ist der Unterschied zwischen merge und rbind in R?

Sie kombinieren in verschiedenen Dimensionen. merge() gleicht Zeilen zweier Tabellen über einen Schlüssel ab und vereint deren Spalten - ein Join. rbind() stapelt die Zeilen einer Tabelle unter die einer anderen - beide müssen dieselben Spaltennamen haben. Monatsdateien mit identischen Spalten wollen rbind(); Kunden-plus-Bestellungen will merge().

Illustration der Programmiersprachen bei Coddy

Lerne mit Coddy zu programmieren

Los geht's