Sequentially index between a boolean vector in R [

2019-06-27 17:05发布

This question already has an answer here:

The title 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 output

[1] 0 1 2 3 0 0 1 2 0 1 0 1 2 3 4 5 6 7 0 

标签: r seq
5条回答
贼婆χ
2楼-- · 2019-06-27 17:36

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
查看更多
在下西门庆
3楼-- · 2019-06-27 17:40

You can also use inverse.seqle from cgwtools:

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

Or similar to @d.b's 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
查看更多
何必那么认真
4楼-- · 2019-06-27 17:41

By using 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
查看更多
我欲成王,谁敢阻挡
5楼-- · 2019-06-27 17:56

You could use rle() along 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() does the coercion for us.

查看更多
贪生不怕死
6楼-- · 2019-06-27 17:57
#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
查看更多
登录 后发表回答