在apply中将输出从矩阵转换为矢量

时间:2016-10-25 13:10:49

标签: r matrix apply

我想在矩阵的一个边距(我的例子中的列)上应用一个函数。问题是函数返回矩阵,apply将其转换为向量,以便返回矩阵。我的目标是获得三维数组。这是一个例子(注意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()unlist()列的内容。

修改 此外,该解决方案应该可以轻松应用于任何维度阵列,可以选择MARGIN我的解决方案不是。

例如,我想返回4维数组。

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')

2 个答案:

答案 0 :(得分:4)

一点也不复杂。只需使用

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

矩阵和通用数组按列存储在物理地址中的1D长数组中。您可以重新分配维度。

好的,这可能是你想要做的一般事情:

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

答案 1 :(得分:2)

您可以尝试将matrix转换为data.frame并使用lapplycolumns上应用您的功能(因为data.frame是{ {1}}),它将返回list,其中每个元素代表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

EDIT2:尝试获得结果

根据this similar question,您可以尝试以下代码:

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

结果的维度为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")

实际上,这里的问题是当x是一个超过2维的数组时,它需要两个不同的调用。在问题的最后一个例子中(使用2 2 2 3),我们希望将第三维的每个元素应用于第二维的每个元素的函数。