在R中转换矩阵

时间:2018-10-25 12:36:40

标签: r matrix

我有一个矩阵,我们称它为A,看起来像这样:

have=matrix(1:24,4,6)

我想要的是像这样向下堆叠列:

want=rbind(matrix(1:8,4,2),matrix(9:16,4,2),matrix(17:24,4,2))

我该怎么做?

4 个答案:

答案 0 :(得分:3)

转换为3d数组,置换尺寸并将其展平回矩阵:

a <- array(have, c(nrow(have), 2, ncol(have) / 2))
m <- matrix(aperm(a, c(1, 3:2)), , 2)

identical(m, want)
## [1] TRUE

答案 1 :(得分:1)

这是一种通用方法:(不建议用于大型矩阵)

do.call(
  rbind,
  lapply(split(as.data.frame(t(have)), rep(1:(ncol(have)/2), each = 2)),  t)
)

#    1  2
#V1  1  5
#V2  2  6
#V3  3  7
#V4  4  8
#V1  9 13
#V2 10 14
#V3 11 15
#V4 12 16
#V1 17 21
#V2 18 22
#V3 19 23
#V4 20 24

冗长:

t(do.call(
  cbind, split(as.data.frame(t(have)), rep(1:(ncol(have)/2), each = 2))
))

MicroBenchmark(看起来像我的速度缓慢,其他人很好,docendo的评论最快)

#Unit: microseconds
#           expr         min           lq        mean      median          uq      max neval cld
#      iod(have)     819.899     961.0395    2012.594    1464.333    1906.841   47355.220   100 a  
#  docendo(have)     770.500     886.4595    1472.148    1278.606    1845.092    6139.614   100 a  
# elrico_1(have) 1264126.245 1402175.8105 1501416.879 1485285.458 1576934.268 1944551.334   100  b 
# elrico_2(have) 1325903.781 1453495.4745 1534026.109 1534564.839 1588372.907 1987343.222   100   c
#  grothen(have)     963.927    1149.9755    1904.186    1796.816    2422.646    8277.573   100 a  
#> 


have=matrix(1:24,4,6)

have = do.call(cbind, rep(list(have), 100)) %>% {do.call(rbind, rep(list(.), 100))}

iod     <- function(have) { apply(matrix(1:dim(have)[2],nrow=2), 1, function(x) {have[,c(x)]})}
docendo <- function(have) { cbind(c(have[, c(TRUE, FALSE)]), c(have[, c(FALSE, TRUE)])) }
elrico_1 <- function(have) { do.call(
    rbind,
    lapply(split(as.data.frame(t(have)), rep(1:(ncol(have)/2), each = 2)),  t) 
) }
elrico_2<- function(have) { t(do.call(
    cbind, split(as.data.frame(t(have)), rep(1:(ncol(have)/2), each = 2))
)) }
grothen <-  function(have) { a <- array(have, c(nrow(have), 2, ncol(have) / 2))
            matrix(aperm(a, c(1, 3:2)), , 2)}

microbenchmark::microbenchmark(iod(have), docendo(have), elrico_1(have), elrico_2(have), grothen(have))

答案 2 :(得分:0)

apply(matrix(1:dim(have)[2],nrow=2), 1, function(x) {have[,c(x)]})

创建一个矩阵,将行数分成两部分,然后将所有的几率和所有的偶数应用为apply中的一个子集调用。

结果:

      [,1] [,2]
 [1,]    1    5
 [2,]    2    6
 [3,]    3    7
 [4,]    4    8
 [5,]    9   13
 [6,]   10   14
 [7,]   11   15
 [8,]   12   16
 [9,]   17   21
[10,]   18   22
[11,]   19   23
[12,]   20   24

答案 3 :(得分:0)

创建2个向量并合并为列:

cbind(c(have[, c(seq(1,5,2))]), c(have[, c(seq(2,6,2))]))