基于唯一ID筛选DataFrame:确保提交数递增时日期不递减
解决方法:用dplyr + purrr实现递增序列筛选
看起来你需要的是对每个id筛选出提交数(submissions)递增且对应日期(date)非递减的行,也就是保留那些能形成“submissions越大,date越晚”的有效链的行。之前用group_by()+filter()没成功是因为单纯的过滤没法跟踪前面行的状态,我们需要结合排序、累计计算来实现。
具体步骤和代码
假设你的数据框叫df,可以用dplyr分组排序,再用purrr的accumulate()函数跟踪每个id下需要满足的最小日期,最后筛选出符合条件的行:
library(dplyr) library(purrr) # 处理数据 filtered_df <- df %>% # 按id分组 group_by(id) %>% # 先按submissions升序排列,确保从最小的提交数开始检查 arrange(submissions, .by_group = TRUE) %>% mutate( # 累计计算当前需要满足的最小日期:如果当前date≥之前的要求,就更新为当前date;否则保持原阈值 min_required_date = accumulate(date, ~ ifelse(.y >= .x, .y, .x)), # 只有当前date等于min_required_date时,说明这一行符合「提交数更大且日期不早于之前有效行」的要求 keep = date == min_required_date ) %>% # 筛选出需要保留的行 filter(keep) %>% # 移除临时计算的列 select(-min_required_date, -keep) %>% # 按id和date排序,匹配你期望的结果格式 arrange(id, date) %>% # 取消分组(可选,根据后续需求调整) ungroup()
代码解释
- 分组排序:先按
id分组,再按submissions升序排列,这样我们能从每个id的最小提交数开始逐步验证。 - 累计跟踪最小日期:
accumulate()函数会遍历date列,每次判断当前日期是否≥之前的有效日期阈值,如果是就更新阈值,否则保持原阈值——这就确保了后续行必须满足日期不早于之前所有有效行的日期。 - 筛选有效行:只有当当前日期等于
min_required_date时,说明这一行是符合“提交数递增且日期不晚”要求的,保留这些行即可。
运行这段代码后,你会得到和示例完全一致的结果:
| id | status | submissions | date |
|---|---|---|---|
| 1 | offline | 1 | 2017 |
| 1 | online | 2 | 2018 |
| 2 | offline | 1 | 2006 |
| 2 | online | 4 | 2018 |
内容的提问来源于stack exchange,提问作者tsiantix
相关产品推荐
相关产品推荐

