How to create a matrix from all possible combinations of 2 or more matrices?

Viewed 289

Let's say, there are two matrices:

A <- B <- diag(3)  
> A
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1

I want to create a new matrix AB, which consists of all the possible combinations of rows of A and B. Expected result:

> AB
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    0    0    1    0    0
 [2,]    1    0    0    0    1    0
 [3,]    1    0    0    0    0    1
 [4,]    0    1    0    1    0    0
 [5,]    0    1    0    0    1    0
 [6,]    0    1    0    0    0    1
 [7,]    0    0    1    1    0    0
 [8,]    0    0    1    0    1    0
 [9,]    0    0    1    0    0    1

How to do this efficiently? And can it be extended for more than two matrices?

1 Answers

You can use expand.grid() and take its output to index the matrix A and B,

x <- expand.grid(1:3,1:3)

cbind(A[x[,1],], B[x[,2],])

gives,

     [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    0    0    1    0    0
 [2,]    0    1    0    0    1    0
 [3,]    0    0    1    0    0    1
 [4,]    1    0    0    1    0    0
 [5,]    0    1    0    0    1    0
 [6,]    0    0    1    0    0    1
 [7,]    1    0    0    1    0    0
 [8,]    0    1    0    0    1    0
 [9,]    0    0    1    0    0    1

EDIT:

For more than two matrices, you can use a function like below,

myfun <- function(...) {

     arguments <- list(...)

     a <- expand.grid(lapply(arguments, function(x) 1:nrow(x)))
    
    
     do.call(cbind,lapply(seq(a),function(x) { arguments[[x]][a[,x],] }))

 
}

out <- myfun(A,B,C)

head(out)

gives,

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    0    0    1    0    0    1    0    0     0
[2,]    0    1    0    1    0    0    1    0    0     0
[3,]    0    0    1    1    0    0    1    0    0     0
[4,]    1    0    0    0    1    0    1    0    0     0
[5,]    0    1    0    0    1    0    1    0    0     0
[6,]    0    0    1    0    1    0    1    0    0     0

Data:

A <- B <- diag(3)
C <- diag(4)
Related