Reshape matrix by rows

我们两清 提交于 2020-01-03 21:02:24

问题


I have a matrix with size 18000 x 54. I would like to reshape it as a matrix with size 54000 x 18, in which each row of my initial matrix becomes a matrix which has 3 rows.

Let's take an example. I have a matrix as follow:

a = matrix(1:18, nrow = 2, ncol = 9, byrow = T)
a
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
   1    2    3    4    5    6    7    8    9
  10   11   12   13   14   15   16   17   18

I would like to reshape this matrix so that it becomes:

[,1]  [,2]  [,3]    
  1      4    7  
  2      5    8
  3      6    9
  10    13   16
  11    14   17
  12    15   18 

I tried two following ways, but they do not work. The first is as follows:

dim(a) = c(6,3)

The second one is to create a function and then apply to each row:

reshapeX = function(x){
   dim(x) = c(3,as.integer(length(x)/3))
   return(as.matrix(x))
}
rbind(apply(a, 1, reshapeX))

But it does not work neither. Can someone help please?


回答1:


You can do:

do.call(rbind, lapply(1:nrow(a), function(i) matrix(a[i, ], nrow=3)))

with your data:

a <- matrix(1:18, nrow = 2, ncol = 9, byrow = TRUE)
do.call(rbind, lapply(1:nrow(a), function(i) matrix(a[i, ], nrow=3)))
#      [,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



回答2:


Here is a loop free method,

m1 <- matrix(c(a), ncol = 3, nrow = 6)
rbind(m1[c(TRUE, FALSE),], m1[c(FALSE, TRUE),])

#     [,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



回答3:


An option would be

out <- sapply(split.default(as.data.frame(a), as.integer(gl(ncol(a), 3, 
          ncol(a)))), function(x) c(t(x)))
colnames(out) <- NULL
out
#     [,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

Or in shorter form of the above

sapply(split(a,(col(a)-1) %/%3), function(x) c(matrix(x, nrow = 3, byrow = TRUE)))

Or this can be done more compactly with array

apply(array(c(t(a)), c(3, 3, 2)), 2, c)
#      [,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


来源:https://stackoverflow.com/questions/56748699/reshape-matrix-by-rows

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