More elegant way to return a sequence of numbers based on booleans?

前端 未结 3 1984
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-30 09:28

Here\'s a sample of booleans I have as part of a data.frame:

atest <- c(FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE,

3条回答
  •  失恋的感觉
    2020-12-30 09:49

    Here is another approach using other familiar functions:

    seq_along(atest) - cummax(seq_along(atest) * !atest) + 1L
    

    Because it is all vectorized, it is noticeably faster than @Joshua's solution (if speed is of any concern):

    f0 <- function(x) sequence(tabulate(cumsum(!x)))
    f1 <- function(x) {i <- seq_along(x); i - cummax(i * !x) + 1L}
    x  <- rep(atest, 10000)
    
    library(microbenchmark)
    microbenchmark(f0(x), f1(x))
    # Unit: milliseconds
    #   expr       min        lq    median        uq      max neval
    #  f0(x) 19.386581 21.853194 24.511783 26.703705 57.20482   100
    #  f1(x)  3.518581  3.976605  5.962534  7.763618 35.95388   100
    
    identical(f0(x), f1(x))
    # [1] TRUE
    

提交回复
热议问题