Search code examples
rmatrixcbind

how to create a empty matrix in the using cbind a loop R


I want to cbind matrix generated for each step in R, how to create a initial empty matrix say result=[] in matlab then cbind for each iteration?


Solution

  • Using cbind in a loop is very slow. If you know the size in advance, you can preallocate the matrix and fill columns in the loop. Otherwise, use a list. Create an empty list and add vectors to the list in the loop. Then, cbind the list into a matrix after the loop has finished.

    Timings:

    Preallocate matrix:
       user  system elapsed 
      1.024   0.064   1.084
    
    Grow matrix with cbind:
       user  system elapsed 
     76.036  50.146 125.840
    
    Preallocate list:
       user  system elapsed 
      0.788   0.040   0.823
    
    Grow list by indexing:
       user  system elapsed 
      0.821   0.043   0.859 
    

    Code:

    # Preallocate matrix.
    f1 = function(x) {
        set.seed(2718)
        mat = matrix(ncol=x, nrow=x)
        for (i in 1:x) {
            mat[, i] = rnorm(x)
        }
        return(mat)
    }
    
    # Grow matrix with cbind.
    f2 = function(x) {
        set.seed(2718)
        mat = c()
        for (i in 1:x) {
            mat = cbind(mat, rnorm(x))
        }
        return(mat)
    }
    
    # Preallocate list.
    f3 = function(x) {
        set.seed(2718)
        lst = vector("list", length=x)
        for (i in 1:x) {
            lst[[i]] = rnorm(x)
        }
        res = do.call(cbind, lst)
        return(res)
    }
    
    # Grow list by indexing.
    f4 = function(x) {
        set.seed(2718)
        lst = list()
        for (i in 1:x) {
            lst[[i]] = rnorm(x)
        }
        res = do.call(cbind, lst)
        return(res)
    }
    
    x = 3000
    
    system.time(r1 <- f1(x))
    system.time(r2 <- f2(x))
    system.time(r3 <- f3(x))
    system.time(r4 <- f4(x))
    
    all.equal(r1, r2)
    all.equal(r1, r3)
    all.equal(r1, r4)