web-dev-qa-db-fra.com

Comment spécifier les noms des colonnes pour x et y lors de la jointure dans dplyr?

Je souhaite joindre deux trames de données à l'aide de dplyr. L'un est un bloc de données contenant des prénoms.

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

L'autre cadre de données contient une version épurée du corpus de noms de Kantrowitz, identifiant le sexe. Voici un exemple minimal:

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"))

Je veux essentiellement rechercher le genre du nom de la test_data table en utilisant la table kantrowitz. Parce que je vais résumer cela dans une fonction encode_gender _, Je ne saurai pas le nom de la colonne du jeu de données qui va être utilisé et je ne peux donc pas garantir que ce sera name, comme dans kantrowitz$name.

En base R, j'effectuerais la fusion de la manière suivante:

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

Cela renvoie la sortie correcte:

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

Mais je veux faire cela dans dplyr car j'utilise ce paquet pour toutes mes autres manipulations de données. L'option dplyr by des différents *_join fonctions ne me permet de spécifier qu'un seul nom de colonne, mais je dois en spécifier deux. Je cherche quelque chose comme ça:

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"))

Quel est le moyen de réaliser ce type de jointure avec dplyr?

(Peu importe que le corpus de Kantrowitz soit un mauvais moyen d'identifier le genre. Je travaille sur une meilleure implémentation, mais je veux que cela fonctionne en premier.)

71
Lincoln Mullen

Cette fonctionnalité a été ajoutée dans dplyr v0.3. Vous pouvez maintenant passer un vecteur de caractère nommé à l'argument by dans left_join (et d'autres fonctions de jointure) pour spécifier les colonnes à joindre dans chaque trame de données. Avec l'exemple donné dans la question d'origine, le code serait:

left_join(test_data, kantrowitz, by = c("first_name" = "name"))
114
Lincoln Mullen

C'est plus une solution de contournement qu'une vraie solution. Vous pouvez créer un nouvel objet test_data avec un autre nom de colonne:

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>
5
Sven Hohenstein