Datenrahmen in R zusammenführen: Vollständige und teilweise Übereinstimmung

⚡ Intelligente Zusammenfassung

Das Zusammenführen von Dataframes in R verknüpft zwei Tabellen anhand einer oder mehrerer gemeinsamer Schlüsselspalten. Die Funktion `merge()` unterstützt Inner Joins, Left Joins, Right Joins und Full Joins. Diese Anleitung demonstriert sowohl einen vollständigen als auch einen partiellen Join.

  • 🔑 Wichtige Spalten: merge() verknüpft die Elemente von by oder von by.x und by.y, wenn der Schlüssel in jedem Frame einen anderen Namen trägt.
  • 🔗 Vollständiges Spiel: Der standardmäßige innere Join behält nur die Zeilen bei, deren Schlüssel in beiden Dataframes vorkommt.
  • 🧩 Teilweise Übereinstimmung: Durch die Einstellung all.x = TRUE bleiben alle Zeilen des ersten Frames erhalten, und die Lücken werden mit NA aufgefüllt.
  • 📐 Maßprüfung: Vergleichen Sie dim() vor und nach dem Merge, um Zeilen zu erkennen, die durch den Join verloren gegangen oder dupliziert wurden.
  • ⚙️ Gemeinsame Steuerung: Die Flags all, all.x und all.y wählen das Verhalten inner, links, rechts oder vollständig außen.
  • Moderne Alternative: dplyr benennt jeden Join im Verb selbst und erhält die ursprüngliche Zeilenreihenfolge bei.

Datenrahmen in R zusammenführen

Sehr oft verfügen wir über Daten aus mehreren Quellen. Um eine Analyse durchzuführen, müssen wir Folgendes tun fusionieren zwei Datenrahmen zusammen mit einem oder mehreren gemeinsame Schlüsselvariablen.

Arten von Zusammenführungen (Joins) in R

Bevor wir die Beispiele durchgehen, ist es hilfreich zu wissen, dass `merge()` alle vom SQL-Benutzer erwarteten Join-Typen ausführt. Das Verhalten wird durch die Argumente `all`, `all.x` und `all.y` gesteuert und nicht durch einen anderen Funktionsnamen.

Join-Typ Reihen gehalten merge()-Aufruf dplyr-Äquivalent
Inner Join (Standard) Nur in beiden Rahmen vorhandene Tasten merge(x, y, by = “k”) inner_join(x, y, by = “k”)
Linke äußere Verbindung Alle Zeilen von x, NA, in denen y keine Übereinstimmung hat. merge(x, y, by = “k”, all.x = TRUE) left_join(x, y, by = “k”)
Rechter äußerer Join Alle Zeilen von y, NA, in denen x keine Übereinstimmung hat merge(x, y, by = “k”, all.y = TRUE) right_join(x, y, by = “k”)
Vollständiger äußerer Join Jede Zeile aus beiden Rahmen merge(x, y, by = “k”, all = TRUE) full_join(x, y, by = “k”)
Cross Join Jede Kombination von Zeilen merge(x, y, by = NULL) cross_join(x, y)

Zwei Details sollten vor dem ersten Anruf beachtet werden:

  • Lässt man `by` weg, führt R dazu, dass die beiden Frames anhand aller gemeinsamen Spaltennamen zusammengeführt werden, was man selten möchte.
  • Die Funktion merge() sortiert das Ergebnis nach der Schlüsselspalte; mit sort = FALSE soll die Reihenfolge der Eingabe beibehalten werden.

Gesamtes Spiel

Eine vollständige Übereinstimmung liefert nur die Werte, die ein Gegenstück in der Zieltabelle haben. Zeilen ohne Übereinstimmung werden aus dem neuen Datenrahmen entfernt. Eine teilweise Übereinstimmung hingegen behält diese Zeilen bei und füllt die fehlenden Spalten mit NA auf.

Wir werden ein einfaches sehen innere Verbindung. Das Schlüsselwort „Inner Join“ wählt Datensätze aus, die in beiden Tabellen übereinstimmende Werte haben. Um zwei Datensätze zu verbinden, können wir die Funktion merge() verwenden. Wir werden drei Argumente verwenden:

