在dplyr中加入时,如何为x和y指定列的名称?

Lin*_*len 74 join r left-join dplyr

我有两个数据帧,我想使用dplyr加入.一个是包含名字的数据框.

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

另一个数据框包含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"))
Run Code Online (Sandbox Code Playgroud)

我基本上想要test_data使用kantrowitz表格从表中查找名称的性别.因为我要将它抽象为一个函数encode_gender,所以我不知道将要使用的数据集中列的名称,因此我不能保证它将会被name用作,例如kantrowitz$name.

在基础RI中将以这种方式执行合并:

merge(test_data, kantrowitz, by.x = "first_names", by.y = "name", all.x = TRUE)
Run Code Online (Sandbox Code Playgroud)

返回正确的输出:

  first_name gender
1       abby either
2       bill either
3       john      M
4    madison      M
5        zzz   <NA>
Run Code Online (Sandbox Code Playgroud)

但我想在dplyr中这样做,因为我正在使用该包进行所有其他数据操作.by各种*_join函数的dplyr 选项只允许我指定一个列名,但我需要指定两个.我正在寻找这样的东西:

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"))
Run Code Online (Sandbox Code Playgroud)

使用dplyr执行此类连接的方法是什么?

(不要紧,Kantrowitz语料库是一种识别性别的坏方法.我正在努力实现更好的实施,但我希望首先使用它.)

Lin*_*len 119

dplyr v0.3中添加了此功能.您现在可以将命名字符向量传递给(和其他连接函数)中的by参数,left_join以指定在每个数据框中要连接的列.使用原始问题中给出的示例,代码将是:

left_join(test_data, kantrowitz, by = c("first_name" = "name"))
Run Code Online (Sandbox Code Playgroud)

  • **编辑**这也适用于一般情况:`left_join(data_a,data_b,by = c("a.first"="b.first","a.second"="b.second"," a.third"="b.第三次"))`` (9认同)
  • 对于函数的任何参数都是如此.但我通常发现在这种情况下使用命名参数而不是位置匹配更明确. (7认同)

Sve*_*ein 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>
Run Code Online (Sandbox Code Playgroud)

  • 在0.1.2中,你至少可以做`select(test_data,first_name = name)`并且只能做一个浅拷贝. (2认同)
  • 自2014年6月起,解决方案select(test_data,first_name = name)无效 (2认同)