Як вказати імена стовпців для x та y при об'єднанні в dplyr?


89

У мене є два кадри даних, до яких я хочу приєднатися за допомогою dplyr. Один - це кадр даних, що містить імена.

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

Інший фрейм даних містить очищену версію корпусу імен Кантровіца, що визначає стать. Ось мінімальний приклад:

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

По суті, я хочу шукати стать назви з test_dataтаблиці за допомогою kantrowitzтаблиці. Оскільки я збираюся абстрагувати це до функції encode_gender, я не буду знати назви стовпця в наборі даних, який буде використовуватися, і тому я не можу гарантувати, що це буде name, як у kantrowitz$name.

У базовій RI буде виконувати злиття таким чином:

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

Це повертає правильний результат:

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

Але я хочу зробити це в dplyr, оскільки я використовую цей пакет для всіх інших маніпуляцій з даними. Параметр dplyr byдля різних *_joinфункцій дозволяє мені вказати лише одне ім'я стовпця, але мені потрібно вказати два. Я шукаю щось подібне:

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

Який спосіб виконати такий вид об’єднання за допомогою dplyr?

(Неважливо, що корпус Кантровіца - це поганий спосіб визначити стать. Я працюю над кращим впровадженням, але я хочу, щоб це працювало першим.)


3
Наразі ви не можете, але це в списку справ
hadley

Відповіді:


148

Ця функція була додана в dplyr v0.3. Тепер ви можете передати іменований вектор символу byаргументу в left_join(та інших об’єднуючих функціях), щоб вказати, до яких стовпців слід приєднуватися в кожному кадрі даних. У прикладі, наведеному в оригінальному питанні, код буде таким:

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

13
редагувати Це працює і в загальному випадку left_join(data_a, data_b, by = c("a.first" = "b.first", "a.second" = "b.second", "a.third" = "b.third")):?
davidski

by =Чи не є обов'язковим. Ти можешleft_join(test_data, kantrowitz, c("first_name" = "name"))
Pranay Aryal

11
Це справедливо для будь-якого аргументу функції. Але я, як правило, вважаю, що краще бути явним, використовуючи іменовані аргументи, а не зіставлення позицій у цьому випадку.
Лінкольн Маллен,

5

Це швидше обхідний шлях, ніж реальне рішення. Ви можете створити новий об'єкт test_dataз іншим ім'ям стовпця:

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>

Перейменування викликає копію, я думаю, що, можливо, dplyr уникає її і змушує вас робити це замість цього.
Джоран

2
У 0.1.2 ви принаймні зможете це зробити, select(test_data, first_name = name)і це зробить лише неглибоку копію.
Hadley

1
Використовувати data.table::setnames?
Х'ю

2
вибір рішення (test_data, first_name = name) не працює станом на червень 2014 р.
userJT
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.