如何在data.table中为多列分别应用不同条件更新数据?
高效实现data.table多列对应条件赋值
问题背景
给定如下data.table:
dt <- data.table( year = c(2020, 2021, 2022), b = c(10, 20, 30), c = c(100, 200, 300) )
需求是为指定列分别匹配对应year条件,将符合条件的单元格设为NaN。现有for循环实现如下:
cols_to_update <- c("b", "c") conds <- c(2020, 2022) for ( i in seq_along(cols_to_update)) { dt[year == conds[i], (cols_to_update[i]) := NaN] } print(dt)
期望输出:
year b c 1: 2020 NaN 100 2: 2021 20 200 3: 2022 30 NaN
希望找到更简洁高效的data.table原生实现方式,避免for循环(虽可用但想更贴合data.table风格)。
解决方案
方法1:用Map配对列与条件
利用Map将列名和对应条件一一绑定,直接在data.table中完成赋值,代码更简洁:
cols_to_update <- c("b", "c") conds <- c(2020, 2022) Map(function(col, cond) dt[year == cond, (col) := NaN], cols_to_update, conds)
方法2:用.SDcols结合lapply
通过构造逻辑判断,配合.SD批量处理目标列:
cols_to_update <- c("b", "c") conds <- c(2020, 2022) dt[, (cols_to_update) := lapply(seq_along(cols_to_update), function(i) { ifelse(year == conds[i], NaN, .SD[[i]]) }), .SDcols = cols_to_update]
补充说明
其实data.table的for循环本身效率并不低(因为data.table的赋值是原地修改,无额外内存拷贝),但上述两种方法更符合data.table的向量化风格,代码更紧凑。如果列数较多,这两种方法的可读性和维护性会更优。
内容的提问来源于stack exchange,提问作者John1104108
相关产品推荐
相关产品推荐

