Мы можем сделать двойное cumsum
после группировки по 'ID' и затем взять lag
вывода
library(dplyr)
ov27 %>%
group_by(ID) %>%
mutate(counter2 = lag(cumsum(cumsum(STOf == 1)), default = 0))
# A tibble: 9 x 5
# Groups: ID [2]
# ID YEAR STOf counter counter2
# <int> <int> <int> <int> <dbl>
#1 1 2000 0 0 0
#2 1 2001 1 0 0
#3 1 2002 0 1 1
#4 1 2003 0 2 2
#5 2 2000 0 0 0
#6 2 2001 0 0 0
#7 2 2002 1 0 0
#8 2 2003 0 1 1
#9 2 2004 0 2 2
Или создать логическое условие и применить cumsum
один раз
ov27 %>%
group_by(ID) %>%
mutate(counter2 = cumsum(row_number() > match(1, STOf)))
Если совпадений нет, т. Е. В группе нет единиц, укажите nomatch = n()
ov27 %>%
group_by(ID) %>%
mutate(counter2 = cumsum(row_number() > match(1, STOf, nomatch = n())))
ПРИМЕЧАНИЕ. Оба метода также работают, если в группе нет совпадений
Или используя те же логи c с data.table
library(data.table)
setDT(ov27)[, counter2 := cumsum(seq_len(.N) > match(1, STOf)), ID]
data
ov27 <- structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), YEAR = c(2000L,
2001L, 2002L, 2003L, 2000L, 2001L, 2002L, 2003L, 2004L), STOf = c(0L,
1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L), counter = c(0L, 0L, 1L, 2L,
0L, 0L, 0L, 1L, 2L)), class = "data.frame", row.names = c(NA,
-9L))