1

Problem

Say I have a function that is currently not vectorized. The following is just an example :

FunctionNotVectorized = function(x,y,some_options) return(x[1]+y[1])

which has, say, 10 different options. I would like to

  • 1) define a matrix of size 1e5 x 1e5 for each option.
  • 2) then, for each matrix, assign values for their corresponding indices.

First, I defined a matrix of size 1e5 x 1e5 for each option, by for loop :

for (k in 1:10){
  assign(sprintf("res%02d", k), matrix(0,1e5,1e5))
}

which defines matrices named res01, ... res10.

Second, I tried to assign values for their corresponding indices for each matrix. But I'm stuck here

Try

What I would like to do:

for (i in 1:1e5){
  for (j in 1:1e5){
    for (k in 1:10){
      assign(sprintf("res%02d[i,j]", k),
             FunctionNotVectorized(i,j,some_options=k))
    }
  }
}

but clearly, assign(sprintf("res%02d[i,j]", k) does not work. Any help will be appreciated.

moreblue
  • 322
  • 1
  • 4
  • 16

2 Answers2

1
  1. Avoid using loops in R, because in makes calculation hundreds times slowlier. Only with iterations<100 it is ok to use for/while/etc

  2. Use lapply to operate on whatever objects the same way, then do.call to aggregate them from list. Use lists instead of assigning. lapply and list are close friends

  3. Here is an example for matrices with sizes 15x15:

mtxs = list()                            #create empty list which will get filled 
for(k in 1:10){                          # loop over 10 matrixes   
mtx = do.call(c,lapply(1:15,function(x){ # gathering second vectorized calculation                
    do.call(c,lapply(1:15,               # gathering first vectorized calculation
      function(y){functionNotVectorized(y, x, k) } ))})) # lapply over rows ans cols   
mtxs[[k]] = matrix(mtx, 15, 15)          # assigning matrices 
}
  • 1
    Meanwhile, `lapply` and its siblings are loops: [Is the “*apply” family really not vectorized?](https://stackoverflow.com/questions/28983292/is-the-apply-family-really-not-vectorized). – Parfait Mar 23 '19 at 00:14
  • 1
    They are vectorized loops which is a big difference. I had dozens of examples where lapply was x100 or so times faster than for – Sergio Alyoshkin Mar 23 '19 at 00:25
1

Simply use a named list without need to use assign to add objects to global environment:

# BUILD LIST OF MATRICES
my_matrix_list <- setNames(replicate(10, matrix(0,1e5,1e5), simplify = FALSE), 
                           paste0("res", 1:10, "d"))

# DYNAMICALLY ASSIGN VALUE BY OBJECT NAME
for (i in 1:1e5){
  for (j in 1:1e5){
    for (k in 1:10){
      my_matrix_list[paste0("res", k, "d")][i,j] <-
          FunctionNotVectorized(i,j,some_options=k)
    }
  }
}

# REFERENCE ITEMS IN LIST
my_matrix_list$res1d
my_matrix_list$res2d
my_matrix_list$res3d
...
Parfait
  • 104,375
  • 17
  • 94
  • 125