在两个 data.tables 中添加值
Adding values in two data.tables
我有两个 data.tables,其中一个是另一个 rows/columns 的子集。我想将较小 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"]
...但事实并非如此。不过,可能有一些简单的变体会起作用,对吗?
您可以使用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
我更喜欢 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.tables,其中一个是另一个 rows/columns 的子集。我想将较小 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"]
...但事实并非如此。不过,可能有一些简单的变体会起作用,对吗?
您可以使用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
我更喜欢 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