如何用dplyr统计R数据框中连续的6 QC条目并分组命名
解决R中识别连续QC条目并分组命名的问题
好的,我来帮你搞定这个需求!要找出连续的6个QC值为"6"的条目(从你的数据来看,应该是指QC列等于"6"的连续行),并按顺序命名为Set 1、Set 2等,我们可以结合**游程编码(rle)**和数据处理工具来实现,下面是具体的步骤和代码:
步骤1:准备数据并确保时间顺序正确
首先,我们需要确保数据是按日期和小时桶的时间顺序排列的,因为原始的Hour_Bucket是字符串格式(比如"0-1"),直接排序可能会出问题,所以先提取起始小时来辅助排序:
# 如果用dplyr的话 library(dplyr) # 假设你的数据框名为df df <- df %>% mutate( # 提取小时桶的起始小时,用于正确排序 start_hour = as.numeric(substr(Hour_Bucket, 1, regexpr("-", Hour_Bucket)-1)), # 标记每行是否是目标QC条目(QC值为"6") is_target = QC == "6" ) %>% arrange(Date, start_hour) # 按日期和起始小时排序
步骤2:识别连续的目标条目组
接下来用rle()函数识别连续的目标条目(is_target为TRUE的行),然后筛选出长度≥6的连续组:
# 计算连续目标条目的游程信息 rle_result <- rle(df$is_target) # 找出所有符合条件的游程(连续6个及以上目标条目) valid_runs <- which(rle_result$values & rle_result$lengths >= 6) # 初始化Set列,默认值为NA df$Set <- NA_integer_ # 给每个有效游程分配Set编号 current_set <- 1 for (run in valid_runs) { # 计算当前游程的起始和结束行位置 start_pos <- sum(rle_result$lengths[1:(run-1)]) + 1 end_pos <- sum(rle_result$lengths[1:run]) # 为对应行设置Set编号 df$Set[start_pos:end_pos] <- current_set current_set <- current_set + 1 }
步骤3:(可选)筛选出有Set编号的行
如果你只需要保留属于某个Set的条目,可以用下面的代码过滤:
df_filtered <- df %>% filter(!is.na(Set))
用data.table实现更高效的处理(适合大数据)
如果你的数据量很大(比如10个月的每日24条数据,其实不算大,但习惯用data.table的话),可以用更简洁高效的写法:
library(data.table) setDT(df) # 处理排序和标记目标条目 df[, `:=`( start_hour = as.numeric(substr(Hour_Bucket, 1, regexpr("-", Hour_Bucket)-1)), is_target = QC == "6" )][order(Date, start_hour)] # 生成游程ID并计算每个游程的长度 df[, run_id := rleid(is_target)] df[, run_length := .N, by = run_id] # 筛选出符合条件的游程并分配Set编号 valid_runs <- unique(df[is_target & run_length >=6, run_id]) df[run_id %in% valid_runs, Set := match(run_id, valid_runs)]
说明
- 这里默认你要找的是连续6个及以上QC值为"6"的条目,如果你的需求是连续6个Type为QC的条目(但你的数据Type都是QC),只需要把
is_target = QC == "6"改成is_target = Type == "QC"即可。 - 连续超过6个的条目会被归为同一个Set(比如连续8个会全部标记为同一个Set编号),如果你需要每6个拆分一组,可以调整逻辑,但根据你的描述,应该是把连续的一段作为一个Set。
内容的提问来源于stack exchange,提问作者Neil
相关产品推荐
相关产品推荐

