r data.table更新join中的多个列

sch*_*h56 3 join r data.table

我有两个data.table具有相同的结构.两个关键列后跟多个数据列.数据列的数量可能会有所不同.我想将第二个data.table中的值添加到第一个data.table中的相应行/列.

DT1 <- cbind(data.table(loc=c("L1","L2","L3"), product=c("P1","P2","P1")), matrix(10,nrow=3,ncol=12))
setkey(DT1, loc, product)
DT1
   loc product V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
1:  L1      P1 10 10 10 10 10 10 10 10 10  10  10  10
2:  L2      P2 10 10 10 10 10 10 10 10 10  10  10  10
3:  L3      P1 10 10 10 10 10 10 10 10 10  10  10  10
DT2 <- cbind(data.table(loc=c("L2","L3"), product=c("P2","P1")), matrix(1:24,nrow=2,ncol=12))
setkey(DT2, loc, product)
   loc product V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
1:  L2      P2  1  3  5  7  9 11 13 15 17  19  21  23
2:  L3      P1  2  4  6  8 10 12 14 16 18  20  22  24
Run Code Online (Sandbox Code Playgroud)

到目前为止,我最好的选择是以下内容

DT1[DT2, 3:14 := as.data.table(DT1[DT2, 3:14, with=FALSE] + DT2[, 3:14, with=FALSE]), with=FALSE]
   loc product V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
1:  L1      P1 10 10 10 10 10 10 10 10 10  10  10  10
2:  L2      P2 11 13 15 17 19 21 23 25 27  29  31  33
3:  L3      P1 12 14 16 18 20 22 24 26 28  30  32  34
Run Code Online (Sandbox Code Playgroud)

请注意,nrow和ncol以及loc和product条目都是可变的,具体取决于源数据.

如果DT2中的每一行都与DT1中的一行匹配,则此方法有效,否则会产生意外结果.是否有更严格/更优雅的方式来表达RHS以参考DT1和DT2进行这种可变数量的列分配?

edd*_*ddi 6

怎么样:

cols = paste0('V', 1:12)

DT1[DT2, (cols) := setDT(mget(cols)) + mget(paste0('i.', cols))]
DT1
#   loc product V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
#1:  L1      P1 10 10 10 10 10 10 10 10 10  10  10  10
#2:  L2      P2 11 13 15 17 19 21 23 25 27  29  31  33
#3:  L3      P1 12 14 16 18 20 22 24 26 28  30  32  34
Run Code Online (Sandbox Code Playgroud)


Sym*_*xAU 0

一种可能性是进行连接,并且在有重复列的情况下,您可以创建一个表达式来使用这些名称来执行求和

DT3 <- DT2[ DT1 ]

dup <- names(DT3)[grep("[i.]", names(DT3))]
dup2 <- gsub("[i.]", "", dup)
expr <- paste0("`:=`(", paste0(dup2,  "=",  dup2, "+", dup, collapse = ","), ")")

## set NA to 0
for(j in names(DT3)) set(DT3, which(is.na(DT3[[j]])), j, 0)

DT3[, eval(parse(text = expr))][, c("loc", "product", dup2), with=F]

#    loc product V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
# 1:  L1      P1 10 10 10 10 10 10 10 10 10  10  10  10
# 2:  L2      P2 11 13 15 17 19 21 23 25 27  29  31  33
# 3:  L3      P1 12 14 16 18 20 22 24 26 28  30  32  34
Run Code Online (Sandbox Code Playgroud)