使用merge和dplyr的left_join

时间:2015-05-25 12:35:38

标签: r merge left-join

我注意到基本merge中的R函数以及left_join的{​​{1}}函数出现意外行为。 以下是数据的最小示例:

dplyr

我预计df1 <- read.table(text="serialno var1 pos_var1 1 C001 NA NA 2 C002 NA NA 3 C003 0.1790000 1 4 C004 NA NA 5 C007 0.0645000 1 6 C010 0.3895000 1 11 C016 0.2805000 1 12 C017 0.7805001 1", header=T, stringsAsFactors=F) df1 serialno var1 pos_var1 1 C001 NA NA 2 C002 NA NA 3 C003 0.1790000 1 4 C004 NA NA 5 C007 0.0645000 1 6 C010 0.3895000 1 11 C016 0.2805000 1 12 C017 0.7805001 1 df2 <- read.table(text="serialno var1 var2 1 C003 0.1790 1.1305 2 C007 0.0645 0.2985 3 C010 0.3895 0.1705 4 C016 0.1740 0.3980 5 C017 0.4840 0.3375", header=T, stringsAsFactors=F) df2 serialno var1 var2 1 C003 0.1790 1.1305 2 C007 0.0645 0.2985 3 C010 0.3895 0.1705 4 C016 0.1740 0.3980 5 C017 0.4840 0.3375 left_join(df1,df2) Joining by: c("serialno", "var1") serialno var1 pos_var1 var2 1 C001 NA NA NA 2 C002 NA NA NA 3 C003 0.1790000 1 1.1305 4 C004 NA NA NA 5 C007 0.0645000 1 0.2985 6 C010 0.3895000 1 0.1705 7 C016 0.2805000 1 NA 8 C017 0.7805001 1 NA 的最后两个值为var20.3980而不是0.3375。 我使用NAs获得了类似的结果:

merge

但是当我在两个数据框中省略变量merge(df1,df2, all.x=T) serialno var1 pos_var1 var2 1 C001 NA NA NA 2 C002 NA NA NA 3 C003 0.1790000 1 1.1305 4 C004 NA NA NA 5 C007 0.0645000 1 0.2985 6 C010 0.3895000 NA 0.1705 7 C016 0.2805000 1 NA 8 C017 0.7805001 1 NA 时(注意两个数据框中的var1变量除小数位外是相同的)问题是固定的:

var1

所以看起来这个问题是由冲突的left_join(df1[,-2],df2[,-2]) Joining by: "serialno" serialno pos_var1 var2 1 C001 NA NA 2 C002 NA NA 3 C003 1 1.1305 4 C004 NA NA 5 C007 1 0.2985 6 C010 NA 0.1705 7 C016 1 0.3980 8 C017 1 0.3375 引起的,但我期望在联接中首先指定的数据框中的var1覆盖第二个数据框中的var1而没有任何副作用

我很感激有关如何克服这个问题的任何建议或评论是否这是一个值得考虑修复的问题? 我一直在寻找解决类似问题的相关帖子,但他们没有解决我的具体问题。特别是,这些帖子的问题是由于类型差异,例如如果第一个数据帧中的一个变量是一个字符,另一个数据帧中的相应变量是一个因子,或者一个是整数而另一个是数字,例如 Incorrect behavior with dplyr's left_join?

1 个答案:

答案 0 :(得分:1)

跟进上述有用的评论

如果您没有提及要用left_join()merge()数据框的列名,那么将考虑具有公共列名的所有列。

您在var2列的最后两个位置获得NA,因为这两个函数都使用serialnovar1合并数据框(df1和df2之间通用) ),df1和df2中列var1的所有值都不匹配。

因此,如果您愿意合并两个数据框,最好提一下您需要合并或加入的列名

在你的情况下

# using merge()
merge(df1, df2, by = c('serialno'), all.x=T)

#> merge(df1,df2, by = c('serialno'), all.x=T)
#serialno    var1.x pos_var1 var1.y   var2
#1     C001        NA       NA     NA     NA
#2     C002        NA       NA     NA     NA
#3     C003 0.1790000        1 0.1790 1.1305
#4     C004        NA       NA     NA     NA
#5     C007 0.0645000        1 0.0645 0.2985
#6     C010 0.3895000        1 0.3895 0.1705
#7     C016 0.2805000        1 0.1740 0.3980
#8     C017 0.7805001        1 0.4840 0.3375

# using left_join()
left_join(df1, df2, by = c("serialno"))

#> left_join(df1, df2, by = c("serialno"))
#serialno    var1.x pos_var1 var1.y   var2
#1     C001        NA       NA     NA     NA
#2     C002        NA       NA     NA     NA
#3     C003 0.1790000        1 0.1790 1.1305
#4     C004        NA       NA     NA     NA
#5     C007 0.0645000        1 0.0645 0.2985
#6     C010 0.3895000        1 0.3895 0.1705
#7     C016 0.2805000        1 0.1740 0.3980
#8     C017 0.7805001        1 0.4840 0.3375