dplyr的left_join行为不正确?

时间:2014-09-16 01:45:03

标签: r merge left-join dplyr

当然这不是故意的吗?这是dplyr功能的其他部分发生的事情,我应该关注吗?我喜欢性能和仇恨data.table语法。是否有dplyrdata.table的替代方案,目前使用安全且性能仍然很高?

A <- structure(list(ORDER = c(30305720L, 30334659L, 30379936L, 
                     30406397L, 30407697L, 30431950L), 
                    COST = c("0", "", "11430.52", "20196.279999999999", "0", "10445.99")), 
               .Names = c("ORDER", "COST"), 
               row.names = c(NA, 6L), 
               class = "data.frame")

B <- structure(list(ORDER = c(30334659, 30379936, 30406397, 30407697, 30431950), 
                    AREA = c(0, 2339, 2162, 23040, 475466)), 
               .Names = c("ORDER", "AREA"), 
               row.names = c(4L, 8L, 11L, 12L, 15L), 
               class = c("tbl_df", "tbl", "data.frame"))

垃圾结果:

left_join(A, B)
  ORDER    COST                 AREA
1 30305720                  0   NA
2 30334659                      NA
3 30379936           11430.52   NA
4 30406397 20196.279999999999   NA
5 30407697                  0   NA
6 30431950           10445.99   NA

有效结果:

merge(A, B, all.x=T, all.y=F)
     ORDER               COST   AREA
1 30305720                  0     NA
2 30334659                         0
3 30379936           11430.52   2339
4 30406397 20196.279999999999   2162
5 30407697                  0  23040
6 30431950           10445.99 475466

2 个答案:

答案 0 :(得分:14)

我前几天贴了类似的东西。我认为你需要做的是将ORDER作为数字(或者可能反过来)。 A有ORDER有整数。但是B将ORDER作为数字。目前,dplyr要求您在同一个类中包含分组变量。我收到了SO用户的评论,说这是哈德利和他的团队现在正在努力的事情。这个问题将在未来修复。

A$ORDER <- as.numeric(A$ORDER)
left_join(A,B, by = "ORDER")

     ORDER               COST   AREA
1 30305720                  0     NA
2 30334659                         0
3 30379936           11430.52   2339
4 30406397 20196.279999999999   2162
5 30407697                  0  23040
6 30431950           10445.99 475466

<强>更新 在与thelatemail交换评论后,我决定在这里添加更多观察。

案例1:将ORDER视为数字

A$ORDER <- as.numeric(A$ORDER)

> left_join(A,B, by = "ORDER")
     ORDER               COST   AREA
1 30305720                  0     NA
2 30334659                         0
3 30379936           11430.52   2339
4 30406397 20196.279999999999   2162
5 30407697                  0  23040
6 30431950           10445.99 475466

> left_join(B,A, by = "ORDER")
Source: local data frame [5 x 3]

     ORDER   AREA               COST
1 30334659      0                   
2 30379936   2339           11430.52
3 30406397   2162 20196.279999999999
4 30407697  23040                  0
5 30431950 475466           10445.99

如果在A和B中都有ORDER作为整数,那也可以。

案例2:将ORDER视为整数和数字

> left_join(A,B, by = "ORDER")
     ORDER               COST AREA
1 30305720                  0   NA
2 30334659                      NA
3 30379936           11430.52   NA
4 30406397 20196.279999999999   NA
5 30407697                  0   NA
6 30431950           10445.99   NA

> left_join(B,A, by = "ORDER")
Source: local data frame [5 x 3]

     ORDER   AREA               COST
1 30334659      0                   
2 30379936   2339           11430.52
3 30406397   2162 20196.279999999999
4 30407697  23040                  0
5 30431950 475466           10445.99

根据thelatemail的建议,整数/数字组合不起作用。但数字/整数组合有效。

鉴于这些观察结果,目前在逐个变量中保持一致是安全的。或者,merge()是可行的方法。它可以处理整数和数字。

> merge(A,B, by = "ORDER", all = TRUE)
     ORDER               COST   AREA
1 30305720                  0     NA
2 30334659                         0
3 30379936           11430.52   2339
4 30406397 20196.279999999999   2162
5 30407697                  0  23040
6 30431950           10445.99 475466 

> merge(B,A, by = "ORDER", all = TRUE)
     ORDER   AREA               COST
1 30305720     NA                  0
2 30334659      0                   
3 30379936   2339           11430.52
4 30406397   2162 20196.279999999999
5 30407697  23040                  0
6 30431950 475466           10445.99

UPDATE2(截至2014年11月8日)

我使用的是dplyr(dplyr_0.3.0.9000)的开发版,您可以从Github下载。 上面的问题现在已经解决了。

left_join(A,B, by = "ORDER")
#     ORDER               COST   AREA
#1 30305720                  0     NA
#2 30334659                         0
#3 30379936           11430.52   2339
#4 30406397 20196.279999999999   2162
#5 30407697                  0  23040
#6 30431950           10445.99 475466

答案 1 :(得分:0)

来自dplyr documentation

  

<强> left_join()

     

返回x的所有行以及xy的所有列。 x中的y中没有匹配的行将在新列中包含NA个值。如果xy之间存在多个匹配项,则会返回所有匹配项的组合。

     

<强> semi_join()

     

返回xy中匹配值的所有行,只保留x中的列。

     

半连接与内连接不同,因为内连接将为x的每个匹配行返回y的一行,其中半连接永远不会复制x的行

semi_join()对您来说是一个有价值的选择吗?