Search code examples
rloopsrep

Sequences of varying length in R


My question is simple but still I haven't been able to find the solution online.

I have a vector, e.g. a = c(7,3,5). I need to convert it to b = c(0,1,2,3,4,5,6,0,1,2,0,1,2,3,4). I can do that with a loop, but its notoriously slow when length(a) > 500000.

m <- 0
n <- 0
for (i in 1:length(a)) {
  m <- n+1;
  n <- n+a[i];

  b[m:n] <- (0:(a[i]-1));
}

Is there a one-liner in R that can produce the described behaviour really fast? Can that same approach convert vector a into c = c(0,0,0,0,0,0,1,0,0,1,0,0,0,0,1)?


Solution

  • Several options in the comments, but not one posted in the answer area, so while the hunt for a possible duplicate is on, here's a consolidation of what we have so far. The most direct/logical alternative for each option is listed first.

    ## To get your first vector
    sequence(a) - 1                                              # @Henrik
    ave(1:sum(a), rep(seq_along(a), a), FUN = seq_along) - 1     # @akrun
    
    ## To get your second vector
    tabulate(cumsum(a))                                          # @alexis_laz
    { x <- integer(sum(a)) ; x[cumsum(a)] <- 1; x }              # @DavidArenburg
    { x <- sequence(a) - 1 ; as.integer(c(diff(x) != 1, TRUE)) } # @Henrik
    sequence(a) %/% rep(a, a)                                    # @GL_Li
    

    This answer is Community Wikied, so feel free to edit and add alternatives.