我想在矩阵的一个边距(我的例子中的列)上应用一个函数。问题是函数返回矩阵,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')
答案 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
并使用lapply
在columns
上应用您的功能(因为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
),我们希望将第三维的每个元素应用于第二维的每个元素的函数。