9

This is a simple problem, but for the life of me I cannot find the answer.

for (w in 1:47) {
    s <- w + 1;

    while(s < 49) {
        xx <- wcc(x$codes[w,], x$codes[s,], 20)
        C = matrix(rbind(w,s,xx), nrow=1128, ncol=3, byrow=TRUE)
        s <- s + 1;
    }
}

in this loop, I want to put the XX into matrix C one by one.

Acsor
  • 1,011
  • 2
  • 13
  • 26
user2645553
  • 109
  • 1
  • 1
  • 4

3 Answers3

16

Preallocating your final matrix will be much more efficient than what you're doing. Calling matrix and rbind repeatedly mean copying your data to a new object every time you iterate through each of your (nested) loops.

Even if you don't know the final size you need, overestimating the final matrix will save you time. See here for some discussion.

Here's a simple example of how to do this:

iter <- 10
out <- matrix(NA, nrow=iter, ncol=3)

for (n in 1:iter)
  out[n,] <- c(n, 2*n, n+1)

Alternatively, you could skip constructing the output object entirely and just use sapply:

t(sapply(1:iter, function(n) c(n, 2*n, n+1)))

Either way you get a nice matrix:

      [,1] [,2] [,3]
 [1,]    1    2    2
 [2,]    2    4    3
 [3,]    3    6    4
 [4,]    4    8    5
 [5,]    5   10    6
 [6,]    6   12    7
 [7,]    7   14    8
 [8,]    8   16    9
 [9,]    9   18   10
[10,]   10   20   11
Community
  • 1
  • 1
Thomas
  • 43,637
  • 12
  • 109
  • 140
10

building a matrix one row at a time is not a very efficient way to code (since the matrix is expanding it will require re-allocation of memory!). however, it can be done. have a look at the following toy example:

> C = c(0, 0, 1)

> for (n in 1:10) {
+   x <- c(n, 2*n, n+1)
+   C <- rbind(C, x)
+ }
> C
  [,1] [,2] [,3]
C    0    0    1
x    1    2    2
x    2    4    3
x    3    6    4
x    4    8    5
x    5   10    6
x    6   12    7
x    7   14    8
x    8   16    9
x    9   18   10
x   10   20   11

C starts out as a vector. each call to rbind() appends another row onto the matrix. obviously the new row has to have as many columns as there are in the existing matrix.

Alternatively, to avoid the pre-allocation issue but still use rbind(), you could assemble the data in a list (no penalty on re-allocation and also no need to determine the number of elements up front) and then convert to a matrix when you are done.

> C = list()
> 
> for (n in 1:10) {
+   C[[n]] <- c(n, 2*n, n+1)
+ }
> 
> do.call(rbind, C)
      [,1] [,2] [,3]
 [1,]    1    2    2
 [2,]    2    4    3
 [3,]    3    6    4
 [4,]    4    8    5
 [5,]    5   10    6
 [6,]    6   12    7
 [7,]    7   14    8
 [8,]    8   16    9
 [9,]    9   18   10
[10,]   10   20   11
datawookie
  • 1,607
  • 12
  • 20
0

Here is an example where the matrix is created based on the pattern, which is the first row. The row to be included is X.

if (!exists("XM")) {
  XM = matrix(X, ncol = length(X))
} else
{
  XM = rbind(XM, X)
}

In the initialization, we need to remove XM (to be sure):

if (exists("XM")) rm("XM") 
Antoni
  • 342
  • 2
  • 7