R语言如何简化重写代码实现等经验组均等分布抽样
简化R代码实现均等分层抽样
需求说明
需要从4个工作经验年限组(1-4年工作经验)中按规则抽取均等分布的样本,规则如下:
- 从最高年限组(4年经验)随机抽取2人
- 次高年限组(3年经验)从未被更高组选中的人员里随机抽2人
- 以此类推,更低年限组抽样时全部排除已被选中的人员id
- 最低年限组(1年经验)取所有未被前序分组选中的对应人员
- 输出结果和原有冗余代码的逻辑、输出结构完全一致
简化后代码
library(tidyverse) # 原始数据集构造(和原代码完全一致) data <- tibble( id = c("A","A","A","B","B","C","C","D","D","D","D","E","E","E","E","F","F","G","G","G","H","H","H","H"), year_exp = c(1,2,3,1,2,1,2,1,2,3,4,1,2,3,4,1,2,1,2,3,1,2,3,4), pre_year_exp = year_exp - 1 ) # 按工作年限从高到低拆分分组 exp_groups <- data %>% group_nest(year_exp) %>% arrange(desc(year_exp)) # 迭代抽样,累积维护已选人员id池 selected_ids <- c() result <- map_dfr(exp_groups$data, ~{ # 过滤掉已经被选中的人员 valid_set <- .x %>% filter(!id %in% selected_ids) # 前3个高年限组每组抽2人,最后1组取全部剩余(完全匹配原代码逻辑) sampled <- if(nrow(valid_set) > 2) sample_n(valid_set, 2) else valid_set # 更新已选id池 selected_ids <<- c(selected_ids, sampled$id) sampled }) result
逻辑说明
- 彻底去掉了原代码中重复拼接
anti_join的冗余写法,改用累积更新已选id池的方式实现跨组去重,不管后续增加多少个年限分组,代码结构都不需要调整 - 抽样顺序、抽样数量、去重规则和原代码100%对齐,输出的数据结构、列名和原结果完全一致
- 用
purrr::map_dfr做迭代,直接输出合并好的最终结果表,不需要手动逐组赋值再bind_rows
内容的提问来源于stack exchange,提问作者Byeong Hyeon So
相关产品推荐
相关产品推荐

