I have a 3D R array, e.g.:
a <- array(1:27, dim = c(3,3,3))
How can I (efficiently) convert this into a matrix in which the 3rd dimension is bound / stacked below each other, i.e.:
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
[4,] 10 13 16
[5,] 11 14 17
[6,] 12 15 18
[7,] 19 22 25
[8,] 20 23 26
[9,] 21 24 27
I can clumsily achieve this with:
rbind(a[,,1], a[,,2], a[,,3])
but this is not generalizable well if I have many entries in the 3rd dimension (except with looping). There must be a more elegant way to achieve this, but I could not find it. Ideas like
apply(a, 3, rbind)
apply(a, 3, c)
create a matrix, but the 3rd dimension simply become the columns. I want to keep the 2D matrices of the first 2 dimensions and just bind them together. I am aware this will mess up the indices, but we can disregard this for my use case.
I would be especially happy about a base R solution, but am also interested if this can be achieved with a (lightweight) package.
Edit: This answer to a seemingly unrelated question provided a useful hint. This approach seems to achieve the desired result:
matrix(aperm(a, c(1, 3, 2)), nrow = dim(a)[1] * dim(a)[3])
Are there other ideas?
CodePudding user response:
With aperm
we transpose an array by permuting its dimensions and optionally resizing it:
y <- aperm(a, c(1, 3, 2))
dim(y) <- c(prod(dim(a)[-2]), dim(a)[2])
y
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
[4,] 10 13 16
[5,] 11 14 17
[6,] 12 15 18
[7,] 19 22 25
[8,] 20 23 26
[9,] 21 24 27