【问题标题】:How to combine the columns of two data.tables?如何组合两个data.tables的列?
【发布时间】:2019-11-08 13:05:36
【问题描述】:

我有两个 data.table 类型的表。我想将这些表合并为一张表。它们看起来像:

DT1:

1  A  B  C
2  A  B  C  
3  A  B  C

DT2:

D  E  F
D  E  F
D  E  F

我想像这样组合它们:

1  A  B  C  D  E  F
2  A  B  C  D  E  F
3  A  B  C  D  E  F

我不知道如何通过合并来做到这一点,因为数据表没有通用的列名。

我知道这可以通过 cbind 实现,但我正在处理很多行,所以我更喜欢为处理大数据表而构建的函数。

谁能告诉我怎么做?

【问题讨论】:

  • 你试过cbind(DT1, DT2) 吗?是不是太慢了?
  • 试试 data.table 包。
  • @RonakShah 我正在处理很多行,而 cbind 不是为此而构建的。然后R可能会崩溃。所以希望有更好的选择
  • @jordinec cbind 比加入/合并需要更少的资源。
  • 尝试library(data.table),然后尝试cbind.data.table(DT1,DT2)

标签: r merge data.table


【解决方案1】:

我尝试了一些稍微大一点的桌子(使用 Hart Radev 提供的代码),我已经 microbenchmarked 他们,也许它会有所帮助:

library(dplyr)
library(microbenchmark)

DT1 = data.frame(A = rep('A', 300000), B = rep('B', 300000))
DT2 = data.frame(C = rep('C', 300000), D = rep('D', 300000))

microbenchmark(
bind_cols = {bind_cols(DT1, DT2)},
cbind = {cbind(DT1,DT2)},
# Hart solution
merge = { DT1$rowname = rownames(DT1) 
          DT2$rowname = rownames(DT2)
          DT3 = merge(DT1, DT2, by = 'rowname')}
)

Unit: microseconds
           expr         min           lq         mean       median           uq         max neval
      bind_cols      72.534      88.9610 1.640497e+02     169.6010     209.4940     348.160   100
          cbind      42.241      50.5610 8.019269e+01      61.4405     114.9875     250.455   100
          merge 2142101.821 2256677.2310 2.574166e+06 2416274.7380 2732207.2465 5956733.422   100

data.table 不是我的一杯茶,但我想它可能会有所帮助。

【讨论】:

  • 我添加了一个带有 data.table 更新连接的答案...随时在此处添加基准测试,我将删除答案..
  • @Wimpel,谢谢,但我认为 data.table 的想法是由你决定的,并且由于它在标签中,我想留给 OP 选择你的答案(以及让你得到正确答案的可能性),直到现在你得到了我的支持。
【解决方案2】:

基于@s_t 答案,这里是使用data.table 进行更新连接的基准

DT1 = data.frame(A = rep('A', 300000), B = rep('B', 300000))
DT2 = data.frame(C = rep('C', 300000), D = rep('D', 300000))

library(data.table)
setDT(DT1)
setDT(DT2)


microbenchmark::microbenchmark(
  cbind = {
    dt1    <-copy(DT1)
    dt2    <-copy(DT2)
    result <- cbind(DT1, DT2)
  },
  update_join = {
    dt1    <-copy(DT1)
    dt2    <-copy(DT2)
    dt1[, id := .I][ dt2[, id := .I], c("C", "D") := .(i.C, i.D), on = .(id)][, id := NULL]
  } )

# Unit: milliseconds
#        expr     min       lq      mean   median       uq      max neval
# cbind        1.8889  2.68405  9.454567  2.99505  3.62625 226.4432   100
# update_join 23.9186 24.67530 36.957518 25.62405 36.42760 249.3631   100

cbind() 仍然以压倒性优势获胜...

【讨论】:

  • 为什么不只是DT1[, names(DT2) := DT2]
【解决方案3】:

如果您想通过合并来尝试,只需将行名添加为列,然后进行合并:

DT1 = data.frame(A = rep('A', 3), B = rep('B', 3))
DT1$rowname = rownames(DT1)
DT2 = data.frame(C = rep('C', 3), D = rep('D', 3))
DT2$rowname = rownames(DT2)
DT3 = merge(DT1, DT2, by = 'rowname')

【讨论】:

    猜你喜欢
    • 2019-02-13
    • 2012-08-28
    • 2021-11-29
    • 2014-06-07
    • 2016-03-24
    • 1970-01-01
    • 2021-03-24
    • 2019-05-13
    • 2015-11-29
    相关资源
    最近更新 更多