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

如何针对样本数量不确定的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]]

代码逻辑说明

  1. melt(dt, measure.vars = names(dt)):将宽格式的dt转换为长格式,每行对应一个样本变量的取值;
  2. group_id := names(group)[match(variable, group)]:通过match将每个样本变量映射到对应的分组ID;
  3. [, .(ok = sum(value > 2) >= 2), by = .(rn = rowid(variable), group_id)]:按行号(rowid(variable)生成每行唯一标识)和分组统计,标记当前分组中值>2的数量是否≥2;
  4. [, all(ok), by = rn]:按行号分组,检查该行所有分组是否都满足条件;
  5. [V1 == TRUE, dt[rn]]:筛选出所有分组都满足条件的行号,提取原dt对应的行。

运行该代码后,得到的结果与固定分组场景的输出完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:24:54