У меня есть два фрейма данных, к которым я хочу присоединиться с помощью 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?
(Неважно, что корпус Кантровица - плохой способ определить пол. Я работаю над лучшей реализацией, но сначала хочу, чтобы это работало.)
Ответы:
Эта функция была добавлена в dplyr v0.3. Теперь вы можете передать именованный вектор символов
by
аргументу вleft_join
(и другим функциям соединения), чтобы указать, какие столбцы следует присоединять в каждом фрейме данных. В примере, приведенном в исходном вопросе, код будет следующим:left_join(test_data, kantrowitz, by = c("first_name" = "name"))
источник
left_join(data_a, data_b, by = c("a.first" = "b.first", "a.second" = "b.second", "a.third" = "b.third"))
:?by =
Не является обязательным. Вы можете сделатьleft_join(test_data, kantrowitz, c("first_name" = "name"))
Это скорее обходной путь, чем реальное решение. Вы можете создать новый объект
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>
источник
select(test_data, first_name = name)
и это сделает только поверхностную копию.data.table::setnames
?