如何在data.table链式操作中让新生成列参与行求和计算
在data.table中同一操作内使用新生成的列计算行和
这个问题我之前也碰到过,核心原因是data.table里.SD的列子集是在整个j表达式执行前就确定的,所以你刚用:=生成的新列不会立刻被包含到.SD中。不过有几种简洁的方式能实现你要的效果:
方法1:按顺序赋值,直接引用新生成的列
data.table的:=是按顺序执行赋值操作的,先定义tau12,后面的sum1就能直接引用这个新列。这种方式适合列数不多的场景:
# 先还原你的data.table library(data.table) library(stringr) name <- c("Bob","Mary","Jane","Kim") weight <- c(60,65,45,55) height <- c(170,165,140,135) dft <- data.table(name,weight,height) dft <- data.table (dft[,.(name)] , dft[, weight %*% t(weight)]) names(dft) <- c("name", str_c("tau",1:4)) # 同一操作内生成tau12并计算包含它的行和 dft[, `:=`( tau12 = tau1 * tau2, sum1 = tau1 + tau2 + tau3 + tau4 + tau12 )]
方法2:用rowSums动态包含新列
如果tau相关的列很多,不想手动列出来,可以先生成tau12,再通过索引指定所有需要求和的列:
dft[, `:=`( tau12 = tau1 * tau2, sum1 = rowSums(.SD[, c(paste0("tau", 1:4), "tau12"), with = FALSE]) )]
这里.SD[, c(..., "tau12"), with = FALSE]会在当前行的上下文中把新生成的tau12和原有tau列组合起来,再用rowSums计算行和。
方法3:利用表达式简化计算
既然tau12是tau1*tau2,你也可以直接把这个表达式代入求和,省去列名引用:
dft[, `:=`( tau12 = tau1 * tau2, sum1 = tau1 + tau2 + tau3 + tau4 + tau1*tau2 )]
为什么你的原代码不生效?
你之前的代码里,.SDcols = patterns("^tau")在整个j表达式执行前就已经锁定了原有4个tau列,.SD不会包含后续生成的tau12,所以lapply(.SD, sum)只能计算原有列的和。
内容的提问来源于stack exchange,提问作者tobinz
相关产品推荐
相关产品推荐

