2014-02-19 3 views
54

У меня есть два кадра данных, с которыми я хочу присоединиться, используя dplyr. Один - это кадр данных, содержащий первые имена.Как указать имена столбцов для x и y при присоединении в 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?

(Не важно, что корпус Kantrowitz плохой способ определить пол. Я работаю на более эффективной реализации, но я хочу, чтобы получить эту работу первым.)

+2

Вы не можете в данный момент, но это в списке, чтобы сделать: https://github.com/hadley/dplyr/issues/177 – hadley

ответ

81

Эта функция была добавлена ​​в dplyr v0.3. Теперь вы можете передать именованный символьный вектор в аргумент by в left_join (и другие функции соединения), чтобы указать, какие столбцы должны объединяться в каждом кадре данных. В примере приведены в первоначальный вопрос, код будет:

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

** edit ** Это также работает в общем случае: 'left_join (data_a, data_b, by = c (" a.first "= «b.first», «a.second» = «b.second», «a.third» = «b.third»)) '? – davidski

+0

'by =' не является обязательным. Вы можете сделать 'left_join (test_data, kantrowitz, c (" first_name "=" name "))' –

+2

Это относится к любому аргументу функции. Но я обычно считаю, что лучше быть явным, используя именованные аргументы, а не сопоставление позиций в этом случае. –

4

Это больше обходной путь, чем реальный решение. Вы можете создать новый объект 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> 
+0

Переименование вызывает копию, я думаю, что может быть способ dplyr избегает этого и заставляет вас сделать это вместо этого. – joran

+2

В 0.1.2 вы, по крайней мере, сможете выполнить 'select (test_data, first_name = name)', и это сделает только мелкую копию. – hadley

+1

Использовать 'data.table :: setnames'? – Hugh

Смежные вопросы