当前位置: 首页 > 知识库问答 >
问题:

r data.table在连接中更新多个列

贺佑运
2023-03-14

我有两个结构相同的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

到目前为止,我的最佳选择如下:

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

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

如果 DT2 中的每一行都与 DT1 中的一行匹配,则此方法有效,否则会产生意外的结果。有没有一种更严格/更优雅的方式来表达RHS来执行这个涉及DT1和DT2的可变数量的列赋值?

共有2个答案

张高义
2023-03-14

一种可能性是进行连接,如果有重复的列,可以创建一个表达式来使用这些名称执行求和

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
杨凌
2023-03-14

怎么样:

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
 类似资料:
  • 问题内容: 如何在MySQL中更新多个值? 这不起作用: 问题答案: 您需要在两个不同的值之间添加一个逗号。例如:

  • 在我的应用程序中,用户和首选项实体之间存在多对多关联。由于连接表需要一个额外的列,因此我必须将其分解为2个一对多的关联: 用户实体: 偏好实体: 用户首选项实体: 为了更新其中一个首选项,我循环浏览用户的一组首选项,并更新值如下: 我已经确认,我试图更新的用户变量在代码运行后确实包含新值。更奇怪的是,当重定向发生时,该值会在网页上更新,但数据库不会更新!这是我用来做更新的代码,这个类用@Trans

  • 问题内容: 我知道您可以一次插入多行,是否可以在MySQL中一次更新多行(如在一个查询中)? 编辑:例如,我有以下内容 我想将以下所有更新合并到一个查询中 问题答案: 是的,这是可能的-您可以在插入的键更新中使用INSERT…。 使用您的示例:

  • 问题内容: 我有使用socket.io(1.5)的这个简单的node.js Servercode: 如果我运行此代码并按几次F5键,则在某些情况下会在断开旧连接之前创建新的连接。一段时间后,我认为它的心跳超时,所有连接都将关闭。查看结果: 我的问题是:这是Bug还是socket.io的正常行为?只需按F5键,如何防止连接泛滥? 最好的问候马克 问题答案: 我制作了自己的测试应用程序,能够弄清楚发生

  • 问题内容: 我有2张桌子,如下所示: serial_table serial_key CHARACTER VARYING(20), PRIMARY KEY(id, serial_key) serial_rate: serial_key CHARACTER VARYING(20), rate NUMERIC, PRIMARY KEY(id, serial_key), FOREIGN KEY (id,

  • 问题内容: 目前,我的连接 mongoose.js 具有以下代码: 需要连接的文件是 test.js : 如何更新mongoose.js以使用mongoose.createConnection(…)函数使用多个连接? 当我进行如下更改时,我仅从一个连接的更改开始: 我得到“未定义不是函数”。如果我使用此代码: 我收到“错误:尝试打开未关闭的连接” 有什么建议吗? 问题答案: mongoose通过