Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R convert vector of numbers to skipping indexes

Tags:

r

I have a vector of widths,

ws = c(1,1,2,1,3,1)

From this vector I'd like to have another vector of this form:

indexes = c(1,2,3,5,6,7,9,11,12)

In order to create such vector I did the following for loop in R:

ws = c(1,1,2,1,3,1)
indexes = rep(0, sum(ws))
counter = 1
counter2 = 1
last = 0
for(i in 1:length(ws))
{
  if (ws[i] == 1)
  {
    indexes[counter] = counter2
    counter = counter + 1
  } else {
    for(j in 1:ws[i])
    {
      indexes[counter] = counter2
      counter = counter + 1
      counter2 = counter2+2
    }
    counter2 = counter2 - 2
  }
  counter2 = counter2+1
}

The logic is as follows, each element in ws specifies the respective number of elements in index. For example if ws is 1, the respective number of elements in indexes is 1, but if ws is > 1, let us say 3, the respective number of elements in index is 3, and the elements are skipped 1-by-1, corresponding to 3,5,7.

However, I'd like to avoid for loops since they tend to be very slow in R. Do you have any suggestions on how to achieve such results only with vector operations? or some more crantastic solution?

Thanks!

like image 597
Dnaiel Avatar asked Sep 24 '13 20:09

Dnaiel


1 Answers

Here's a vectorized one-liner for you:

ws <- c(1,1,2,1,3,1)

cumsum((unlist(sapply(ws, seq_len)) > 1) + 1)
# [1]  1  2  3  5  6  7  9 11 12

You can pick it apart piece by piece, working from the inside out, to see how it works.

like image 76
Josh O'Brien Avatar answered Oct 23 '22 14:10

Josh O'Brien