dplyr left_join 匹配NA

10
当使用关键字连接data.frame时,如果一个关键字有缺失值(NA),我的直觉是带有NA关键字的行在第二个数据框中应该没有匹配项。但令我惊讶的是,如果两个数据框中都有NA,则dplyr将它们匹配为值。这使得情况变得更加混乱,因为这在dplyr存储库的问题中已经详细讨论请参阅此处,并且似乎已经解决了!如果是这样,那么我没有看到这是正确的解决方案;或者我可能错过了什么。我正在使用dplyr 0.7.4


t1 <- data.frame(a = as.character(c("1", "2", NA, NA, "4", "2")), b = c(1, 2, 3, 3, 4, 5), stringsAsFactors = FALSE)
t2 <- data.frame(a = as.character(c("1", "2", NA)), c = c("b", "n", "i"), stringsAsFactors = FALSE)
library(dplyr)
t1
#>      a b
#> 1    1 1
#> 2    2 2
#> 3 <NA> 3
#> 4 <NA> 3
#> 5    4 4
#> 6    2 5
t2
#>      a c
#> 1    1 b
#> 2    2 n
#> 3 <NA> i
left_join(t1, t2, by = "a")
#>      a b    c
#> 1    1 1    b
#> 2    2 2    n
#> 3 <NA> 3    i
#> 4 <NA> 3    i
#> 5    4 4 <NA>
#> 6    2 5    n

事实上,我本来期望以下内容:
#>      a b    c
#> 1    1 1    b
#> 2    2 2    n
#> 3 <NA> 3 <NA>
#> 4 <NA> 3 <NA>
#> 5    4 4 <NA>
#> 6    2 5    n

你的期望是什么?在你提供的链接中,有一个评论:“是的,NA永远不应该与另一个NA匹配”。 - akrun
好的,我刚刚编辑了问题以展示似乎是“正确”的结果。 - AndrewMacDonald
2个回答

7
解决方案是使用参数na_matches = "never"。这是由Twitter上的Dani RabaiottiHadley Wickham指出的。
该参数在tbl_df类的left_join方法中有记录: ?left_join.tbl_df

0

这种行为与 merge 相同(尽管有一些重新排序)。

merge(t1,t2,all.x=T)
     a b    c
1    1 1    b
2    2 2    n
3    2 5    n
4    4 4 <NA>
5 <NA> 3    i
6 <NA> 3    i

通过设置incomparables=NA,您可以获得预期的输出:

merge(t1,t2,all.x=T,incomparables=NA)
     a b    c
1    1 1    b
2    2 2    n
3    2 5    n
4    4 4 <NA>
5 <NA> 3 <NA>
6 <NA> 3 <NA>

dplyr中,这个选项似乎没有被记录文档,但是查看dplyr:::left_join.tbl_df,你会发现na_matches看起来很有前途。一些尝试揭示你需要给它一个"never"的值。
left_join(t1,t2,by="a",na_matches="never")
     a b    c
1    1 1    b
2    2 2    n
3 <NA> 3 <NA>
4 <NA> 3 <NA>
5    4 4 <NA>
6    2 5    n

谢谢!在我的dplyr文档中,它明确描述了na_matches="never"参数。只是想留下这个评论,以防未来的读者想要阅读更多。他们可以通过?join.tbl_df获得此信息。 - AndrewMacDonald

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接