【问题标题】:加入dplyr时如何为x和y指定列名?
【发布时间】:2014-03-20 06:44:09
【问题描述】:

我有两个要使用 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

在基础 R 中,我会以这种方式执行合并:

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 语料库是一种不好的性别识别方法。我正在努力实现更好的实现,但我想先让它发挥作用。)

【问题讨论】:

标签: r join left-join dplyr


【解决方案1】:

这与其说是真正的解决方案,不如说是一种解决方法。您可以使用另一个列名创建一个新对象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 避免它并让你这样做的方式。
  • 在 0.1.2 中你至少可以做到 select(test_data, first_name = name) 并且只会做一个浅拷贝。
  • 使用data.table::setnames?
  • 解决方案 select(test_data, first_name = name) 自 2014 年 6 月起不起作用
【解决方案2】:

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

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

【讨论】:

  • edit 这也适用于一般情况: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"))
  • 函数的任何参数都是如此。但我通常发现在这种情况下使用命名参数而不是位置匹配更好。
猜你喜欢
  • 2016-06-14
  • 1970-01-01
  • 2014-02-18
  • 2018-01-08
  • 2011-07-15
  • 2021-09-14
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
相关资源
最近更新 更多