merge(x, y, by.x = x, by.y = y)

Arguments:
-x: The origin data frame
-y: The data frame to merge
-by.x: The column used for merging in x data frame. Column x to merge on
-by.y: The column used for merging in y data frame. Column y to merge on

Ejemplo:

Erstellen Sie den ersten Datensatz mit Variablen

  • Familien-oder Nachname
  • Staatsangehörigkeit

Erstellen Sie einen zweiten Datensatz mit Variablen

  • Familien-oder Nachname
  • Filme

Die gemeinsame Schlüsselvariable ist der Nachname. Wir können beides zusammenführen. Datenrahmen und überprüfen Sie, ob die Dimensionalität 7×3 beträgt.

Wir fügen stringsAsFactors=FALSE im Datenrahmen hinzu, weil wir nicht wollen R um die Zeichenketten in eine FaktorDie Variable sollte ein Zeichenvektor bleiben. Seit R 4.0.0 ist dies bereits der Standardwert für data.frame(), daher ist das Argument in neuem Code optional und in altem Code unproblematisch.

# Create origin dataframe(

producers <- data.frame(   
    surname =  c("Spielberg","Scorsese","Hitchcock","Tarantino","Polanski"),    
    nationality = c("US","US","UK","US","Poland"),    
    stringsAsFactors=FALSE)

# Create destination dataframe
movies <- data.frame(    
    surname = c("Spielberg",
		"Scorsese",
                "Hitchcock",
              	"Hitchcock",
                "Spielberg",
                "Tarantino",
                "Polanski"),    
    title = c("Super 8",
    		"Taxi Driver",
    		"Psycho",
    		"North by Northwest",
    		"Catch Me If You Can",
    		"Reservoir Dogs","Chinatown"),                
     		stringsAsFactors=FALSE)

# Merge two datasets
m1 <- merge(producers, movies, by.x = "surname")
m1
dim(m1)

Ausgang:

surname		nationality		title
1 Hitchcock		UK		Psycho
2 Hitchcock		UK		North by Northwest
3 Polanski		Poland		Chinatown
4 Scorsese		US		Taxi Driver
5 Spielberg		US		Super 8
6 Spielberg		US		Catch Me If You Can
7 Tarantino		US		Reservoir Dogs

Lassen Sie uns Datenrahmen zusammenführen, wenn die gemeinsamen Schlüsselvariablen unterschiedliche Namen haben.

Im Filmdatenrahmen ändern wir den Nachnamen in den Vornamen. Wir verwenden die Funktion identisch(x1, x2), um zu prüfen, ob beide Datenrahmen identisch sind.

# Change name of ` movies ` dataframe
colnames(movies)[colnames(movies) == 'surname'] <- 'name'
# Merge with different key value
m2 <- merge(producers, movies, by.x = "surname", by.y = "name")
# Print head of the data
head(m2)

Ausgang:

##surname     nationality		title
## 1 Hitchcock          UK		Psycho
## 2 Hitchcock          UK		North by Northwest
## 3 Polanski          Poland		Chinatown
## 4 Scorsese           US		Taxi Driver
## 5 Spielberg          US		Super 8
## 6 Spielberg          US		Catch Me If You Can
# Check if data are identical
identical(m1, m2)

Ausgang:

## [1] TRUE

Dies zeigt, dass der Zusammenführungsvorgang auch dann ausgeführt wird, wenn die Spaltennamen unterschiedlich sind.

Teilweise Übereinstimmung

Der obige Inner Join hat stillschweigend alle Elemente ohne Gegenstück verworfen. Es ist nicht überraschend, dass zwei Dataframes nicht dieselben gemeinsamen Schlüsselvariablen besitzen. volle Übereinstimmung, der Datenrahmen kehrt zurück einzige Zeilen, die sowohl im x- als auch im y-Datenrahmen gefunden werden. Mit teilweises Zusammenführenist es möglich, die Zeilen ohne übereinstimmende Zeilen im anderen Datenrahmen beizubehalten. Diese Zeilen haben NA in den Spalten, die normalerweise mit Werten von y gefüllt sind. Das können wir erreichen, indem wir all.x= TRUE setzen.

