将.SDcols和.SD与data.table中的两组列一起使用

时间:2020-06-13 02:00:21

标签: r data.table

是否可以将.SD / .SDcols与两组列一起使用?

即在下面的代码中,在最后一行中,我需要将第一组(colA)的多个列乘以第二组(colsA)的对应列,如下所示:

colA <- paste0("a", 1:3);     colB <- paste0("b", 1:3)
colC <- paste0("c", 1:3)

dt <- data.table(V1=1:3);dt                   # just creating a data.table to work with 
dt[, (colA):=.(1:3,4:6,7:9)][, V1:=NULL][]
dt[, (colB):=.(11:13,14:16,17:19)][]

dt[, (colC):= .SD * .SD, .SDcols=colA][]      # is done efficiently using `data.table`
dt[ , (colC):= .SD1 * .SD2, .SDcols1=colA, .SDcols2=colB][] # Is that possible using `data.table` framework?

经常发生这种情况,当您有数百个具有某些值的列,然后又有数百个具有某些归一化值的列时,您需要将它们相乘(或除)。目前,我只是简单地使用for循环来执行此操作,从而抵消了data.table的所有功能和优点。

2 个答案:

答案 0 :(得分:3)

可能您正在尝试做:

library(data.table)
dt[, (colC) := .SD[, colA, with = FALSE] * .SD[,colB, with = FALSE]]

答案 1 :(得分:3)

release notes for data.table v1.11.0 (01 May 2018)状态:

因此,在任何情况下都不再需要with=。请更改为 使用..前缀,在接下来的几年中,我们将开始 正式弃用并删除with=参数。

所以,这是另外两个提示:

使用..前缀

library(data.table) # development version 1.12.9 used
dt[, (colC) := .SD[, ..colA] * .SD[, ..colB]][]
   a1 a2 a3 b1 b2 b3 c1 c2  c3
1:  1  4  7 11 14 17 11 56 119
2:  2  5  8 12 15 18 24 75 144
3:  3  6  9 13 16 19 39 96 171

虽然结果与预期的一样,但仍有警告消息

1:在[.data.table(.SD,,..colA)中:均为'colA' 和'.colA'存在于调用范围中。请删除“ ..colA” 为清楚起见,在调用范围中使用了变量。
2:在[.data.table(.SD, ..colB):调用范围中同时存在'colB'和'..colB'。请 为了清楚起见,请在调用范围内删除“ ..colB”变量。

要消除警告,可以使用中间结果

tmp <- dt[, ..colA] * dt[, ..colB]
dt[, (colC) := tmp][]

使用mget()

mget()也对我有用:

dt[, (colC) := .SD[, mget(colA)] * .SD[, mget(colB)]][]

数据

library(data.table)
colA <- paste0("a", 1:3)
colB <- paste0("b", 1:3)
colC <- paste0("c", 1:3)
dt <- data.table(1:3, 4:6, 7:9, 11:13, 14:16, 17:19)
setnames(dt, c(colA, colB))[]