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 mitNA.- Unterschiedliche Schlüsselnamen:
by.x/by.yin 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(), hinterhernrow().
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().