Sequential index between a boolean vector in R

The name says it.

my vector

TF <- c(F,T,T,T,F,F,T,T,F,T,F,T,T,T,T,T,T,T,F)

my desired result

[1] 0 1 2 3 0 0 1 2 0 1 0 1 2 3 4 5 6 7 0 
+4
source share
5 answers
#with(rle(TF), sequence(lengths) * rep(values, lengths))
with(rle(TF), sequence(lengths) * TF) #Like Rich suggested in comments
# [1] 0 1 2 3 0 0 1 2 0 1 0 1 2 3 4 5 6 7 0
+6
source

You can use rle()with sequence().

replace(TF, TF, sequence(with(rle(TF), lengths[values])))
# [1] 0 1 2 3 0 0 1 2 0 1 0 1 2 3 4 5 6 7 0

replace() coercion works for us.

+6
source

You can also use inverse.seqlefrom cgwtools:

library(cgwtools)
SEQ = inverse.seqle(rle(TF)) 
SEQ[!TF] = 0

Or similar to @db answer:

inverse.seqle(rle(TF))*TF

# [1] 0 1 2 3 0 0 1 2 0 1 0 1 2 3 4 5 6 7 0
+2
source

We can use rleid

library(data.table)
ave(TF, rleid(TF), FUN = seq_along)*TF
#[1] 0 1 2 3 0 0 1 2 0 1 0 1 2 3 4 5 6 7 0
+2
source

Using the base R

ave(cumsum(TF==FALSE), cumsum(TF==FALSE), FUN=seq_along)-1
 [1] 0 1 2 3 0 0 1 2 0 1 0 1 2 3 4 5 6 7 0
+2
source

Source: https://habr.com/ru/post/1686581/


All Articles