2

how can one vectorize the following double for loop in R?

a <-  seq(1,10, length=5)
b <- seq(0,1, length=4)
fun <- function(a,b){return(a+b)}

out <- matrix(NaN, nrow=5, ncol=4)

  for(i in 1:5) {
    for(j in 1:4) {
      out[i, j] <- fun(a[i], b[j])
    }
  }

I have attempted, for example, without success. Please advise, thanks in advance

outer(1:nrow(out), 1:ncol(out), FUN = fun(a,b))
mapply(out, fun)
T_D
  • 67
  • 6

2 Answers2

3

What about:

outer(a, b, '+')

## > outer(a, b, '+')
##       [,1]      [,2]      [,3]  [,4]
## [1,]  1.00  1.333333  1.666667  2.00
## [2,]  3.25  3.583333  3.916667  4.25
## [3,]  5.50  5.833333  6.166667  6.50
## [4,]  7.75  8.083333  8.416667  8.75
## [5,] 10.00 10.333333 10.666667 11.00
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • I have a much more complicated function "fun", hence I keep getting errors "Error in outer(a, b, function(ai, bj) { : dims [product 900] do not match the length of object [1]".. But your answer is useful, thanks! – T_D Sep 24 '13 at 17:42
  • @T_D [This](http://stackoverflow.com/questions/18110397/why-doesnt-outer-work-the-way-i-think-it-should-in-r/18110630#18110630) should help you on how you can use `outer` and rewrite your "fun". – agstudy Sep 24 '13 at 18:02
  • @T_D I'd say post the function you're attempting to use then. – Tyler Rinker Sep 24 '13 at 18:07
2

As a general rule, vectorizing the innermost loop is usually enough to get you the performance gains. In this case that would mean:

for(i in 1:5) {
  out[i,]<- a[i] + b
}

Assuming that a and b both have length O(n), then by doing it this way, you ensure that the overhead from iterating through a loop in R is only incurred O(n) times, rather than O(n^2) times if you do both loops in R. Since the running time of the algorithm is going to be O(n^2) anyway, the additional O(n) overhead won't affect the running time much.

Of course, for this particular example, you could use outer like others have suggested.

mrip
  • 14,913
  • 4
  • 40
  • 58
  • I upvoted because someone downvoted. While this isn't the best solution (likely) it removes a `for` loop and replaces it with vectorization. I don't think this deserved a downvote. – Tyler Rinker Sep 24 '13 at 19:26