R语言按ID分组统计response列连续1序列并生成分组编号
实现方案
核心逻辑
- 不要同时按id和response分组,这会把同id下所有的1合并计算,导致连续段识别错误
- 仅按
id分组后,先识别每一段连续1的起始位置:当前行response为1、且前一行response为0 - 对起始位置做累积和,得到每段连续1的递增编号,最后将response为0的行编号替换为0即可
完整可运行代码
library(dplyr) # 示例数据 df1 <- data.frame(row = c(1:13), date = seq.Date(as.Date("2021-10-06"), as.Date("2021-10-18"), "day"), id = rep("A", times = 13), response = c(1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0), want_group = c(1, 0, 2, 0, 0, 3, 3, 3, 3, 0, 4, 0, 0) ) df2 <- data.frame(row = c(14:26), date = seq.Date(as.Date("2021-10-06"), as.Date("2021-10-18"), "day"), id = rep("B", times = 13), response = c(0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1), want_group = c(0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 2, 2, 2) ) df <- rbind(df1, df2) # 计算目标分组列 df_result <- df %>% group_by(id) %>% mutate( # 标记连续1段的起始位置,default=0处理每个id第一行是1的边界情况 new_block = response == 1 & lag(response, default = 0) == 0, # 累积和得到连续段编号 group_id = cumsum(new_block), # 0值行编号重置为0 group_id = ifelse(response == 0, 0, group_id) ) %>% ungroup() # 如果需要额外计算每段内的累积计数(你期望的cs_res效果),追加以下逻辑 df_result <- df_result %>% group_by(id, group_id) %>% mutate(cs_res = ifelse(group_id == 0, 0, sequence(n()))) %>% ungroup()
结果验证
输出的group_id和你示例中的want_group完全一致,cs_res也符合按段累计的要求。
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

