dplyr inner_join 与字符列上的 NA

Posted

技术标签:

【中文标题】dplyr inner_join 与字符列上的 NA【英文标题】:dplyr inner_join with NAs on character columns 【发布时间】:2015-08-11 19:28:29 【问题描述】:

我有两个相等的数据框

a <- c(1,2,3)
b <- c(3,2,1)
c <- c('a','b',NA)

df1 <- data.frame(a=a, b=b, c=c, stringsAsFactors=FALSE)
df2 <- data.frame(a=a, b=b, c=c, stringsAsFactors=FALSE)

我想用dplyr::inner_join

"返回 x 中 y 中有匹配值的所有行,以及 x 和 y 中的所有列" dplyr documentation

(它们都是平等的)但它似乎不适用于c 列中的NA(类型chr)。这是不加入NAs 的标准行为吗?

例如

library(dplyr)
> inner_join(df1, df2)
Joining by: c("a", "b", "c")
  a b c
1 1 3 a
2 2 2 b

不加入NA。但是,我希望它返回与 merge 相同的值

> merge(df1, df2)
  a b    c
1 1 3    a
2 2 2    b
3 3 1 <NA>

我是否误解了inner_join 在这种情况下的工作方式,并且它的行为与描述的一样吗?

更多细节

inner_join 匹配数字列上的NA

a <- c(1,2,3)
b <- c(3,2,NA)
c <- c('a','b','c')

df1 <- data.frame(a=a, b=b, c=c, stringsAsFactors=FALSE)
df2 <- data.frame(a=a, b=b, c=c, stringsAsFactors=FALSE)

> inner_join(df1, df2)
Joining by: c("a", "b", "c")
  a  b c
1 1  3 a
2 2  2 b
3 3 NA c

编辑

正如@thelatemail 指出的那样,当NA 在因子列中时,inner_join 也可以用作merge

df1 <- data.frame(a=a, b=b, c=c, stringsAsFactors=T)
df2 <- data.frame(a=a, b=b, c=c, stringsAsFactors=T)
inner_join(df1, df2)
Joining by: c("a", "b", "c")
  a b    c
1 1 3    a
2 2 2    b
3 3 3 <NA>

编辑 2

感谢@shadow 指出这是一个已知问题here 和here

【问题讨论】:

很好的问题和很好的例子。有趣的是,inner_join 在使用存储为factors 的字符数据时也可以按预期工作,例如:更改您的第一个示例df1$c &lt;- factor(df1$c); df2$c &lt;- factor(df2$c); inner_join(df1,df2) 这是一个已知问题。见here 或here 谢谢@shadow,我会留意修复的。 你试过最新的开发版 dplyr 吗? left_join 有一个类似的问题已修复,所以我假设这个问题也可能已修复。 【参考方案1】:

此问题出现在版本 0.4.1 中。这已在 0.4.2 版中得到修复:

sessionInfo()
...
other attached packages:
[1] dplyr_0.4.2
...

> inner_join(df1, df2)
Joining by: c("a", "b", "c")
  a b    c
1 1 3    a
2 2 2    b
3 3 1 <NA>

检查合并:

> merge(df1, df2)
  a b    c
1 1 3    a
2 2 2    b
3 3 1 <NA>

> all.equal(inner_join(df1, df2), merge(df1, df2))
Joining by: c("a", "b", "c")
[1] TRUE

【讨论】:

以上是关于dplyr inner_join 与字符列上的 NA的主要内容,如果未能解决你的问题,请参考以下文章

dplyr:inner_join 与部分字符串匹配

如何在 R 中 dplyr::inner_join 多个 tbls 或 data.frames

为啥 data.table 的 inner_join 行为不同?

在许多列上使用 dplyr + gsub

如何在不使用for循环的情况下合并需要提前3个月的列上的两个数据框

如何在行而不是列上应用dplyr的select(,starts_with())? [重复]