Here's a mixture of Josh and Ananda's solution, in this I use RLE to create the way Josh answered:
t <- rle(DT$name) t <- t$lengths[t$values == "a"] DT[, cd := rep(t, t+1)] DT[, cd:=max(.I) - .I, by=cd]
Even better: taking advantage of the fact that only one b always (or assuming here), you can do it better:
t <- rle(DT$name) t <- t$lengths[t$values == "a"] DT[, cd := rev(sequence(rev(t+1)))-1]
Edit: It can be seen from the OP comment that there are more than 1 b , and in such cases all b must be 0. The first step in this is to create groups where b ends after each consecutive a .
DT <- data.table(idx=sample(10), name=c("a","a","a","b","b","a","a","b","a","b")) t <- rle(DT$name) val <- cumsum(t$lengths)[t$values == "b"] DT[, grp := rep(seq(val), c(val[1], diff(val)))] DT[, val := c(rev(seq_len(sum(name == "a"))), rep(0, sum(name == "b"))), by = grp]
source share