I have a 3-dimensional array and would like to collapse to a 2-dimensional by stacking one dimension by rows (combining rows of one dimension). In my code, I have filled a "worksheet" (3rd dimension) with a 2-d array at each index, and now I want to take that 3-d array and stack these sheets' rows on top of one another.
Here an example array so I can explain what I want the end result to look like:
x <- array(1:24, dim=c(2, 3, 4),
dimnames=list(letters[1:2], LETTERS[1:3], letters[23:26]))
dim(x)
I would like w
, x
, y
, z
to be stacked on top of one another in a 2-dimensional array, which would have 8 rows and 3 columns. Here is a way to do it that is cumbersome (and not possible in my loop):
x1<-x[,,1]
x2<-x[,,2]
x3<-x[,,3]
x4<-x[,,4]
All<-rbind(x1,x2,x3,x4)
I have looked at abind
and adrop
but they are not quite right.
I have also tried aperm
but I don't think you can reduce dimensions with this, just transpose (?)
Alternatively, I could create a list
(this would be ideal, actually, since arrays might have different row numbers). In that case, how would I combine the rows of multiple elements in a list the same way?
I'll promote my comment to an answer, though I still think there should be a way to do this just altering the dimensions.
apply(x, 2, c)
#or if you're really pushing for speed, the simpler function:
apply(x, 2, identity)
# Giving:
# A B C
#[1,] 1 3 5
#[2,] 2 4 6
#[3,] 7 9 11
#[4,] 8 10 12
#[5,] 13 15 17
#[6,] 14 16 18
#[7,] 19 21 23
#[8,] 20 22 24
Matches the requested output sans the rownames:
all.equal(apply(x,2,c), All, check.attributes=FALSE)
#[1] TRUE
Here's how to do it by manipulating the dimensions:
y <- aperm(x, c(1, 3, 2))
dim(y) <- c(prod(dim(x)[-2]), dim(x)[2])
# the above evaluates to c(8, 3)
y
# [,1] [,2] [,3]
# [1,] 1 3 5
# [2,] 2 4 6
# [3,] 7 9 11
# [4,] 8 10 12
# [5,] 13 15 17
# [6,] 14 16 18
# [7,] 19 21 23
# [8,] 20 22 24
Follow up with colnames(y) <- colnames(x)
if you need to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With