Reputation: 801
Let's assume I have a 3d array of dimensions (x,y,z) and would like to restructure my data as a matrix of dimensions (x*y,z), something like:
my_array <- array(1:600, dim=c(10,5,12))
my_matrix<-data.frame()
for (j in 1:5) {
for (i in 1:10) {
my_matrix <- rbind (my_matrix, my_array[i,j,1:12])
}
}
Could you suggest a faster and more elegant way?
thanks
Upvotes: 12
Views: 16001
Reputation: 1316
Both @akrun and @Lars Arne Jordanger's solutions work and generate the same results.
The two solutions work by:
(1) concatenating the first rows of all matrices together and placing these rows in the top of the combined matrix; and then
(2) concatenating the second rows of all matrices together and placing these rows under the concatenation of the first rows, and so on.
The following example illustrates the idea very well:
> threeDimArray <- array( NA, dim=c(3,3,4) )
> dims <- dim( threeDimArray )
>
> constants <- c(1, 10, 100)
> for( id in 1:length(constants) ){
const <- constants[id]
threeDimArray[id,,] <- matrix( (1:prod(dims[2:3]))*const, dims[2], dims[3] )
}
> threeDimArray[1,,]
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
> threeDimArray[2,,]
[,1] [,2] [,3] [,4]
[1,] 10 40 70 100
[2,] 20 50 80 110
[3,] 30 60 90 120
> threeDimArray[3,,]
[,1] [,2] [,3] [,4]
[1,] 100 400 700 1000
[2,] 200 500 800 1100
[3,] 300 600 900 1200
> # solution 1:
> twoDimMat <- matrix(threeDimArray, prod(dims[1:2]), dims[3])
> twoDimMat
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 10 40 70 100
[3,] 100 400 700 1000
[4,] 2 5 8 11
[5,] 20 50 80 110
[6,] 200 500 800 1100
[7,] 3 6 9 12
[8,] 30 60 90 120
[9,] 300 600 900 1200
>
> # solution 2:
> threeDArray <- threeDimArray
> dim(threeDArray) <- c(prod( dims[1:2] ), dims[3])
> threeDArray
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 10 40 70 100
[3,] 100 400 700 1000
[4,] 2 5 8 11
[5,] 20 50 80 110
[6,] 200 500 800 1100
[7,] 3 6 9 12
[8,] 30 60 90 120
[9,] 300 600 900 1200
>
Upvotes: 1
Reputation: 887901
We can convert to a matrix
by calling the matrix
and specifying the dimensions
res <- matrix(my_array, prod(dim(my_array)[1:2]), dim(my_array)[3])
all.equal(as.matrix(my_matrix), res, check.attributes=FALSE)
#[1] TRUE
NOTE: This will not change the original 'my_array`. Also, in fact, the code can be simplified to
matrix(my_array, 10*5, 12)
and make it compact.
nchar("matrix(my_array, 10*5, 12)")
#[1] 26
nchar("dim(my_array) <- c(10 * 5 , 12)")
#[1] 31
Upvotes: 11
Reputation: 671
Change the dimension of the array:
dim(my_array) <- c(10 * 5 , 12)
Upvotes: 13