如何在data.table中使用.SD批量生成新变量而非覆盖原变量?
当然有更简洁高效的方法!你完全可以在data.table的括号操作里直接批量生成新列,不用额外的合并步骤——这正是data.table设计中“原地修改、减少冗余操作”的优势所在。
直接上核心代码:
library(data.table) mtcars <- as.data.table(mtcars) # 一步到位生成新列 mtcars[, paste0(c("hp", "drat", "gear"), "_newvars") := lapply(.SD, function(z) z * wt), .SDcols = c("hp", "drat", "gear")]
代码解释:
- 左侧的列名生成:用
paste0()直接拼接原列名和后缀,作为:=的左侧,告诉data.table要创建哪些新列 - .SD与.SDcols:
.SDcols指定我们要操作的原列集合,.SD就是这些列组成的子数据表 - 右侧的批量操作:
lapply(.SD, ...)对.SD里的每一列执行和wt相乘的计算,结果会自动对应到左侧的新列上,完全不用额外合并
如果觉得重复写列名麻烦,还可以把列名存成变量,进一步简化:
target_cols <- c("hp", "drat", "gear") mtcars[, paste0(target_cols, "_newvars") := lapply(.SD, `*`, wt), .SDcols = target_cols]
这里用*的函数形式替代了匿名函数,代码更简洁。
这种方法的好处是原地修改数据,不会像cbind那样复制整个数据集,在处理大型数据集时性能优势会非常明显。而你之前逐个赋值的方式,在列数少的时候没问题,但列数多的时候,批量方法能节省大量重复代码。
内容的提问来源于stack exchange,提问作者MatthewR
相关产品推荐
相关产品推荐

