Skip to content

How to join matrices of different row length from a list

6 messages · Dimitris Rizopoulos, emj83, David Winsemius +2 more

#
Hi,

I have several matrix in a list, for example:
e
[[1]]
     [,1] [,2]
[1,]    1    3
[2,]    2    4

[[2]]
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

[[3]]
     [,1] [,2]
[1,]    2    1

I would like to join them by column i.e.
     [,1] [,2]   [,3] [,4][,5] [,6]
[1,]    1    3   1    4    2    1
[2,]    2    4   2    5   NA  NA
[3,]   NA  NA  3    6   NA   NA

I have tried  do.call(cbind,e) but I get this error message as the rows are
of different length-
Error in function (..., deparse.level = 1)  :
  number of rows of matrices must match (see arg 2)

Can anyone advise me please?

Thanks Emma
#
try this:

matLis <- list(matrix(1:4, 2, 2), matrix(1:6, 3, 2),
     matrix(2:1, 1, 2))

n <- max(sapply(matLis, nrow))
do.call(cbind, lapply(matLis, function (x)
     rbind(x, matrix(, n-nrow(x), ncol(x)))))


I hope it helps.

Best,
Dimitris
On 1/6/2011 11:56 AM, emj83 wrote:

  
    
#
On Jan 6, 2011, at 6:23 AM, Dimitris Rizopoulos wrote:

            
It's good that you solved the OP's question so neatly, since the  
alternate solution I was going to propose turns out to be for a  
different problem. Had the problem been for binding by row and padding  
with NA's, there is a ready-made function in the plyr package,  
rbind.fill.matrix(). No cbind.fill or cbind.fill.matrix, yet. It looks  
as though switching the roles of column and row in either of your  
respective solutions could create a general solution though.
#
On Thu, Jan 6, 2011 at 5:56 AM, emj83 <stp08emj at shef.ac.uk> wrote:
One reasonably simple approach is to convert your matrices to time
series (either ts series or zoo series) as cbind.ts and cbind.zoo both
NA fill.

L <- list(matrix(1:4, 2, 2), matrix(1:6, 3, 2), matrix(2:1, 1, 2))


# using ts
M <- unclass(do.call(cbind, lapply(L, ts)))
tsp(M) <- colnames(M) <- NULL

# With zoo its slightly shorter:

library(zoo)
M <- coredata(do.call(cbind, lapply(L, zoo)))
colnames(M) <- NULL


We can omit the colnames(M) <- NULL part in both cases if the list
itself or the constituent matrices have column names, e.g.

L <- list(A = matrix(1:4, 2, 2), B = matrix(1:6, 3, 2), C = matrix(2:1, 1, 2))

# or

L <- list(cbind(a = 1:2, b = 3:4), cbind(c = 1:3, d = 4:6), cbind(e = 2, f = 1))
#
Dear Emma,

there is a 'cbind.na', 'rbind.na' and 'data.frame.na' function in my qpcR
package.

library(qpcR)
matLis <- list(matrix(1:4, 2, 2), matrix(1:6, 3, 2),
     matrix(2:1, 1, 2))
do.call(cbind.na, matLis)

They are essentially the generic functions extended with an internal fill.

You might also want to try these examples:

## binding
cbind.na(1, 1:7) # the '1' (= shorter vector) is NOT recycled but filled
cbind.na(1:8, 1:7, 1:5, 1:10) # same with many vectors
rbind.na(1:8, 1:7, 1:5, 1:10) # or in rows

a <- matrix(rnorm(20), ncol = 4) # unequal size matrices
b <- matrix(rnorm(20), ncol = 5)
cbind.na(a, b) # works, in contrast to original cbind
rbind.na(a, b) # works, in contrast to original rbind

## data frame with unequal size vectors
data.frame.na(A = 1:7, B = 1:5, C = letters[1:3], 
              D = factor(c(1, 1, 2, 2))) 
              
## convert a list with unequal length list items
## to a data frame
z <- list(a = 1:5, b = letters[1:3], c = matrix(rnorm(20), ncol = 2))
do.call(data.frame.na, z)