在应用中从矩阵转换为向量的输出

Output converted from matrix to vector in apply

我想在矩阵的一个边距(在我的例子中是列)上应用一个函数。问题是函数 returns 矩阵和 apply 将其转换为向量,因此它 returns 是一个矩阵。我的目标是得到三维数组。下面是例子(注意 matrix() 不是感兴趣的函数,只是一个例子):

x <- matrix(1:12, 4, 3)
apply(x, 2, matrix, nrow = 2, ncol = 2)

输出与输入完全相同。我对此有相当乏味的解决方案:

library(abind)
abind2 <- function (x, ...)
  abind(x, ..., along = dim(x) + 1)
apply(x, 2, list) %>% 
  lapply(unlist) %>% 
  lapply(matrix, nrow = 2, ncol = 2) %>% 
  do.call(what = 'abind2')

我相信一定有比这更好的东西。不包括 list()ing 和 unlist()ing 列的内容。


编辑: 此外,该解决方案应该准备好可以轻松地应用于任意维数组,可以选择 MARGIN 而我的解决方案不是。

这个,比如我要return4维数组。

x <- array(1:24, c(4,3,2))
apply(x, 2:3, list) %>% 
  lapply(unlist) %>% 
  lapply(matrix, nrow = 2, ncol = 2) %>% 
  do.call(what = 'abind2')

一点也不复杂。只需使用

array(x, dim = c(2, 2, ncol(x)))

矩阵和普通数组按列存储到物理地址的一维长数组中。您可以重新分配维度。


好的,这可能是您通常想要做的事情:

tapply(x, col(x), FUN = matrix, nrow = 2, ncol = 2)

#$`1`
#     [,1] [,2]
#[1,]    1    3
#[2,]    2    4
# 
#$`2`
#     [,1] [,2]
#[1,]    5    7
#[2,]    6    8
#
#$`3`
#     [,1] [,2]
#[1,]    9   11
#[2,]   10   12

您可以尝试将 matrix 转换为 data.frame 并使用 lapply 将您的函数应用于 columns(因为 data.frame a list), 它将 return a list, 其中每个元素代表 column:

的函数结果
    lapply(as.data.frame(x), matrix, nrow = 2, ncol = 2)

    # $V1
         # [,1] [,2]
    # [1,]    1    3
    # [2,]    2    4

    # $V2
         # [,1] [,2]
    # [1,]    5    7
    # [2,]    6    8

    # $V3
         # [,1] [,2]
    # [1,]    9   11
    # [2,]   10   12    

编辑 x 的第二个定义:

x <- array(1:24, c(4,3,2))
lapply(as.data.frame(x), matrix, nrow = 2, ncol = 2)
# $V1
     # [,1] [,2]
# [1,]    1    3
# [2,]    2    4

# $V2
     # [,1] [,2]
# [1,]    5    7
# [2,]    6    8

# $V3
     # [,1] [,2]
# [1,]    9   11
# [2,]   10   12

# $V4
     # [,1] [,2]
# [1,]   13   15
# [2,]   14   16

# $V5
     # [,1] [,2]
# [1,]   17   19
# [2,]   18   20

# $V6
     # [,1] [,2]
# [1,]   21   23
# [2,]   22   24

EDIT2: 尝试获得一个 arry 作为结果

基于this similar question,你可以试试这个代码:

x <- array(1:24, c(4,3,2))
sapply(1:3, 
       function(y) sapply(1:ncol(x[, y, ]), 
                          function(z) matrix(x[,y,z], ncol=2, nrow=2), 
                          simplify="array"), 
       simplify="array")

结果的维度是2 2 2 3

其实这里的问题是,当x是二维以上的数组时,需要两次不同的调用才能应用。在问题的最后一个例子中(x <- array(1:24, c(4,3,2))),我们想对第三维的每个元素应用一个函数,该函数将矩阵函数应用于第二维的每个元素。