如何基于两个分类变量对DataFrame按组下采样(单样本限指定行数)
解决方法:用dplyr快速实现分组下采样
嗨,这个需求用dplyr包就能轻松搞定,代码简洁逻辑清晰,完全匹配你的要求。
核心思路
我们需要先按groups和samples做双重分组,确保每个子组对应「某一个group下的某一个sample」的所有行,然后对每个子组保留最多X行——如果子组本身行数≤X,就直接全部保留。
完整代码示例
先构造你的原始数据:
samples<-c("A","A","A","A","B","B","B","C","C","C") groups<-c(1,1,2,3,1,1,1,2,2,2) df<- data.frame(samples,groups)
加载dplyr并执行下采样操作(这里X设为2):
library(dplyr) # 设置下采样的最大行数 max_rows <- 2 # 执行下采样 downsampled_df <- df %>% # 按组别+样本双重拆分数据 group_by(groups, samples) %>% # 每个子组取「当前行数和max_rows的较小值」,自动兼容行数不足的情况 slice_sample(n = min(n(), max_rows)) %>% # 取消分组,恢复普通DataFrame结构 ungroup()
可选调整
如果你不需要随机采样,而是想要固定保留每个子组的前X行,可以把slice_sample换成slice_head:
downsampled_df <- df %>% group_by(groups, samples) %>% slice_head(n = min(n(), max_rows)) %>% ungroup()
结果验证
运行后你会看到:
- groups=1中的sample A原本有2行,全部保留
- groups=1中的sample B原本有3行,被缩减到2行
- 所有行数≤2的子组(比如groups=2的sample A、groups=3的sample A等)都完整保留
- groups=2中的sample C原本有3行,被缩减到2行
内容的提问来源于stack exchange,提问作者Kaizen
相关产品推荐
相关产品推荐

