在R中不重排数据框实现数据平衡的方法及被删行号定位
问题与解决方案
问题描述
原始数据集:
df <- data.frame( "stim" = c("face", "object", "pareidolia", "face", "face", "object", "pareidolia", "object"), "RT" = c(23, 24, 25, 26, 27, 22, 25, 23), "Opac" = c(70, 60, 80, 65, 60, 61, 59, 70) )
目标是让每个stim分组的样本数相等,尝试了以下dplyr代码:
library(dplyr) newdf <- df %>% mutate(mn = min(table(stim))) %>% group_by(stim) %>% sample_n(mn[1]) %>% ungroup()
但代码会打乱原始数据顺序:
- 期望输出(按原始顺序保留各分组的前N条,N为最小分组数):
stim RT Opac face 23 70 object 24 60 pareidolia 25 80 face 26 65 object 22 61 pareidolia 25 59
- 实际输出(分组内聚合,顺序被打乱):
stim RT Opac face 23 70 face 26 65 object 24 60 object 22 61 pareidolia 25 80 pareidolia 25 59
同时需要解决附加问题:如何确定被裁剪数据的行号?
解决方案
1. 保持原始顺序的分组下采样
核心思路是给每个分组内的行编号,筛选出编号≤最小分组数的行,最后按原始行号排序:
library(dplyr) # 计算最小分组样本数 min_count <- df %>% count(stim) %>% pull(n) %>% min() newdf <- df %>% mutate(row_id = row_number()) %>% # 保留原始行号 group_by(stim) %>% mutate(group_row = row_number()) %>% # 分组内按原始顺序编号 filter(group_row <= min_count) %>% # 筛选每个分组的前min_count条 ungroup() %>% arrange(row_id) %>% # 还原原始数据顺序 select(-row_id, -group_row) # 移除辅助列 print(newdf)
运行后输出会与期望一致,既保证了每个分组样本数相等,又保留了原始数据的顺序。
2. 获取被裁剪的行号
基于上述逻辑,通过对比原始行号与保留行号的差异,即可得到被删除的行编号:
# 先执行预处理保留行号信息 temp_df <- df %>% mutate(row_id = row_number()) %>% group_by(stim) %>% mutate(group_row = row_number()) %>% filter(group_row <= min_count) %>% ungroup() # 计算被裁剪的行号 removed_rows <- setdiff(df$row_id, temp_df$row_id) print(removed_rows) # 输出:5(对应原始数据中第5行的face,RT=27,Opac=60)
内容的提问来源于stack exchange,提问作者thefriendly_plague.doctor
相关产品推荐
相关产品推荐