Wir können beispielsweise einen neuen Produzenten, Lucas, im Produzenten-Dataframe hinzufügen, ohne die Filmreferenzen im Film-Dataframe zu haben. Wenn wir `all.x = FALSE` setzen, verknüpft R nur die übereinstimmenden Werte aus beiden Dataframes. In unserem Fall wird der Produzent Lucas nicht in das Ergebnis aufgenommen, da er in einem der Dataframes fehlt.

Sehen wir uns die Dimension jeder Ausgabe an, wenn wir all.x= TRUE angeben und wenn nicht.

# Create a new producer
add_producer <-  c('Lucas', 'US')
#  Append it to the ` producer` dataframe
producers <- rbind(producers, add_producer)
# Use a partial merge 
m3 <-merge(producers, movies, by.x = "surname", by.y = "name", all.x = TRUE)
m3

Ausgang:

Die untenstehende Konsolenausgabe zeigt die zusätzliche Lucas-Zeile, wobei NA für den fehlenden Filmtitel steht.

Konsolenausgabe der Teilzusammenführung, die Lucas mit NA in der Titelspalte anzeigt

# Compare the dimension of each data frame
dim(m1)

Ausgang:

## [1] 7 3
dim(m2)

Ausgang:

## [1] 7 3
dim(m3)

Ausgang:

## [1] 8 3

Wie wir sehen können, ist der neue Datenrahmen 8×3 groß, im Vergleich zu 7×3 für m1 und m2. R füllt die Spalte „Titel“ mit NA für Lucas, den Produzenten, der keine entsprechende Zeile im Datenrahmen „Filme“ hat.

merge() vs dplyr Joins in R

Base R löst jeden Join mit einer Funktion und einer Menge von Flags. dplyr Das Paket gibt stattdessen jedem Join ein eigenes Verb, was viele Teams in einer Pipeline als lesbarer empfinden.

Eigenschaften Basisverschmelzung() dplyr tritt bei
Auswahl der Verbindung alle.x / alle.y / alle Flaggen Benannt im Verb: left_join(), full_join()
Zeilenreihenfolge Sortiert nach dem Schlüssel, es sei denn, sort = FALSE Die Reihenfolge der linken Tabelle bleibt erhalten.
Geschwindigkeit bei großen Rahmen Langsamer Generell schneller
Fehlende Schlüsselspalte Fehler treten zu spät auf oder führen Zusammenführungen in den falschen Spalten durch. Fehler sofort
Abhängigkeiten Base R, keine Installation erforderlich Erfordert das dplyr-Paket

Die beiden oben gezeigten Merges lassen sich direkt in dplyr-Verben übersetzen:

library(dplyr)
# Same inner join as merge(producers, movies, by.x = "surname", by.y = "name")
m4 <- inner_join(producers, movies, by = c("surname" = "name"))
# Same partial merge as all.x = TRUE
m5 <- left_join(producers, movies, by = c("surname" = "name"))

Innerhalb eines Pakets, das keine Abhängigkeiten haben sollte, ist `merge()` die sicherere Wahl. Bei interaktiven Analysen, bei denen Lesbarkeit und Geschwindigkeit wichtiger sind, ist `dplyr` die bessere Wahl.

Häufige Merge-Fehler in R und wie man sie behebt

