【问题标题】:Adding values in two data.tables在两个 data.tables 中添加值
【发布时间】:2015-09-27 01:58:57
【问题描述】:

我有两个 data.tables,一个有另一个的行/列的子集。我想将较小的 data.table 的值添加到较大的值:

DT1 <- as.data.table(matrix(c(0, 1, 2, 3), nrow=2, ncol=2, 
       dimnames=list(c("a", "b"), c("a", "b"))), keep=T)
DT2 <- as.data.table(matrix(c(0, 0, 1, 2, 2, 1, 1, 0, 3), nrow=3, ncol=3, 
       dimnames=list(c("a", "b", "c"), c("a", "b", "c"))), keep=T)

DT1
#   rn a b
#1:  a 0 2
#2:  b 1 3
DT2
#   rn a b c
#1:  a 0 2 1
#2:  b 0 2 0
#3:  c 1 1 3

我想将 DT1 添加到 DT2 以便我得到

#   rn a b c
#1:  a 0 4 1
#2:  b 1 5 0
#3:  c 1 1 3

我知道我可以很容易地用 DT1 覆盖 DT2 的值:

DT2[DT1, names(DT1) := DT1, on="rn"]

我希望这样的事情会起作用:

DT2[DT1, names(DT1) := DT1 + .SD, on="rn"]

...但事实并非如此。不过,这可能有一些简单的变化会起作用,对吧?

【问题讨论】:

标签: r data.table


【解决方案1】:

您可以使用rbindlist() 将两者结合起来,然后根据rn 将值相加

rbindlist(list(DT1, DT2), fill=TRUE)[, lapply(.SD, sum, na.rm = TRUE), by = rn]
#    rn a b c
# 1:  a 0 4 1
# 2:  b 1 5 0
# 3:  c 1 1 3

【讨论】:

    【解决方案2】:

    我更喜欢 Richard 的方式,但这里有一个看起来更像 OP 最初想法的替代方案:

    vs = setdiff(names(DT1),"rn")
    DT2[DT1, (vs) := {
      x.SD = mget(vs) 
      i.SD = mget(paste0("i.",vs)) 
      Map("+", x.SD, i.SD)
    }, on="rn", by=.EACHI]
    #    rn a b c
    # 1:  a 0 4 1
    # 2:  b 1 5 0
    # 3:  c 1 1 3
    

    【讨论】:

    • 虽然这可能有点复杂,但它比理查德的回答要快得多——谢谢!
    • 嗯。我在一个小的 data.table (1.3M x 70) 上运行,Rich 的速度快了 70 倍! 1.5 秒对 102 秒。
    猜你喜欢
    • 1970-01-01
    • 2015-11-29
    • 2013-11-22
    • 1970-01-01
    • 2020-05-02
    • 2019-02-13
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    相关资源
    最近更新 更多