【问题标题】:rbind.fill but in base Rrbind.fill 但在基础 R
【发布时间】:2018-08-07 15:21:28
【问题描述】:

我正在尝试找到一种高效(运行速度快且编码简单)的方法来执行 rbind.fill 函数,但在基础 R 中。根据我的搜索,似乎有很多库函数,例如 smartbindbind_rowsrbinddata.table 上,不过,如前所述,我需要一个基本 R 中的解决方案。我发现使用:

df3 <- rbind(df1, df2[, names(df1)])

来自this question 的回答,但它删除了列,而我希望添加用NA 填充的额外列。

EDIT 如果此方法适用于空的data.frame 和已填充的data.frame 也很好,本质上只是设置返回已填充的。 (这是为了简单起见,但如果不可能,只需将变量替换为新的 data.frame (如果它为空)并不难。

EDIT2 我还希望它按列名绑定标记为相同的列。此外,第一个数据框可以比第二个数据框更大也可以更小,并且两者都可能有另一个没有的列。

EDIT3 正如评论所建议的,这是我想要的示例输入和输出(我只是编造了它们并不重要的数字)。

#inputs
a <- data.frame(aaa=c(1, 1, 2), bbb=c(2, 3, 3), ccc=c(1, 3, 4))
b <- data.frame(aaa=c(8, 5, 4), bbb=c(1, 1, 4), ddd=c(9, 9, 9), eee=(1, 2, 4))
#desired output
aaa bbb ccc ddd eee
1   2   1   NA  NA
1   3   3   NA  NA
2   3   4   NA  NA
8   1   NA  9   1
5   1   NA  9   2
4   4   NA  9   4

虽然我使用 R 已经有几个星期了,但它对我来说还是比较新的,所以我还没有把机制弄得足够低,还没有真正找到解决方案,尽管我一直在考虑以某种方式使用 intersect使用names(a)names(b) 并尝试首先仅绑定这些列,然后以某种方式添加其他列,但我不确定从这里去哪里/如何以“R”方式实际实现它...

【问题讨论】:

  • 您提到了您想要的几个功能。如果您添加一个具有预期输出的具体示例,我们将更清楚地了解您的确切含义。如果您有兴趣,请提供一些指导:stackoverflow.com/questions/5963269/…
  • 进一步,你有没有尝试过任何东西(除了简单的rbind)?这可能很容易做到,但请不要将 SO 视为免费代码服务。 (无论如何,有人可能会这样做,但它对你的努力有很长的路要走。)
  • 我已经更新了我的答案,以(希望)解决你的一些 cmets!
  • 您是否只是要求在基础 R 中重新实现 rbind.fill?如果是这样,为什么要重新发明呢?它做了/不做你需要的什么?
  • @Aaron 我正在为一个服务器编写这段代码,该服务器对那里的内容有非常具体的限制。我并不是真的需要任何 功能。我想我只是要求实现 rbind.fill,但我只是感到惊讶(可能是因为我没有足够地使用 R)没有真正的基本“R 风格”方式来做到这一点定义新功能。

标签: r rbind


【解决方案1】:

我不知道它的效率如何,但一种简单的编码方法是将缺失的列添加到每个数据帧,然后将rbind 一起添加。

rbindx <- function(..., dfs=list(...)) {
  ns <- unique(unlist(sapply(dfs, names)))
  do.call(rbind, lapply(dfs, function(x) {
    for(n in ns[! ns %in% names(x)]) {x[[n]] <- NA}; x }))
}

a <- data.frame(aaa=c(1, 1, 2), bbb=c(2, 3, 3), ccc=c(1, 3, 4))
b <- data.frame(aaa=c(8, 5, 4), bbb=c(1, 1, 4), ddd=c(9, 9, 9), eee=c(1, 2, 4))
rbindx(a, b)

#   aaa bbb ccc ddd eee
# 1   1   2   1  NA  NA
# 2   1   3   3  NA  NA
# 3   2   3   4  NA  NA
# 4   8   1  NA   9   1
# 5   5   1  NA   9   2
# 6   4   4  NA   9   4

【讨论】:

    【解决方案2】:

    只需使用rbind.fill。如果您无法安装plyr 包,请拔出您需要的部件。

    rbind.fill 内部依赖似乎很少:plyr::compact 是单行的,plyr:::output_template 依赖于plyr:::allocate_column,但乍一看似乎都是基本代码。因此,复制这 4 个功能(注明来源并确保许可证与您的使用兼容 - CRAN 上的当前版本使用非常宽松的 MIT 许可证,您只需要保持它是 MIT 许可的),然后您就拥有了rbind.fill的真正实现。

    为什么采用这种方法?因为,正如 Aaron 指出的那样 - 你知道它是有效的。它已经使用和调试多年。

    【讨论】:

    • 这是一个不错的选择。代码经过了很好的测试,我确信可以正确处理各种边缘情况,而我的几行几乎可以肯定没有。
    猜你喜欢
    • 2021-03-27
    • 2013-05-01
    • 2018-11-11
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多