想象一下,你有一个包含行,列和图层的三维数组:
A <- array (1:27, c(3,3,3))
并想象你有一个函数将矩阵作为输入并返回一个矩阵作为输出,如t
。
如何将函数应用于数组的每一层,返回与第一层相同大小的另一个数组?
我觉得我应该能够以apply
的方式做到这一点,但我做不到。
奖金问题(如果你回答这个问题,我将非常感激):这样做是否更快,或者为每个层矩阵制作一个列表并将lapply
函数添加到它们中?
-
编辑:请不要认为这个问题已经回答了 - 下面的答案没有回答这个问题。
答案 0 :(得分:5)
您必须考虑要提取值的边距。
您可以通过应用维度1和2(行和列来换取更好的单词)来转置每个3rd
维度矩阵
apply(A,1:2,t)
, , 1
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 10 11 12
[3,] 19 20 21
, , 2
[,1] [,2] [,3]
[1,] 4 5 6
[2,] 13 14 15
[3,] 22 23 24
, , 3
[,1] [,2] [,3]
[1,] 7 8 9
[2,] 16 17 18
[3,] 25 26 27
您还可以使用可能更直观的plyr
和aaply
library(plyr)
aaply(A,3,t)
, , = 1
X1 1 2 3
1 1 4 7
2 10 13 16
3 19 22 25
, , = 2
X1 1 2 3
1 2 5 8
2 11 14 17
3 20 23 26
, , = 3
X1 1 2 3
1 3 6 9
2 12 15 18
3 21 24 27
至于哪个更快lapply
或apply
,我想也许lapply
会赢,但你仍然需要考虑你想要提取矩阵的边距从
我通常发现在一个维度上思考要容易得多。如果地球平坦,一切都会更直接!
答案 1 :(得分:1)
转置的另一种可能性是函数aperm
。
A <- array (1:27, c(3,3,3))
# aperm permute the dimensions in the given order
# here we want to permute dimension 1 and 2
# so the new order is 2-1-3 instead of 1-2-3
aperm(A, c(2,1,3))
, , 1
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
, , 2
[,1] [,2] [,3]
[1,] 10 11 12
[2,] 13 14 15
[3,] 16 17 18
, , 3
[,1] [,2] [,3]
[1,] 19 20 21
[2,] 22 23 24
[3,] 25 26 27
就每个层应用一个函数(比如你想将每个层乘以不同的值)而言,这是另一种可能性:
vec <- c(1,5,3)
lapply(seq_along(vec), function(x)A[,,x]*vec[x])
[[1]]
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
[[2]]
[,1] [,2] [,3]
[1,] 50 65 80
[2,] 55 70 85
[3,] 60 75 90
[[3]]
[,1] [,2] [,3]
[1,] 57 66 75
[2,] 60 69 78
[3,] 63 72 81
但是当你看到它创建一个列表时,它需要使用函数simplify2array
再多一步:
simplify2array(lapply(seq_along(vec),function(x)A[,,x]*vec[x]))
, , 1
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
, , 2
[,1] [,2] [,3]
[1,] 50 65 80
[2,] 55 70 85
[3,] 60 75 90
, , 3
[,1] [,2] [,3]
[1,] 57 66 75
[2,] 60 69 78
[3,] 63 72 81
或直接使用sapply
:
sapply(seq_along(vec), function(x)A[,,x]*vec[x], simplify="array")
, , 1
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
, , 2
[,1] [,2] [,3]
[1,] 50 65 80
[2,] 55 70 85
[3,] 60 75 90
, , 3
[,1] [,2] [,3]
[1,] 57 66 75
[2,] 60 69 78
[3,] 63 72 81