我有两个要使用 dplyr 加入的数据框。一个是包含名字的数据框。
test_data <- data.frame(first_name = c("john", "bill", "madison", "abby", "zzz"),
stringsAsFactors = FALSE)
另一个数据框包含 Kantrowitz 姓名语料库的清理版本,用于识别性别。这是一个最小的例子:
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"))
我基本上想使用 kantrowitz
表从 test_data
表中查找名称的性别。因为我要把它抽象成一个函数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 中执行此操作,因为我正在使用该包进行所有其他数据操作。各种 *_join
函数的 dplyr by
选项只允许我指定一个列名,但我需要指定两个。我正在寻找这样的东西:
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 语料库是一种识别性别的不好方法。我正在研究更好的实现,但我想先让它工作。)
此功能已在 dplyr v0.3 中添加。您现在可以将命名字符向量传递给 left_join
(和其他连接函数)中的 by
参数,以指定每个数据帧中要连接的列。对于原始问题中给出的示例,代码将是:
left_join(test_data, kantrowitz, by = 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
?
不定期副业成功案例分享
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"))