Convert 4-dimensional array to 2-dimensional dataset in R

I would like to convert a 4-dimensional array to a two-dimensional dataset. I present the code for two approaches that do this: one approach using brute force including cbind and rbind , and the second approach using nested for-loops . However, I think there is a better way. Thank you for any suggestions.

 R <- 3 # regions M <- 5 # sites J <- 2 # samples T <- 4 # years # 4-dim example array y <- array(NA, dim = c(M, J, T, R)) # region 1 y[,1,1,1] = 1; y[,2,1,1] = 2; y[,1,2,1] = 3; y[,2,2,1] = 4; y[,1,3,1] = 5; y[,2,3,1] = 6; y[,1,4,1] = 7; y[,2,4,1] = 8; # region 2 y[,1,1,2] = 9; y[,2,1,2] = 10; y[,1,2,2] = 11; y[,2,2,2] = 12; y[,1,3,2] = 13; y[,2,3,2] = 14; y[,1,4,2] = 15; y[,2,4,2] = 16; # region 3 y[,1,1,3] = 17; y[,2,1,3] = 18; y[,1,2,3] = 19; y[,2,2,3] = 20; y[,1,3,3] = 21; y[,2,3,3] = 22; y[,1,4,3] = 23; y[,2,4,3] = 24; # desired two-dimensional data set z = read.table(text = " 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 9 10 11 12 13 14 15 16 9 10 11 12 13 14 15 16 9 10 11 12 13 14 15 16 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 17 18 19 20 21 22 23 24 17 18 19 20 21 22 23 24 17 18 19 20 21 22 23 24 17 18 19 20 21 22 23 24 ", sep = "", header = FALSE) # using cbind and rbind to convert 4-dimensional array to 2-dimensional data set r1 <- cbind(y[,,1,1], y[,,2,1], y[,,3,1], y[,,4,1]) r2 <- cbind(y[,,1,2], y[,,2,2], y[,,3,2], y[,,4,2]) r3 <- cbind(y[,,1,3], y[,,2,3], y[,,3,3], y[,,4,3]) my.data <- rbind(r1,r2,r3) my.data # using nested for-loops to convert 4-dimensional array to 2-dimensional data set m2 <- matrix(NA, nrow = M*R, ncol= J*T) for(i in 1:R) { for(j in 1:T) { m2[(M*(i-1) + (1:M)), (J*(j-1) + (1:J))] = y[,,j,i] } } m2 # basis for nested for-loops above m3 <- matrix(NA, nrow = M*R, ncol= J*T) m3[(M*0 + (1:M)), (J*0 + (1:J))] = y[,,1,1] m3[(M*0 + (1:M)), (J*1 + (1:J))] = y[,,2,1] m3[(M*0 + (1:M)), (J*2 + (1:J))] = y[,,3,1] m3[(M*0 + (1:M)), (J*3 + (1:J))] = y[,,4,1] m3[(M*1 + (1:M)), (J*0 + (1:J))] = y[,,1,2] m3[(M*1 + (1:M)), (J*1 + (1:J))] = y[,,2,2] m3[(M*1 + (1:M)), (J*2 + (1:J))] = y[,,3,2] m3[(M*1 + (1:M)), (J*3 + (1:J))] = y[,,4,2] m3[(M*2 + (1:M)), (J*0 + (1:J))] = y[,,1,3] m3[(M*2 + (1:M)), (J*1 + (1:J))] = y[,,2,3] m3[(M*2 + (1:M)), (J*2 + (1:J))] = y[,,3,3] m3[(M*2 + (1:M)), (J*3 + (1:J))] = y[,,4,3] m3 
+4
source share
2 answers

It takes several attempts, but:

 matrix(aperm(y,c(1,4,2,3)),15) 

or in general

 matrix(aperm(y,c(1,4,2,3)),prod(dim(y)[c(1,4)])) 
+9
source

In case someone comes here to look for a similar question about folding into an array, but to one that is larger than dimension = 2, use array () instead of matrix (), with the argument dim (), to indicate which dimensions you want. Code that will also work for the problem above:

 array(aperm(y,c(1,4,2,3)), dim=c(15,8)) 

This can be easily changed if you want the result to be, for example, a three-dimensional array by adding an additional value to dim (). The aperm () bit may not be needed for your specific case, but you should always check that the collapsed array is in the order you want, and use aperm () accordingly.

0
source

All Articles