如何按组提取indicator为TRUE行及之后首次value变更的行?
按分组提取指定行的实现方案
原始数据
我们有如下名为df的DataFrame:
df <- structure(list(group = c("A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B", "B"), date = structure(c(1667260800, 1667268000, 1667271600, 1667275200, 1667278800, 1667282400, 1667293200, 1667300400, 1667260800, 1667264400, 1667268000, 1667278800, 1667282400, 1667286000, 1667296800, 1667304000), class = c("POSIXct", "POSIXt" ), tzone = ""), indicator = c(FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE), value = c(2, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2)), row.names = c(NA, -16L), class = "data.frame")
需求说明
按group分组,完成两个提取操作:
- 提取每个组中
indicator == TRUE的行 - 提取该行之后第一个value与TRUE行的value不相等的行
最终期望输出df_desired:
df_desired <- structure(list(group = c("A", "A", "B", "B"), date = c("2022-11-01 06:00:00", "2022-11-01 10:00:00", "2022-11-01 06:00:00", "2022-11-01 11:00:00" ), indicator = c(TRUE, FALSE, TRUE, FALSE), value = c(1, 2, 1, 2)), class = "data.frame", row.names = c(NA, -4L))
解决方案
使用dplyr包的分组操作可以高效实现需求,代码如下:
library(dplyr) result <- df %>% group_by(group) %>% # 存储当前组中indicator为TRUE的行的value值 mutate(true_value = value[indicator == TRUE]) %>% # 筛选目标行:indicator为TRUE的行,以及TRUE行后第一个value不同的行 filter(indicator == TRUE | (row_number() > which(indicator == TRUE) & value != true_value & row_number() == min(row_number()[row_number() > which(indicator == TRUE) & value != true_value]))) %>% # 移除临时辅助列 select(-true_value) %>% ungroup() # 查看结果 print(result)
代码逻辑说明
group_by(group):按group字段分组,确保每个组独立处理mutate(true_value = value[indicator == TRUE]):为每个组添加临时列,记录该组中indicator == TRUE行的valuefilter()核心筛选:- 直接保留
indicator == TRUE的行 - 筛选满足三个条件的行:行号在TRUE行之后、value不等于
true_value、是满足前两个条件的第一行(通过min(row_number())取最小行号)
- 直接保留
select(-true_value):清理临时辅助列ungroup():取消分组状态,恢复普通DataFrame结构
运行代码后,输出结果与df_desired完全一致。
内容的提问来源于stack exchange,提问作者Quinten
相关产品推荐
相关产品推荐

