如何用更简洁的dplyr方法按比例过滤向量中的负值?
简洁优雅的dplyr实现:保留正值与最后1/3负值
给定包含有序正负值的向量:
x <- c(-35, -30, -25, -20, -15, -10, -5, -2, -1, -0.5, 0, 5, 22, 77)
需求:保留所有正值与0,仅保留最后1/3的负值。原解决方案逻辑繁琐,以下是更简洁的dplyr实现方式。
优化后的代码
library(dplyr) tibble(x) %>% mutate(is_neg = x < 0) %>% group_by(is_neg) %>% filter(!is_neg | row_number() > n() - ceiling(n()/3)) %>% ungroup()
逻辑说明
- 用
is_neg标记所有负值元素 - 按是否为负值分组:
- 非负值组(正值、0)直接全部保留
- 负值组内通过
row_number() > n() - ceiling(n()/3)筛选出最后ceiling(n()/3)个负值(ceiling向上取整,保证结果和原示例一致)
原方案对比
原方案通过生成x_neg、id、x_neg_length等多个辅助列实现筛选,步骤冗余。优化后的方案直接通过分组+行号筛选,代码更简洁易读,逻辑更直观。
内容的提问来源于stack exchange,提问作者Chris Ruehlemann
相关产品推荐
相关产品推荐

