One approach is to think of the indices of the rows of your data that make up each line of the desired output. Using your data:
mat <- matrix(c("A","B","A",
"A","A","B",
"B","A","A"), ncol = 3, byrow = TRUE)
I create those indices using expand.grid()
. The first row of your output is formed by the concatenation of row 1 of mat
with row 1 of mat
, and so on. These indices are produced as follows
> ind <- expand.grid(r1 = 1:3, r2 = 1:3)
> ind
r1 r2
1 1 1
2 2 1
3 3 1
4 1 2
5 2 2
6 3 2
7 1 3
8 2 3
9 3 3
Note that to get what your output shows we need to take columns r2
then r1
rather than the other way round.
Now I just index mat
with the second column of ind
and the first column of ind
and supply that to paste0()
the output from which is a vector so we need to reshape it to a matrix.
> matrix(paste0(mat[ind[,2], ], mat[ind[,1], ]), ncol = 3)
[,1] [,2] [,3]
[1,] "AA" "BB" "AA"
[2,] "AA" "BA" "AB"
[3,] "AB" "BA" "AA"
[4,] "AA" "AB" "BA"
[5,] "AA" "AA" "BB"
[6,] "AB" "AA" "BA"
[7,] "BA" "AB" "AA"
[8,] "BA" "AA" "AB"
[9,] "BB" "AA" "AA"
The paste0()
step returns a vector of the pasted strings:
> paste0(mat[ind[,2], ], mat[ind[,1], ])
[1] "AA" "AA" "AB" "AA" "AA" "AB" "BA" "BA" "BB" "BB" "BA" "BA" "AB" "AA" "AA"
[16] "AB" "AA" "AA" "AA" "AB" "AA" "BA" "BB" "BA" "AA" "AB" "AA"
The trick as to why the matrix restructuring shown above works is to note that the entries in the output from paste0()
are in column-major order because of how the index ind
was formed. Essentially the two arguments passed to paste0()
are:
> mat[ind[,2], ]
[,1] [,2] [,3]
[1,] "A" "B" "A"
[2,] "A" "B" "A"
[3,] "A" "B" "A"
[4,] "A" "A" "B"
[5,] "A" "A" "B"
[6,] "A" "A" "B"
[7,] "B" "A" "A"
[8,] "B" "A" "A"
[9,] "B" "A" "A"
> mat[ind[,1], ]
[,1] [,2] [,3]
[1,] "A" "B" "A"
[2,] "A" "A" "B"
[3,] "B" "A" "A"
[4,] "A" "B" "A"
[5,] "A" "A" "B"
[6,] "B" "A" "A"
[7,] "A" "B" "A"
[8,] "A" "A" "B"
[9,] "B" "A" "A"
R treats each as a vector and hence the output is a vector, but because R stores matrices by columns, we fill our output matrix with the pasted strings by columns also.