dplyr按分组多阈值筛选行:按区域选取前20%药房的问题
按区域筛选销量前20%药房的正确实现方法
你遇到的核心问题是:在分组筛选时,没有将区域对应的阈值和当前分组匹配,导致所有区域都使用了第一个区域的阈值(248)。下面提供两种可行的解决方法:
方法一:手动匹配区域阈值(兼容旧版dplyr)
先给每个区域内的药房按销量排序并添加组内行号,再和阈值表关联后筛选:
# 确保ranked_pharmas已按区域分组、销量降序排序(未排序的话执行这步) ranked_pharmas <- ranked_pharmas %>% group_by(province) %>% arrange(desc(total_units), .by_group = TRUE) %>% mutate(province_rank = row_number()) # 关联阈值表并筛选前20%药房 top_20_pharma <- ranked_pharmas %>% left_join(spad_number_20_threshold, by = "province") %>% filter(province_rank <= Top_20_threshold) %>% # 按需移除辅助列 select(-province_rank, -Top_20_threshold)
方法二:用slice_head直接按比例筛选(dplyr 1.0.0+推荐)
如果你的dplyr版本在1.0.0及以上,slice_head支持按比例取分组内的头部数据,无需手动计算阈值,更简洁:
top_20_pharma <- ranked_pharmas %>% group_by(province) %>% arrange(desc(total_units), .by_group = TRUE) %>% slice_head(prop = 0.2)
为什么之前的代码失效?
slice(1:spad_number_20_threshold$Top_20_threshold)中,spad_number_20_threshold$Top_20_threshold是全局向量,分组操作不会自动匹配当前区域的对应值,只会取第一个元素。filter(row_number(...) <= first(...))里的first()是取整个阈值向量的第一个值,而非当前分组对应的阈值。
内容的提问来源于stack exchange,提问作者Olaf Odinn
相关产品推荐
相关产品推荐

