在R语言中如何按条件随机删除指定比例行以调整数据分布?
R语言实现按比例随机删除行以控制性别和岗位占比
核心思路
先通过随机抽样控制男性占比不超过50%,再在结果集中进一步控制管理岗占比不超过50%,同时最大化保留样本量。
代码实现
1. 加载依赖包与模拟测试数据
library(dplyr) # 设置随机种子保证结果可复现 set.seed(123) # 模拟符合初始占比的数据集(1000条样本) df <- tibble( gender = sample(c("男", "女"), size = 1000, replace = TRUE, prob = c(0.6, 0.4)), position = sample(c("管理岗", "非管理岗"), size = 1000, replace = TRUE, prob = c(0.85, 0.15)) )
2. 查看初始数据占比
# 性别占比 df %>% count(gender) %>% mutate(percent = round(n / sum(n) * 100, 1)) # 岗位占比 df %>% count(position) %>% mutate(percent = round(n / sum(n) * 100, 1))
3. 分步筛选控制占比
# 第一步:控制男性占比≤50% female_count <- sum(df$gender == "女") # 目标男性数量:等于女性数量(刚好达到50%上限) target_male <- female_count # 随机抽取对应数量的男性 male_sample <- df %>% filter(gender == "男") %>% sample_n(size = min(target_male, n())) # 合并女性与抽选的男性 gender_filtered <- bind_rows(df %>% filter(gender == "女"), male_sample) # 第二步:在性别筛选结果中控制管理岗占比≤50% non_manager_count <- sum(gender_filtered$position == "非管理岗") # 目标管理岗数量:等于非管理岗数量(刚好达到50%上限) target_manager <- non_manager_count # 随机抽取对应数量的管理岗 manager_sample <- gender_filtered %>% filter(position == "管理岗") %>% sample_n(size = min(target_manager, n())) # 合并非管理岗与抽选的管理岗 final_df <- bind_rows(gender_filtered %>% filter(position == "非管理岗"), manager_sample)
4. 验证最终结果占比
# 最终性别占比 final_df %>% count(gender) %>% mutate(percent = round(n / sum(n) * 100, 1)) # 最终岗位占比 final_df %>% count(position) %>% mutate(percent = round(n / sum(n) * 100, 1))
说明
- 如果希望男性/管理岗占比低于50%,只需调整
target_male或target_manager的数值(比如设为floor(female_count * 0.9)) sample_n()函数会自动处理“目标数量大于现有数量”的情况,此时会保留所有对应行
内容的提问来源于stack exchange,提问作者LanCan
相关产品推荐
相关产品推荐

