在应用中从矩阵转换为向量的输出
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))
),我们想对第三维的每个元素应用一个函数,该函数将矩阵函数应用于第二维的每个元素。
我想在矩阵的一个边距(在我的例子中是列)上应用一个函数。问题是函数 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))
),我们想对第三维的每个元素应用一个函数,该函数将矩阵函数应用于第二维的每个元素。