【问题标题】:Merge two dataframes containing duplicate elements合并两个包含重复元素的数据框
【发布时间】:2014-09-11 22:41:07
【问题描述】:

给定两个名称部分重叠的数据框,foobar

foo <- iris[1:10,-c(4,5)]
#   Sepal.Length Sepal.Width Petal.Length
# 1           5.1         3.5          1.4
# 2           4.9         3.0          1.4
# 3           4.7         3.2          1.3
# 4           4.6         3.1          1.5
# 5           5.0         3.6          1.4
# 6           5.4         3.9          1.7
# 7           4.6         3.4          1.4
# 8           5.0         3.4          1.5
# 9           4.4         2.9          1.4
# 10          4.9         3.1          1.5

bar <- iris[3:13,-c(3,5)]
bar[1:8, ] <- bar[1:8, ] * 2
#    Sepal.Length Sepal.Width Petal.Width
# 3           9.4         6.4         0.4
# 4           9.2         6.2         0.4
# 5          10.0         7.2         0.4
# 6          10.8         7.8         0.8
# 7           9.2         6.8         0.6
# 8          10.0         6.8         0.4
# 9           8.8         5.8         0.4
# 10          9.8         6.2         0.2
# 11          5.4         3.7         0.2
# 12          4.8         3.4         0.2
# 13          4.8         3.0         0.1

如何合并数据框,以便为缺失的情况填充行和列,同时优先考虑重叠元素的一个数据框的结果?在此示例中,我希望优先考虑 bar 中的重叠结果。

merge(..., by = "row.names", all = TRUE) 很接近,因为它保留了所有 13 行,并将缺失值返回为 NA:

foobar <- merge(foo, bar, by = "row.names", all = TRUE)
#    Row.names Sepal.Length.x Sepal.Width.x Petal.Length Sepal.Length.y Sepal.Width.y Petal.Width
# 1          1            5.1           3.5          1.4             NA            NA          NA
# 2         10            4.9           3.1          1.5            9.8           6.2         0.2
# 3         11             NA            NA           NA            5.4           3.7         0.2
# 4         12             NA            NA           NA            4.8           3.4         0.2
# 5         13             NA            NA           NA            4.8           3.0         0.1
# 6          2            4.9           3.0          1.4             NA            NA          NA
# 7          3            4.7           3.2          1.3            9.4           6.4         0.4
# 8          4            4.6           3.1          1.5            9.2           6.2         0.4
# 9          5            5.0           3.6          1.4           10.0           7.2         0.4
# 10         6            5.4           3.9          1.7           10.8           7.8         0.8
# 11         7            4.6           3.4          1.4            9.2           6.8         0.6
# 12         8            5.0           3.4          1.5           10.0           6.8         0.4
# 13         9            4.4           2.9          1.4            8.8           5.8         0.4

但是,它会为组成数据框中的每一列创建一个不同的列,而不管它们是否共享名称。

期望的输出是这样的:

#    Sepal.Length Sepal.Width Petal.Length Petal.Width
# 1           5.1         3.5          1.4          NA # unique to foo
# 2           4.9         3.0          1.4          NA # unique to foo
# 3           9.4         6.4          1.3          0.4 # overlap, retained from bar
# 4           9.2         6.2          1.5          0.4 # 
# 5          10.0         7.2          1.4          0.4 # .
# 6          10.8         7.8          1.7          0.8 # .
# 7           9.2         6.8          1.4          0.6 # .
# 8          10.0         6.8          1.5          0.4 # 
# 9           8.8         5.8          1.4          0.4 # 
# 10          9.8         6.2          1.5          0.2 # overlap, retained from bar
# 11          5.4         3.7           NA          0.2 # unique to bar
# 12          4.8         3.4           NA          0.2 # unique to bar
# 13          4.8         3.0           NA          0.1 # unique to bar

我的直觉是将数据分成两个不相交的集合,以及bar中的相交元素集合,然后将它们合并,但我相信还有更优雅的解决方案!

【问题讨论】:

    标签: r merge


    【解决方案1】:

    (已编辑) 包 plyr 非常适合这种事情。做吧:

     library(plyr)
     foo$ID <- row.names(foo)
     bar$ID <- row.names(bar)
     foobar <- join(foo, bar, type = "full", by = "ID")
    

    正如 Flodl 在 cmets 中指出的那样,通过 row.names 加入不起作用,所以这就是我创建一个新列“ID”的原因。

    【讨论】:

    • Error in [.data.frame(x, by) : undefined columns selected
    • 此外,帮助页面建议我们应该期望结果与来自merge 的结果相同。
    • 现在这并没有像 OP 想要的那样进行覆盖。请测试并与他的预期输出进行比较。
    • 啊,我明白了...是的,我认为我所拥有的任何解决方案都不会比 voidHead 所想的更好。
    • join(bar, foo, type = "full", by = "ID", match = "first") 似乎更像它。如果 OP 不关心行和列的顺序。
    【解决方案2】:

    我看到了对 plyr::join 的热烈推荐,但看不出它与基础 merge 提供的有多大不同:

     merge(foo, bar, by=c("Sepal.Length", "Sepal.Width"), all=TRUE)
    

    【讨论】:

    • 好吧,这显然不是 OP 想要的。只需将您的输出与 OP 进行比较即可。
    • 同意不清楚。我假设 Petal.Width 值的差异是由 OP 的懒惰来解释的。我的懒惰解释了缺少的计算文本值。
    • @BondedDust 您指的是哪个 Petal.Width 值?我手动构建了预期的输出,但我相信它与示例数据一致。
    • 所有 Petal.Length 值小于 1.0。原著中没有这样的。
    • 没错。已更正。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多