tags:

views:

101

answers:

3

Hi all, I have a matrix A which is:

A <- matrix(c(1:15), byrow=T, nrow=5)
A
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]   10   11   12
[5,]   13   14   15

Now I want to create a matrix B, which is 8x8 dimensions (or 10x10, or 15x15, etc), which would look like this:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    1    2    3    0    0    0    0    0
[2,]    4    5    6    0    0    0    0    0
[3,]    7    8    9    0    0    0    0    0
[4,]   10   11   12    0    0    0    0    0
[5,]   13   14   15    0    0    0    0    0
[6,]    0    0    0    0    0    0    0    0
[7,]    0    0    0    0    0    0    0    0
[8,]    0    0    0    0    0    0    0    0

So starting from A, I want to add columns and rows, to an 8x8 dimensions, all replaced with zero values... Any idea? Thank you in advance!!

+1  A: 

How about:

A <- matrix(c(1:15), byrow=T, nrow=5)

expandMatrix <- function(X, nrow, ncol) {
    X <- cbind(X, matrix(0, nrow = nrow(X), ncol = ncol - ncol(X)))
    X <- rbind(X, matrix(0, nrow = nrow - nrow(X), ncol = ncol(X)))
    X
}

Then

> expandMatrix(A, 8, 8)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    1    2    3    0    0    0    0    0
[2,]    4    5    6    0    0    0    0    0
[3,]    7    8    9    0    0    0    0    0
[4,]   10   11   12    0    0    0    0    0
[5,]   13   14   15    0    0    0    0    0
[6,]    0    0    0    0    0    0    0    0
[7,]    0    0    0    0    0    0    0    0
[8,]    0    0    0    0    0    0    0    0

or

> expandMatrix(A, 10, 10)
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1    2    3    0    0    0    0    0    0     0
 [2,]    4    5    6    0    0    0    0    0    0     0
 [3,]    7    8    9    0    0    0    0    0    0     0
 [4,]   10   11   12    0    0    0    0    0    0     0
 [5,]   13   14   15    0    0    0    0    0    0     0
 [6,]    0    0    0    0    0    0    0    0    0     0
 [7,]    0    0    0    0    0    0    0    0    0     0
 [8,]    0    0    0    0    0    0    0    0    0     0
 [9,]    0    0    0    0    0    0    0    0    0     0
[10,]    0    0    0    0    0    0    0    0    0     0

Could also give it a default if you mostly want square matrix as outputs:

expandMatrix <- function(X, nrow, ncol = nrow) {
    X <- cbind(X, matrix(0, nrow = nrow(X), ncol = ncol - ncol(X)))
    X <- rbind(X, matrix(0, nrow = nrow - nrow(X), ncol = ncol(X)))
    X
}

Then expandMatrix(A, 8) would suffice.

eyjo
That's exactly what I was looking for!! Thank you very much for the fast answer!
Tommaso
+5  A: 

Another way is to first create the bigger matrix, and then slot the small one in, as in this function:

    expandR = function(m,nrows,ncols,with=0){
      p=matrix(with,nrows,ncols)
      p[1:nrow(m),1:ncol(m)]=m
      p
    }

Not sure which is better (faster, cleaner etc). Mine errors if you try and expand to a size that's smaller than the original.

Spacedman
Yes, your is faster. For example, starting from a matrix B, which is 5x9, the computation time for a 4096x4096 matrix with zeros are 0.11 for your function, and 0.53 for the first function. So thank you!
Tommaso
+1  A: 

Try this assuming A has at least one row and one column:

B <- matrix(0, 8, 8)
B[1:nrow(A), 1:ncol(A)] <- A

or as a single statement:

B <- "[<-"(matrix(0, 8, 8), 1:nrow(A), 1:ncol(A), value = A)

If A can have zero rows or zero columns then use seq_len(nrow(A)) and seq_len(ncol(A)) in place of 1:nrow(A) and 1:ncol(A).

Alternately, this works even in the case that A has zero rows or columns:

B <- matrix(0, 8, 8)
B[cbind(c(row(A)), c(col(A)))] <- A

or

B <- "[<-"(matrix(0, 8, 8), cbind(c(row(A)), c(col(A))), value = A)

or

B <- replace(matrix(0, 8, 8), cbind(c(row(A)), c(col(A))), A)
G. Grothendieck
I think this is the best way to perform what I desired. I used your suggestion, in my function. So I cited you in my new post: http://statistic-on-air.blogspot.com/2010/10/fast-matrix-multiplication-in-r.html Thank you very much!
Tommaso