R中data.table等效dplyr across()转换多列并返回全表的方法
data.table 等价于dplyr across()的实现方案
你之前的代码失效核心是两个错误:
- 额外加了
unlist操作,:=原生支持接收lapply返回的列表结构,拆包后反而会打乱列对应关系 - 赋值左侧的列名变量没有用括号包裹,导致data.table将其识别为创建单个新列,而非使用变量中存储的多列名称
1. 原地修改原数据集(data.table默认高效原地操作)
直接对选中列批量修改,修改直接作用于原对象,不需要二次赋值:
library(data.table) library(stringr) # 转换为data.table对象 iris <- setDT(copy(datasets::iris)) # 筛选列名包含"Petal"的列 petal_cols <- str_subset(colnames(iris), "Petal") # 批量处理多列,直接修改原表 iris[, (petal_cols) := lapply(.SD, round, digits = 0), .SDcols = petal_cols]
如果不需要提前声明列名变量,还可以用patterns直接在.SDcols中匹配列名,写法更简洁:
iris[, names(.SD) := lapply(.SD, round, digits = 0), .SDcols = patterns("Petal")]
2. 不修改原数据集,返回新的完整数据集
和dplyr mutate行为一致,不改动原数据,输出处理后的新表:
# 先复制原对象再修改,避免影响原数据 iris_new <- copy(iris)[, (petal_cols) := lapply(.SD, round, digits = 0), .SDcols = petal_cols]
如果需要将处理结果存为新列不覆盖原列,只需要修改赋值左侧的列名即可:
# 给处理后的列加_round后缀 iris[, paste0(petal_cols, "_round") := lapply(.SD, round, digits = 0), .SDcols = petal_cols]
内容的提问来源于stack exchange,提问作者EMD
相关产品推荐
相关产品推荐

