Search code examples
r

Transform for loop with if else condition to a more efficient implementation in R


I have implemented the combination of for loop and if else condition in R

for (i in 1:n) {
  if(some condition) {
    some code
  else {
    some code
  }
}

The condition is the i-th element of a vector is lower than a certain threshold. And I perform some different operation on it depending whether it is true or false. The vector is very long and I would like to know if there is a way to perform this without using for loop.


Solution

  • Here are some benchmarks for you.

    
    vec <- rep(c(1:5,5:1),1000)
    
    
    f1 <- \(x){
      9 * (x < 3) + 7 * (x >= 3)
    }
    f2 <- \(x){
      for (i in seq_along(x)) {
        if (x[i] < 3) {
         x[i] <- 9
        } else {
          x[i] <- 7
        }
      }
      x
    }
    
    f3 <- \(x){
      if(x<3)
        return(9)
      else 
        return( 7)
    }
    
    f4 <- \(x){
      ifelse(x<3,9,7)
    }
    
    bench::mark(
      vec_direct=f1(vec),
      vec_forloop=f2(vec),
      vec_sapply=sapply(vec,f3),
      vec_ifelse=f4(vec)
    )
    
    # A tibble: 4 × 13
      expression       min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time
      <bch:expr>  <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm>
    1 vec_direct    38.9µs   45.5µs    16022.   264.5KB    79.9   5015    25      313ms
    2 vec_forloop  684.1µs  702.6µs     1344.    78.2KB     2.03   661     1      492ms
    3 vec_sapply    3.93ms   4.27ms      225.   362.6KB     6.42   105     3      468ms
    4 vec_ifelse   118.8µs 162.25µs     4908.   555.3KB    55.9   1668    19      340ms
    

    the iterations/sec column