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().

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S