Convert a vector of zeros and ones to groups

I have a vector of zeros and ones, for example:

x <- c(0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,1)

I need to convert this vector to another form:

c(0,0,1,1,1,0,0,0,0,2,2,2,0,0,3)

where subsequent natural numbers will indicate the number of blocks of "units" from the original vector at the positions of this block. Basically I need a solution that will be quickly calculated (the vector x will usually be at least> 30k in length, and there will be so many vectors in one run).

Any ideas that are not related to for for loops?

+4
source share
2 answers

We can use rle

inverse.rle(within.list(rle(x), values[values!=0] <- seq_along(values[values!=0])))
#[1] 0 0 1 1 1 0 0 0 0 0 2 2 2 0 0 3

Another option is rleidfromdata.table

library(data.table)
cumsum(!duplicated(rleid(x)) & x!=0)*x
#[1] 0 0 1 1 1 0 0 0 0 0 2 2 2 0 0 3
+3
source

, . , @akrun, , .

replace(x, x!=0, cumsum(diff(c(0,x)==1)[x!=0]) )
# [1] 0 0 1 1 1 0 0 0 0 0 2 2 2 0 0 3

, , :

replace(x, x!=0, factor(cumsum(x==0)[x!=0]) )
# [1] 0 0 1 1 1 0 0 0 0 0 2 2 2 0 0 3
+4

All Articles