Wie werden die Spaltennamen für x und y beim Beitritt zu dplyr angegeben?

88

Ich habe zwei Datenrahmen, denen ich mit dplyr beitreten möchte. Einer ist ein Datenrahmen, der Vornamen enthält.

test_data <- data.frame(first_name = c("john", "bill", "madison", "abby", "zzz"),
                        stringsAsFactors = FALSE)

Der andere Datenrahmen enthält eine bereinigte Version des Kantrowitz-Namenskorpus, die das Geschlecht identifiziert. Hier ist ein minimales Beispiel:

kantrowitz <- structure(list(name = c("john", "bill", "madison", "abby", "thomas"), gender = c("M", "either", "M", "either", "M")), .Names = c("name", "gender"), row.names = c(NA, 5L), class = c("tbl_df", "tbl", "data.frame"))

Ich möchte im Wesentlichen das Geschlecht des Namens test_dataanhand der kantrowitzTabelle aus der Tabelle nachschlagen . Da ich dies in eine Funktion abstrahieren encode_genderwerde, kenne ich den Namen der Spalte in dem Datensatz, der verwendet werden soll, nicht und kann daher nicht garantieren, dass dies der Fall ist name, wie in kantrowitz$name.

In der Basis würde RI die Zusammenführung folgendermaßen durchführen:

merge(test_data, kantrowitz, by.x = "first_names", by.y = "name", all.x = TRUE)

Das gibt die richtige Ausgabe zurück:

  first_name gender
1       abby either
2       bill either
3       john      M
4    madison      M
5        zzz   <NA>

Aber ich möchte dies in dplyr tun, weil ich dieses Paket für alle meine anderen Datenmanipulationen verwende. Mit der byOption dplyr für die verschiedenen *_joinFunktionen kann ich nur einen Spaltennamen angeben, aber ich muss zwei angeben. Ich suche so etwas:

library(dplyr)
# either
left_join(test_data, kantrowitz, by.x = "first_name", by.y = "name")
# or
left_join(test_data, kantrowitz, by = c("first_name", "name"))

Wie kann diese Art von Join mit dplyr ausgeführt werden?

(Egal, dass der Kantrowitz-Korpus ein schlechter Weg ist, um das Geschlecht zu identifizieren. Ich arbeite an einer besseren Implementierung, aber ich möchte, dass dies zuerst funktioniert.)

Lincoln Mullen
quelle
3
Sie können derzeit nicht, aber es ist auf der
To-

Antworten:

148

Diese Funktion wurde in dplyr v0.3 hinzugefügt. Sie können jetzt einen benannten Zeichenvektor an das byArgument in left_join(und andere Verknüpfungsfunktionen) übergeben, um anzugeben, welche Spalten in jedem Datenrahmen verknüpft werden sollen. Mit dem Beispiel in der ursprünglichen Frage wäre der Code:

left_join(test_data, kantrowitz, by = c("first_name" = "name"))
Lincoln Mullen
quelle
13
edit Das funktioniert auch im allgemeinen Fall : left_join(data_a, data_b, by = c("a.first" = "b.first", "a.second" = "b.second", "a.third" = "b.third"))?
Davidski
Das by =ist optional. Sie können tunleft_join(test_data, kantrowitz, c("first_name" = "name"))
Pranay Aryal
11
Das gilt für jedes Argument für eine Funktion. Im Allgemeinen finde ich es jedoch besser, explizit zu benennen, indem in diesem Fall benannte Argumente als Positionsabgleich verwendet werden.
Lincoln Mullen
5

Dies ist eher eine Problemumgehung als eine echte Lösung. Sie können ein neues Objekt test_datamit einem anderen Spaltennamen erstellen :

left_join("names<-"(test_data, "name"), kantrowitz, by = "name")

     name gender
1    john      M
2    bill either
3 madison      M
4    abby either
5     zzz   <NA>
Sven Hohenstein
quelle
Das Umbenennen führt meiner Meinung nach zu einer Kopie, die möglicherweise von dplyr vermieden wird und Sie stattdessen dazu bringt, dies zu tun.
Joran
2
In 0.1.2 werden Sie zumindest in der Lage sein, select(test_data, first_name = name)und das wird nur eine flache Kopie machen.
Hadley
1
Verwenden data.table::setnames?
Hugh
2
Die Lösungsauswahl (test_data, first_name = name) funktioniert ab Juni 2014 nicht mehr
userJT