R语言无放回采样出现重复行及动态数据框分配问题
问题原因
这不是R或dplyr的已知Bug,问题出在代码逻辑:replace=FALSE仅保证单次采样的结果无重复,你每次循环都是从完整的原始df中采样,没有移除之前循环已经抽走的行,所以自然会出现同一行出现在多个分组的情况。
修复方案
需要同时满足「所有分组无重复行」「每个分组固定2名女性、其余为男性」的要求,核心逻辑为:先将原始数据按性别拆分出独立的采样池,每次采样后从对应池子中移除已选行,最后将分组结果存入预定义的列表即可。
可运行代码示例
library(dplyr) # 构造示例数据,可替换为你的真实数据 df <- data.frame( name = c("arjun","Andrea", "Biswas","Ann","Biju", "Sheela","Deepti","Betty", "Hema", "Gowri","Kunal", "Anamika","Ashik", "Hina","Kiran"), gender = c("M","F", "M","M","F", "M","F","F","F", "F","M","F", "F","F","M"), # 模拟5个附加列,真实数据会自动保留 col1 = rnorm(15), col2 = rnorm(15), col3 = rnorm(15), col4 = rnorm(15), col5 = rnorm(15) ) # 配置参数,可根据你的需求调整 n_group <- 7 # 要拆分的分组数量 per_group_female <- 2 # 每个分组的女性人数 per_group_total <- 3 # 每个分组的总人数 per_group_male <- per_group_total - per_group_female # 预拆分男女采样池,避免每次循环重复筛选 female_pool <- df %>% filter(gender == "F") male_pool <- df %>% filter(gender == "M") # 预定义存储结果的列表 result_list <- vector("list", n_group) for (i in 1:n_group) { # 采样前检查剩余样本是否满足要求,避免报错 if(nrow(female_pool) < per_group_female | nrow(male_pool) < per_group_male) { stop("剩余样本不足,无法满足分组规则,请调整参数") } # 分别从男女池采样对应人数 selected_female <- female_pool %>% slice_sample(n = per_group_female, replace = FALSE) selected_male <- male_pool %>% slice_sample(n = per_group_male, replace = FALSE) # 合并为当前分组的数据集 current_group <- bind_rows(selected_female, selected_male) # 存入结果列表 result_list[[i]] <- current_group # 从采样池中移除已选行,彻底避免重复 female_pool <- anti_join(female_pool, selected_female, by = "name") male_pool <- anti_join(male_pool, selected_male, by = "name") } # 给列表元素命名,对应你需要的df1、df2...格式 names(result_list) <- paste0("df", 1:n_group) # 如果需要把分组数据释放为全局环境的独立数据框(可选,更推荐直接操作列表做批量处理) list2env(result_list, envir = .GlobalEnv)
注意事项
- 如果你的数据存在重名情况,把
anti_join的by参数改为所有能唯一标识行的列即可,也可以用行索引匹配实现去重 - 运行前请先确认总女性人数 ≥ 分组数2、总男性人数 ≥ 分组数每组男性人数,否则会触发样本不足的报错
内容的提问来源于stack exchange,提问作者Satish Kumar
相关产品推荐
相关产品推荐

