You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用dplyr按ID保留首次出现grade 5及之前的所有记录?

问题:按ID分组保留首次出现grade 5及之前的记录

示例数据集

ID   grade    date 
A     1        1/1/2001
A     3        1/2/2002 
A     5        2/4/2002
B     4        1/1/2008
B     4        1/1/2010
B     5        1/1/2011
B     5        1/3/2011
B     4        1/5/2011
C     2        1/1/2006
C     5        1/1/2007
C     5        1/1/2008
D     3        1/1/1996
D     5        1/1/1997
D     5        1/1/1999
E     1        1/1/2003
E     3        1/1/2005
E     3        1/1/2007

需求说明

按ID分组后,对每个ID执行以下规则:

  • 保留首次出现grade=5及之前的所有条目,忽略该条之后的所有记录
  • 若ID从未出现grade=5,则保留全部条目

期望输出

ID   grade    date 
A     1        1/1/2001
A     3        1/2/2002 
A     5        2/4/2002
B     4        1/1/2008
B     4        1/1/2010
B     5        1/1/2011
C     2        1/1/2006
C     5        1/1/2007
D     3        1/1/1996
D     5        1/1/1997
E     1        1/1/2003
E     3        1/1/2005
E     3        1/1/2007

解决方案(使用dplyr)

通过dplyr的分组定位+过滤逻辑可以实现需求,代码如下:

library(dplyr)

# 构建示例数据集(假设原数据集名为df)
df <- data.frame(
  ID = c("A", "A", "A", "B", "B", "B", "B", "B", "C", "C", "C", "D", "D", "D", "E", "E", "E"),
  grade = c(1, 3, 5, 4, 4, 5, 5, 4, 2, 5, 5, 3, 5, 5, 1, 3, 3),
  date = c("1/1/2001", "1/2/2002", "2/4/2002", "1/1/2008", "1/1/2010", "1/1/2011", "1/3/2011", "1/5/2011", "1/1/2006", "1/1/2007", "1/1/2008", "1/1/1996", "1/1/1997", "1/1/1999", "1/1/2003", "1/1/2005", "1/1/2007")
)

# 核心处理逻辑
result <- df %>%
  group_by(ID) %>%
  # 定位每个组内首次出现grade=5的行号,无则取组内总行数
  mutate(first_5_pos = ifelse(any(grade == 5), min(which(grade == 5)), n())) %>%
  # 保留首次grade=5及之前的所有行
  filter(row_number() <= first_5_pos) %>%
  # 清理临时辅助列并取消分组
  select(-first_5_pos) %>%
  ungroup()

print(result)

代码逻辑解释

  1. group_by(ID):按ID分组,确保每个ID的记录单独处理
  2. mutate(first_5_pos = ...):
    • 用any(grade == 5)判断当前组是否存在grade=5的记录
    • 存在则用min(which(grade == 5))取首次出现的行号;不存在则取组内总行数n()
  3. filter(row_number() <= first_5_pos):保留行号小于等于目标行号的所有记录
  4. select(-first_5_pos)与ungroup():删除临时计算列并取消分组,还原常规数据结构

内容的提问来源于stack exchange,提问作者tacrolimus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 22:20:29