如何在 R 中重置为 0 时执行 cumsum?

How to perform cumsum with reset at 0 in R?

我有一个table,我想获得一个组内的累计总和(按ID),但是如果在一个组内的任何一点计数器为0,则累计计数应该重置,然后再次启动从 1 开始的累计计数。

ID  Counter  Cumulative       
A  1         1
A  0         0              
A  1         1                
A  1         2                
B  1         1                 
B  0         0                
B  1         1    

创建一个临时组列,每次遇到 0 时创建一个新组。

library(dplyr)

df %>%
  group_by(ID, grp = cumsum(Counter == 0)) %>%
  mutate(Cumulative = cumsum(Counter)) %>%
  ungroup() %>%
  select(-grp) -> result

result

#  ID    Counter Cumulative
#  <chr>   <int>      <int>
#1 A           1          1
#2 A           0          0
#3 A           1          1
#4 A           1          2
#5 B           1          1
#6 B           0          0
#7 B           1          1

相同的逻辑可以在 base R 和 data.table 中实现为:

df$Cumulative <- with(df, ave(Counter, ID, cumsum(Counter == 0), FUN = cumsum))

library(data.table)
setDT(df)[, Cumulative := cumsum(Counter), .(ID, cumsum(Counter == 0))]

数据

df <- structure(list(ID = c("A", "A", "A", "A", "B", "B", "B"), Counter = c(1L, 
0L, 1L, 1L, 1L, 0L, 1L)), class = "data.frame", row.names = c(NA, -7L))

另一种方法可以是

df %>% group_by(ID) %>%
  mutate(cs = accumulate(Counter, ~ifelse(.y == 0, .y, .x + .y)))

根据亲爱的@Ronak 在他的评论中提供的数据检查它

df <- structure(list(ID = c("A", "A", "A", "A", "A", "B", "B", "B"), Counter = c(1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L)), class = "data.frame", row.names = c(NA, -8L))

df %>% group_by(ID) %>%
  mutate(cs = accumulate(Counter, ~ifelse(.y == 0, .y, .x + .y)))

# A tibble: 8 x 3
# Groups:   ID [2]
  ID    Counter    cs
  <chr>   <int> <int>
1 A           1     1
2 A           0     0
3 A           1     1
4 A           1     2
5 A           1     3
6 B           1     1
7 B           0     0
8 B           1     1