如何用R(优先dplyr)筛选Departure列符合指定连续模式的行?
用dplyr筛选Departure列符合连续"TRUE""FALSE""FALSE""FALSE"模式的行
需求说明
从给定数据集中,按ID分组后,筛选出Departure列连续出现TRUE→FALSE→FALSE→FALSE模式的所有对应行。
原始数据集
ID Departure Date A TRUE Jan 1 A FALSE Jan 2 A TRUE Jan 3 A FALSE Jan 4 A FALSE Jan 5 A FALSE Jan 6 A FALSE Jan 7 A TRUE Jan 8 A FALSE Jan 9 B TRUE Jan 1 B FALSE Jan 2 B FALSE Jan 3 B FALSE Jan 4 B TRUE Jan 5
对应的R数据结构:
data <- structure(list(ID = c("A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B"), Departure = c("TRUE", "FALSE", "TRUE", "FALSE", "FALSE", "FALSE", "FALSE", "TRUE", "FALSE", "TRUE", "FALSE", "FALSE", "FALSE", "TRUE"), Date = c("Jan 1", "Jan 2", "Jan 3", "Jan 4", "Jan 5", "Jan 6", "Jan 7", "Jan 8", "Jan 9", "Jan 1", "Jan 2", "Jan 3", "Jan 4", "Jan 5")), class = "data.frame", row.names = c(NA, -14L))
期望结果
ID Departure Date A TRUE Jan 3 A FALSE Jan 4 A FALSE Jan 5 A FALSE Jan 6 B TRUE Jan 1 B FALSE Jan 2 B FALSE Jan 3 B FALSE Jan 4
解决方案(优先使用dplyr)
可以通过按ID分组,结合lead()/lag()函数检测目标模式,标记并筛选符合条件的行,无需额外依赖其他包:
library(dplyr) result <- data %>% group_by(ID) %>% mutate( # 标记模式的起始行:当前行是TRUE,且后续3行都是FALSE match_start = Departure == "TRUE" & lead(Departure, 1) == "FALSE" & lead(Departure, 2) == "FALSE" & lead(Departure, 3) == "FALSE", # 标记需要保留的行:起始行及之后的3行都要保留 keep = match_start | lag(match_start, 1, default = FALSE) | lag(match_start, 2, default = FALSE) | lag(match_start, 3, default = FALSE) ) %>% filter(keep) %>% select(-match_start, -keep) %>% ungroup() print(result)
代码逻辑说明
group_by(ID):确保每个ID组内独立检测模式,避免跨ID匹配。match_start列:标记出符合模式的起始行(即连续4行的第一行)。keep列:将起始行及其后3行都标记为需要保留,覆盖整个模式的4行数据。- 最后筛选出
keep为TRUE的行,移除辅助列后得到目标结果。
如果习惯用滑动窗口工具,也可以搭配slider包实现,代码逻辑更直观:
library(dplyr) library(slider) result <- data %>% group_by(ID) %>% mutate( # 滑动窗口检测4行是否匹配目标模式 match_pattern = slide_lgl( Departure, ~ all(.x == c("TRUE", "FALSE", "FALSE", "FALSE")), .before = 0, .after = 3, .complete = TRUE ), # 标记所有属于匹配模式的行 keep = any(match_pattern | lead(match_pattern, 1) | lead(match_pattern, 2) | lead(match_pattern, 3)) ) %>% filter(keep) %>% select(-match_pattern, -keep) %>% ungroup() print(result)
内容的提问来源于stack exchange,提问作者Cam
相关产品推荐
相关产品推荐

