0
votes

I've got two matrix with same numbers of rows and columns, and I would like to merge them by their index in order to create a new matrix (I don't know nrow() nor ncol() in advance, nrow() comes from k kmeans clusters centroid and ncol() comes from k' knn values)

A <- matrix(sample(letters), ncol = 10, nrow = 3)
B <- matrix(sample(letters), ncol = 10, nrow = 3)

A

[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] "h"  "p"  "j"  "w"  "z"  "e"  "q"  "o"  "s"  "y"  
[2,] "y"  "b"  "k"  "t"  "a"  "v"  "f"  "x"  "c"  "r"  
[3,] "r"  "i"  "m"  "g"  "d"  "n"  "l"  "u"  "h"  "p"  

B

[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]      
[1,] "k"  "q"  "l"  "n"  "o"  "r"  "u"  "b"  "s"  "y"       
[2,] "y"  "f"  "v"  "c"  "t"  "w"  "h"  "a"  "d"  "x"       
[3,] "x"  "e"  "j"  "g"  "m"  "i"  "p"  "z"  "k"  "q"       

I find their index :

a <- which(A !=0, arr.ind = T)
b <- which(B !=0, arr.ind = T)

I would like a final matrix merging A and B by row and by column index, so that A[1,1] comes just before B[1,1]

A[1,1]  B[1,1]  A[1,2]  B[1,2]  A[1,3]  B[1,3]  A[1,4]  B[1,4]  ...
A[2,1]  B[2,1]  A[2,2]] B[2,2]  A[2,3]  B[2,3]  A[2,4]  B[2,4]  ...
A[3,1]  B[3,1]  A[3,2]  B[3,2]  A[3,3]  B[3,3]  A[3,4]  B[3,4]  ...

So for instance first row would be :

h   k   p   q   j   l   w   n   z   o

I found here that the lapply function does the job but it gives me a list :

t <- lapply(1:length(knn.mat),
        function(i){cbind(A[i], B[i])})

I can't just unlist because I don't know in advance how many rows and columns my input matrix will have, and I would like a matrix or dataframe as an output, maybe something with a for loop that I could use with a function of the apply family ? (this one doesn't run well)

doMat <- function(x,y){
  X <- matrix(0, nrow = nrow(x), ncol = ncol(x)*2)
  for (i in 1:nrow(x))
 {
    X[i] <- cbind(x[i],y[i])
    i = i+1
  }
  return(X)}
3

3 Answers

0
votes

This will do it in a single line - making use of the way R can treat matrices as vectors.

AB <- matrix(matrix(c(t(A),t(B)),nrow=2,byrow=TRUE),ncol=2*ncol(A),byrow=TRUE)

A
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] "x"  "a"  "u"  "t"  "r"  "g"  "z"  "d"  "l"  "v"  
[2,] "v"  "h"  "n"  "w"  "i"  "b"  "k"  "o"  "y"  "m"  
[3,] "m"  "q"  "p"  "c"  "e"  "j"  "f"  "s"  "x"  "a"  

B
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] "v"  "e"  "n"  "j"  "w"  "h"  "d"  "m"  "z"  "p"  
[2,] "p"  "g"  "t"  "a"  "f"  "r"  "i"  "s"  "q"  "c"  
[3,] "c"  "y"  "o"  "u"  "l"  "k"  "b"  "x"  "v"  "e"  

AB
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
[1,] "x"  "v"  "a"  "e"  "u"  "n"  "t"  "j"  "r"  "w"   "g"   "h"   "z"   "d"   "d"   "m"   "l"   "z"   "v"   "p"  
[2,] "v"  "p"  "h"  "g"  "n"  "t"  "w"  "a"  "i"  "f"   "b"   "r"   "k"   "i"   "o"   "s"   "y"   "q"   "m"   "c"  
[3,] "m"  "c"  "q"  "y"  "p"  "o"  "c"  "u"  "e"  "l"   "j"   "k"   "f"   "b"   "s"   "x"   "x"   "v"   "a"   "e" 
0
votes

yet another take :)

A <- matrix(sample(letters), ncol = 10, nrow = 3)
B <- matrix(sample(letters), ncol = 10, nrow = 3)   

# > A
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] "h"  "f"  "g"  "q"  "e"  "s"  "a"  "b"  "v"  "i"  
# [2,] "i"  "o"  "t"  "y"  "r"  "z"  "u"  "x"  "w"  "l"  
# [3,] "l"  "c"  "m"  "n"  "k"  "p"  "j"  "d"  "h"  "f"

# > B
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] "b"  "p"  "e"  "g"  "x"  "q"  "k"  "o"  "r"  "d"  
# [2,] "d"  "j"  "n"  "v"  "w"  "l"  "t"  "a"  "c"  "f"  
# [3,] "f"  "u"  "z"  "m"  "h"  "s"  "y"  "i"  "b"  "p"

column_order <-rep(seq(1:ncol(A)),each=2) + rep(c(0,ncol(A)),times=ncol(A)) # 1,11,2,12 ...
AB_sorted  <- cbind(A,B)[,column_order]

# > AB_sorted
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
# [1,] "p"  "f"  "u"  "g"  "n"  "t"  "q"  "x"  "m"  "n"   "k"   "w"   "h"   "e"   "l"   "a"   "w"   "p"   "x"   "o"  
# [2,] "x"  "o"  "e"  "m"  "o"  "s"  "g"  "i"  "r"  "j"   "t"   "k"   "d"   "z"   "c"   "q"   "i"   "h"   "v"   "l"  
# [3,] "v"  "l"  "j"  "y"  "a"  "r"  "y"  "b"  "f"  "c"   "s"   "u"   "z"   "v"   "b"   "d"   "p"   "f"   "u"   "g"
0
votes

If all you are trying to do is interweave columns, then you can use a similar approach as in this question: Alternate, interweave or interlace two vectors

This seems to work: matrix(c(rbind(A,B)), nrow = nrow(A))

Edit:

As @Moody_Mudskipper pointed out in the comments, c() is actually superfluous in this case: matrix(rbind(A,B), nrow = nrow(A)) would work just as well.