convert 4-dimensional array to 2-dimensional data set in R

匿名 (未验证) 提交于 2019-12-03 01:23:02

问题:

I would like to convert a 4-dimensional array into a 2-dimensional data set. I present code for two approaches that do that: one approach using a brute force method involving cbind and rbind and a second approach using nested for-loops. Nevertheless, I am thinking there is likely 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 

回答1:

It took a couple of tries, but:

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

or more generally

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


回答2:

In case someone comes here looking for a similar question about collapsing to an array, but to one that is greater than dimension=2, use array() instead of matrix(), with the dim() argument to specify what dimensions you want. Code that will also work for the problem above is:

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

This can easily be modified if you wanted the output to be, say, a 3d array by putting in an additional value to dim(). The aperm() bit may not be necessary for your particular case, but you should always check that the collapsed array is in the order you want and use aperm() accordingly.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!