使用dplyr按组计算截至最新日期的连续1序列长度
用dplyr统计每组从最新日期往前的连续1序列长度
先看示例数据:
df <- data.frame( Group = c("A","A","A","B","B","C","C","C"), Date = as.Date(c("2023-01-01","2023-01-02","2023-01-03","2023-01-01","2023-01-02","2023-01-01","2023-01-02","2023-01-03")), B = c(1,1,0,1,0,1,1,1) )
需求说明:按Group分组,从每组的最新日期(最大日期)往前数,统计连续出现1的长度,只要碰到0就停止计数;如果最新日期对应的B值是0,直接返回0。
实现代码
library(dplyr) result <- df %>% # 按组分组,每组内按日期降序排列(最新日期在前) group_by(Group) %>% arrange(desc(Date), .by_group = TRUE) %>% # 标记连续1的中断点:碰到0后,后续所有行都标记为已中断 mutate( is_break = cumsum(B == 0) > 0, # 未中断的位置记为1,中断的记为0 count = ifelse(is_break, 0, 1) ) %>% # 每组求和得到连续1的长度 summarise(continuous_ones = sum(count)) %>% ungroup() print(result)
代码逻辑解释
- 先按
Group分组,再把每组内的行按Date降序排列,让最新日期排在最前面,方便从开头就检查连续1的序列。 - 用
cumsum(B == 0) > 0标记中断:只要出现一个0,cumsum的结果就会变成1,后续所有行都会被标记为已中断。 - 未中断的行赋值为1,中断的赋值为0,最后每组求和,得到的就是从最新日期往前的连续1长度;如果最新日期的
B是0,第一行的count就是0,求和结果自然为0,完全匹配需求。
运行代码后输出:
# A tibble: 3 × 2 Group continuous_ones <chr> <dbl> 1 A 0 2 B 0 3 C 3
内容的提问来源于stack exchange,提问作者TheGoat
相关产品推荐
相关产品推荐

