如何针对样本数量不确定的R data.table按分组条件筛选行?
基于动态分组的data.table行筛选方案
1. 原始数据准备
首先生成示例data.table:
set.seed(123666) dt <- data.table(sample1 = sample(10), sample2 = sample(10), sample3 = sample(10), sample4 = sample(10), sample5 = sample(10), sample6 = sample(10))
生成的dt内容如下:
sample1 sample2 sample3 sample4 sample5 sample6 1: 2 6 3 9 1 2 2: 10 9 10 3 7 5 3: 6 10 8 5 5 1 4: 8 2 9 8 6 6 5: 5 4 5 10 10 8 6: 7 1 7 4 4 10 7: 4 3 1 6 3 7 8: 1 5 6 1 2 3 9: 3 7 2 2 8 9 10: 9 8 4 7 9 4
2. 固定分组场景的解法
假设前3个样本属于group_a,后3个属于group_b,需要筛选出每个分组中至少2个样本值大于2的行,固定分组下可以这样实现:
group_a <- paste0('sample', seq(1,3)) group_b <- paste0('sample', seq(4,6)) dt[rowSums(dt[, ..group_a, with = FALSE] > 2) >= 2 & rowSums(dt[, ..group_b, with = FALSE] > 2) >= 2]
运行结果:
sample1 sample2 sample3 sample4 sample5 sample6 1: 10 9 10 3 7 5 2: 6 10 8 5 5 1 3: 8 2 9 8 6 6 4: 5 4 5 10 10 8 5: 7 1 7 4 4 10 6: 4 3 1 6 3 7 7: 3 7 2 2 8 9 8: 9 8 4 7 9 4
3. 动态分组场景需求
当样本数量不确定时,我们有一个描述样本分组的变量:
group <- paste0('sample', seq(1,6)) group_id <- c(rep('group_a', 3), rep('group_b', 3)) names(group) <- group_id
该变量的对应关系为:
group_a group_a group_a group_b group_b group_b "sample1" "sample2" "sample3" "sample4" "sample5" "sample6"
需要用最简洁的data.table语法完成相同的筛选逻辑。
4. 动态分组的简洁解法
可以通过宽表转长表+分组统计+行级校验的链式操作实现,代码如下:
melt(dt, measure.vars = names(dt))[, group_id := names(group)[match(variable, group)] ][, .(ok = sum(value > 2) >= 2), by = .(rn = rowid(variable), group_id) ][, all(ok), by = rn][V1 == TRUE, dt[rn]]
代码逻辑说明
melt(dt, measure.vars = names(dt)):将宽格式的dt转换为长格式,每行对应一个样本变量的取值;group_id := names(group)[match(variable, group)]:通过match将每个样本变量映射到对应的分组ID;[, .(ok = sum(value > 2) >= 2), by = .(rn = rowid(variable), group_id)]:按行号(rowid(variable)生成每行唯一标识)和分组统计,标记当前分组中值>2的数量是否≥2;[, all(ok), by = rn]:按行号分组,检查该行所有分组是否都满足条件;[V1 == TRUE, dt[rn]]:筛选出所有分组都满足条件的行号,提取原dt对应的行。
运行该代码后,得到的结果与固定分组场景的输出完全一致。
内容的提问来源于stack exchange,提问作者zhang
相关产品推荐
相关产品推荐

