r - More elegant way to return a sequence of numbers based on booleans? -
here's sample of booleans have part of data.frame:
atest <- c(false, true, true, true, true, true, true, true, true, true, false, true, true, true, true, true, true, true, true, true, false)
i want return sequence of numbers starting @ 1 each false , increasing 1 until next false.
the resulting desired vector is:
[1] 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1
here's code accomplishes this, i'm sure there's simpler or more elegant way in r. i'm trying learn how code things more efficiently in r rather getting job done.
result <- c() x <- 1 for(i in 1:length(atest)){ if(atest[i] == false){ result[i] <- 1 x <- 1 } if(atest[i] != false){ x <- x+1 result[i] <- x } }
here's 1 way it, using handy (but not widely-known/used) base functions:
> sequence(tabulate(cumsum(!atest))) [1] 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1
to break down:
> # return/repeat integer each false > cumsum(!atest) [1] 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 > # count number of occurrences of each integer > tabulate(cumsum(!atest)) [1] 10 10 1 > # create concatenated seq_len each integer > sequence(tabulate(cumsum(!atest))) [1] 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1
Comments
Post a Comment