[R] updating elements of a vector sequentially - is there a faster way?

Petr Savicky savicky at cs.cas.cz
Fri Aug 24 11:53:58 CEST 2012


On Thu, Aug 23, 2012 at 09:49:33PM -0700, Gopi Goteti wrote:
> I would like to know whether there is a faster way to do the below
> operation (updating vec1).
> 
> My objective is to update the elements of a vector (vec1), where a
> particular element i is dependent on the previous one. I need to do this on
> vectors that are 1 million or longer and need to repeat that process
> several hundred times. The for loop works but is slow. If there is a faster
> way, please let me know.
> 
> probs <- c(.1, .3, .2, .4, .7, .9, .3, .4, .5, .6)
> p10 <- 0.6
> p00 <- 0.4
> vec1 <- rep(0, 10)
> for (i in 2:10) {
>   vec1[i] <- ifelse(vec1[i-1] == 0,
>                     ifelse(probs[i]<p10, 0, 1),
>                     ifelse(probs[i]<p00, 0, 1))
> }

Hi.

There are already several solutions, which use the fact that each
output value either does not depend on the previous value or is its
copy. The following implements this using rle() function.

  probs <- c(.1, .3, .2, .4, .7, .9, .3, .4, .5, .6)
  p10 <- 0.6
  p00 <- 0.4

  # original code  
  vec1 <- rep(0, 10)
  for (i in 2:10) {
    vec1[i] <- ifelse(vec1[i-1] == 0,
                      ifelse(probs[i]<p10, 0, 1),
                      ifelse(probs[i]<p00, 0, 1))
  }

  # modification 
  a10 <- ifelse(probs<p10, 0, 1)
  a00 <- ifelse(probs<p00, 0, 1)
  vec2 <- ifelse(a10 == a00, a10, -1)
  vec2[1] <- 0
  r <- rle(vec2)
  rlen <- r$lengths
  rval <- r$values
  i <- which(rval == -1)
  rval[i] <- rval[i-1]
  vec2 <- rep(rval, times=rlen)

  all(vec1 == vec2)

  [1] TRUE

Hope this helps.

Petr Savicky.




More information about the R-help mailing list