4

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 
Maxwell Chandler
  • 626
  • 8
  • 18

5 Answers5

6

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.

Rich Scriven
  • 97,041
  • 11
  • 181
  • 245
6
#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
d.b
  • 32,245
  • 6
  • 36
  • 77
2

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
acylam
  • 18,231
  • 5
  • 36
  • 45
2

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
akrun
  • 874,273
  • 37
  • 540
  • 662
2

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
BENY
  • 317,841
  • 20
  • 164
  • 234
  • 2
    `TF == FALSE` is more simply `!TF`. Also, assigning `cumsum(!TF)` first would be more efficient since you won't need to calculate it twice. – Rich Scriven Sep 28 '17 at 20:09
  • @RichScriven yeah , that is great suggestion , thank you !! :) – BENY Sep 28 '17 at 20:13