Die meisten Merge-Probleme machen sich eher durch eine unerwartete Zeilenanzahl als durch eine Fehlermeldung bemerkbar. Daher ist es ratsam, sich die Angewohnheit anzueignen, nach jedem Join die Methode `dim()` zu überprüfen.

  • Das Ergebnis enthält mehr Zeilen als jede der Eingabezeilen. Ein Schlüssel, der in beiden Frames vorkommt, erzeugt eine Many-to-Many-Beziehung, und R gibt jede Kombination zurück. Untersuchen Sie die Schlüssel vor dem Zusammenführen mit `table(duplicated(x$k))`.
  • Das Ergebnis ist leer. Die Schlüsselspalten unterscheiden sich üblicherweise im Datentyp, oder eine enthält nachfolgende Leerzeichen. Wenden Sie str() auf beide Frames an und bereinigen Sie den Schlüssel vor dem Zusammenführen mit trimws().
  • Die Spalten werden als title.x und title.y zurückgegeben. Beide Frames enthalten eine nicht-Schlüsselspalte mit demselben Namen. Verwenden Sie `suffixes = c(“_producer”, “_film”)`, um die Herkunft eindeutig zu kennzeichnen.
  • Die Reihen befinden sich nicht mehr in ihrer ursprünglichen Reihenfolge. Die Funktion `merge()` sortiert standardmäßig nach dem Schlüssel. Fügen Sie `sort = FALSE` hinzu oder verwenden Sie eine explizite Art danach.
  • Ein wichtiger Vergleich scheitert an bestimmten Faktoren. Vergleiche Zeichen, nicht Faktorstufen: Umschließen Sie den Schlüssel mit as.character(), bevor Sie Frames zusammenführen, die unter älteren R-Standardeinstellungen erstellt wurden.

Wenn derselbe Merge-Vorgang wiederholt ausgeführt werden muss, sollte er in einen Wrapper eingebettet werden. benutzerdefinierte Funktion Die Argumente können sich also zwischen den Durchläufen nicht verändern.

Häufig gestellte Fragen

R führt eine Zusammenführung anhand aller Spaltennamen durch, die die beiden Frames gemeinsam haben. Bei einer gemeinsamen Spalte ist das praktisch; bei mehreren gemeinsamen Spalten wird das Ergebnis stillschweigend eingeschränkt, und bei keiner gemeinsamen Spalte wird ein Cross Join zurückgegeben. Die explizite Benennung des Schlüssels vermeidet alle drei unerwünschten Ergebnisse.

Nicht in einem einzigen `merge()`-Aufruf. Verketten Sie die Aufrufe oder falten Sie eine Liste mit `Reduce(function(x, y) merge(x, y, by = “k”), list(df1, df2, df3))`. Überprüfen Sie die Zeilenanzahl nach jedem Schritt, da sich doppelte Schlüssel schnell anhäufen.

Beide Frames enthielten eine nicht-Schlüsselspalte mit demselben Namen, daher unterscheidet R sie. Verwenden Sie `suffixes = c(“_producer”, “_film”)`, um den Kopien aussagekräftige Namen zu geben, oder entfernen Sie die redundante Spalte vor dem Zusammenführen.

Nein. `merge()` sortiert das Ergebnis standardmäßig nach der Schlüsselspalte. Verwenden Sie `sort = FALSE`, um die ursprüngliche Reihenfolge beizubehalten, oder verwenden Sie eine andere Methode. dplyr join, wodurch die Ordnung des linken Rahmens erhalten bleibt.

Geben Sie einen Vektor an: merge(x, y, by = c(“surname”, “year”)). Wenn sich die Namen unterscheiden, übergeben Sie übereinstimmende Vektoren an by.x und by.y. Beide Vektoren müssen die Spalten in der gleichen Reihenfolge auflisten.

Verwenden Sie by = “row.names”, oder die Kurzform by = 0. R fügt die Zeilennamen als Spalte namens Row.names wieder hinzu, die Sie normalerweise umbenennen oder löschen möchten, bevor Sie mit der Analyse fortfahren.

Beschreiben Sie die beiden Frames und die Zeilenanzahl. Ein KI-Assistent weist dann auf doppelte Schlüssel als wahrscheinliche Ursache hin und schlägt eine Überprüfung mit `duplicated()` vor. Bestätigen Sie die Diagnose anhand Ihrer eigenen Daten, bevor Sie die Verknüpfung ändern.

Ja. RStudio Desktop 2023.09.0 und höher enthält eine optionale Funktion. GitHub-Copilot Die Integration erstellt einen Merge-Vorgang anhand eines Kommentars. Überprüfen Sie den gewählten Join-Typ, da eine falsche Kennzeichnung die Zeilenanzahl unbemerkt verändert.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: