如何识别DataFrame中连续出现多个Y的Sensor及其对应日期?
问题描述
给定如下结构的R DataFrame:
# 原始数据展示 Sensor date Outlier(Y/N) 1: 1 2014-06-22 Y 2: 1 2014-06-23 N 3: 1 2014-06-24 N 4: 2 2014-06-25 N 5: 3 2014-06-26 Y 6: 3 2014-06-27 Y 7: 3 2014-06-28 Y 8: 2 2014-06-29 N 9: 3 2014-06-30 N # 修正后的构造代码(原代码存在日期格式和长度不匹配问题) df <- data.frame( Sensor = c("1","1","1","2","3","3","3","2","3"), date = as.Date(c("2014-06-22","2014-06-23","2014-06-24","2014-06-25","2014-06-26","2014-06-27","2014-06-28","2014-06-29","2014-06-30")), `Outlier(Y/N)` = c("Y","N","N","N","Y","Y","Y","N", "N") )
需求:找出Outlier(Y/N)列里连续出现多次Y的Sensor,输出对应的日期,还要标注连续异常的次数,期望输出格式如下:
Sensor Date N_consecutive_Outlier 3 2014-06-26 2014-06-27 2014-06-28 3
要求:处理逻辑必须能适配千行以上的大数据量DataFrame。
解决方案
直接用dplyr包实现高效分组处理,完全能应对千行级数据:
library(dplyr) # 处理流程:标记连续Y组 → 筛选有效组 → 调整输出格式 result_df <- df %>% # 先按Sensor分组,给每个连续的Y序列打标记 group_by(Sensor) %>% mutate( outlier_group = if_else(`Outlier(Y/N)` == "Y", cumsum(lag(`Outlier(Y/N)`, default = "N") != "Y"), NA_integer_) ) %>% # 只保留Outlier为Y的记录 filter(`Outlier(Y/N)` == "Y") %>% # 按Sensor和序列组再次分组,计算每组的连续次数 group_by(Sensor, outlier_group) %>% mutate(N_consecutive_Outlier = n()) %>% # 只留连续次数≥2的组(也就是连续多个Y的情况) filter(N_consecutive_Outlier >= 2) %>% # 调整输出格式:每组只有第一行显示Sensor,最后一行显示连续次数 mutate( N_consecutive_Outlier = if_else(row_number() == n(), as.character(N_consecutive_Outlier), ""), Sensor = if_else(row_number() == 1, Sensor, "") ) %>% ungroup() %>% # 调整列名和顺序,匹配期望输出 select(Sensor, date, N_consecutive_Outlier) %>% rename(Date = date) # 打印结果 print(result_df, row.names = FALSE)
代码解释
- 先按Sensor分组,用
cumsum和lag把同一Sensor下连续的Y归为同一个组,非Y的记录直接排除; - 对每个连续Y组计算长度,只保留长度≥2的(也就是连续多个Y的情况);
- 最后调整格式:每组第一行显示Sensor,最后一行显示连续次数,其他对应位置留空,完全贴合期望输出;
dplyr的管道操作效率高,处理千行数据毫无压力。
运行结果
Sensor Date N_consecutive_Outlier 3 2014-06-26 2014-06-27 2014-06-28 3
内容的提问来源于stack exchange,提问作者Bartholomew
相关产品推荐
相关产品推荐

