如何在R data.table中高效获取最大值及其来源列
高效动态为data.table添加最大值及其来源列
可以利用data.table的向量化特性和.SD工具,一次性计算出指定列的最大值来源列名与对应数值,避免重复计算或硬编码列判断,适配任意数量的目标列:
核心实现代码
library(data.table) DT <- data.table(mtcars) target_cols <- c('gear', 'carb') # 一次性生成maxColName和maxValue两列 DT[, c('maxColName', 'maxValue') := { max_pos <- max.col(.SD) .(names(.SD)[max_pos], .SD[cbind(seq_len(.N), max_pos)]) }, .SDcols = target_cols]
关键逻辑说明
max.col(.SD):快速获取每行最大值在目标列中的位置索引(相对于.SD的列顺序)names(.SD)[max_pos]:将索引转换为对应的列名,生成maxColName列.SD[cbind(seq_len(.N), max_pos)]:通过行号+列索引的矩阵组合,向量化提取每行的最大值,生成maxValue列- 全程基于data.table的原生向量化操作,效率远高于逐条件赋值,且无需修改代码即可扩展到3列及以上的场景
关于get()失败的原因
get()函数无法直接处理每行不同的列名字符串,它是针对单个变量名的提取工具,不支持向量化的多列名匹配。而上述方案用矩阵索引.SD的方式,完全契合data.table的向量化设计逻辑。
可选:复用最大值索引(如需后续操作)
如果需要复用最大值的位置索引,可以先单独计算索引列,再生成目标列:
DT[, max_pos := max.col(.SD), .SDcols = target_cols] DT[, c('maxColName', 'maxValue') := .(names(.SD)[max_pos], .SD[cbind(seq_len(.N), max_pos)]), .SDcols = target_cols] # 不需要索引列时可删除 DT[, max_pos := NULL]
内容的提问来源于stack exchange,提问作者TrainedMusician
相关产品推荐
相关产品推荐

