You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在data.table中用lapply为动态列设置指定最小值?

动态为data.table多列设置各自的最小值

问题场景

有一个列数动态可变的data.table,需要为匹配col<数字>格式的每一列设置对应的指定最小值。示例数据如下:

library(data.table)
dt <- data.table(
  urn = 1:10,
  col1 = 5:14,
  col2 = 11:20
)

错误原因分析

你之前的两种方法都错误地将列名字符向量my_cols当作列的实际数值进行处理,导致逻辑错误或报错:

  • 第一种方法中,my_cols < x是字符串与数字的比较,结果全为FALSE,最终所有行被赋值为x;
  • 第二种方法同理,用列名字符串参与数值比较,直接触发类型不匹配的错误。

正确解决方案

利用Map(或mapply)将目标列与对应最小值一一配对,结合pmax函数实现“取列值与最小值中的较大者”,即可完成动态替换:

方法1:使用Map与.SD

min_vals <- c(10, 15)
my_cols <- grep("^col", colnames(dt), value = TRUE)

# 对每个目标列应用pmax,替换低于最小值的行
dt[, (my_cols) := Map(function(col, min_val) pmax(.SD[[col]], min_val), my_cols, min_vals)]

方法2:使用mapply与.SDcols(更简洁)

dt[, (my_cols) := mapply(function(col_val, min_val) pmax(col_val, min_val), 
                         .SD, min_vals, SIMPLIFY = FALSE), 
   .SDcols = my_cols]

更安全的命名向量版本(避免顺序错误)

如果担心min_vals的顺序与列顺序不匹配,可以将min_vals定义为命名向量,确保每个列对应正确的最小值:

min_vals <- c(col1 = 10, col2 = 15)
my_cols <- grep("^col", colnames(dt), value = TRUE)

dt[, (my_cols) := Map(function(col, min_val) pmax(.SD[[col]], min_val), 
                      my_cols, min_vals[my_cols])]

验证结果

执行后得到期望输出:

dt
#       urn  col1  col2
#     <int> <int> <int>
#  1:     1    10    15
#  2:     2    10    15
#  3:     3    10    15
#  4:     4    10    15
#  5:     5    10    15
#  6:     6    10    16
#  7:     7    11    17
#  8:     8    12    18
#  9:     9    13    19
# 10:    10    14    20

内容的提问来源于stack exchange,提问作者Dan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 23:47:23