如何在R语言中筛选包含start和pass的id配对行?
R语言筛选包含start和pass的配对行解决方案
你的原代码错误在于filter(PorF == "start" & PorF == "pass")——单一行的PorF不可能同时等于两个不同的值,因此这个条件永远不成立,返回空结果。
以下是两种可行的解决方案:
方法一:基于配对组标识筛选
先为每个id内的start-pass/fail配对创建分组标识,再筛选包含start和pass的配对组:
library(dplyr) filtered_testdf <- testdf %>% group_by(id) %>% # 用cumsum标记每个start开始的新配对组 mutate(pair_id = cumsum(PorF == "start")) %>% group_by(id, pair_id) %>% # 筛选组内同时包含start和pass的配对 filter(all(c("start", "pass") %in% PorF)) %>% ungroup() %>% # 移除临时创建的配对标识列 select(-pair_id) print(filtered_testdf)
运行结果:
# A tibble: 6 × 3 id PorF timest <dbl> <chr> <dttm> 1 2 start 2021-05-28 08:17:09 2 2 pass 2021-05-28 08:17:25 3 1 start 2021-05-28 08:32:07 4 1 pass 2021-05-28 08:32:12 5 3 start 2021-05-28 08:33:14 6 3 pass 2021-05-28 08:33:45
方法二:基于相邻行关联筛选
通过lead()和lag()函数关联start与对应的结果行,直接筛选符合条件的行:
library(dplyr) filtered_testdf <- testdf %>% group_by(id) %>% # 标记当前行的下一行PorF值 mutate(next_PorF = lead(PorF)) %>% # 筛选两种情况:当前是start且下一行是pass,或者当前是pass且上一行是start filter((PorF == "start" & next_PorF == "pass") | (PorF == "pass" & lag(PorF) == "start")) %>% ungroup() %>% # 移除临时列 select(-next_PorF) print(filtered_testdf)
这个方法直接定位start-pass的连续配对行,同样能得到预期结果。
内容的提问来源于stack exchange,提问作者JontroPothon
相关产品推荐
相关产品推荐

