在多个数组上应用R函数,返回相同大小的数组

时间:2015-06-20 23:24:09

标签: arrays r plyr

我有两个2x2矩阵数组,我想在每对2x2矩阵上应用一个函数。这是一个最小的例子,将A中的每个矩阵乘以B中的相应矩阵

A <- array(1:20, c(5,2,2))
B <- array(1:20, c(5,2,2))
n <- nrow(A)
# Desired output: array with dimension 5x2x2 that contains 
# the product of each pair of 2x2 matrices in A and B.
C <- aperm(sapply(1:n, function(i) A[i,,]%*%B[i,,], simplify="array"), c(3,1,2))

这需要两个数组,每个数组有5个2x2矩阵,并将每对2x2矩阵相乘,所需的结果为C.

我当前的代码是这个丑陋的最后一行,使用sapply循环遍历第一个数组维度并分别从A和B中拉出每个2x2矩阵。然后我需要用aperm()置换数组维度以便与原始数组相同的顺序(sapply(...,simplify =&#34; array&#34;)使用第三维而不是第一维索引每个2x2矩阵。)

有更好的方法吗?我讨厌那个丑陋的函数(i),这实际上只是伪造for循环的一种方式。并且aperm()调用使得可读性更低。我现在的工作正常;我只是在寻找更像是惯用的东西。

mapply()将采用多个列表或向量,但它似乎不适用于数组。 plyr的aaply()也很接近,但它并没有多次输入。我最接近的是使用带有aaply()的abind()将A和B一次打包到一个包含2个矩阵的数组中,但这并不是很有效(它只能得到前两个条目) ;某处我的索引已关闭):

aaply(.data=abind(A,B,along=0), 1, function(ab) ab[1,,]%*%ab[2,,])

无论如何,这并不是更清洁或更清晰!

我试图将其作为一个最小的例子,但我的真实用例需要一个更复杂的矩阵对函数(我也喜欢将它扩展到两个以上的数组),所以我正在寻找能够概括和扩展的东西。

3 个答案:

答案 0 :(得分:2)

D <- aaply(abind(A, B, along = 4), 1, function(x) x[,,1] %*% x[,,2])

这是使用abindaaply的有效解决方案。

答案 1 :(得分:1)

有时for循环是最容易遵循的。它还概括和扩展:

n <- nrow(A)
C <- A
for(i in 1:n) C[i,,] <- A[i,,] %*% B[i,,]

答案 2 :(得分:0)

R的列表基础设施比数组要好得多(所以),所以我也可以通过将数组转换为这样的矩阵列表来实现它:

A <- alply(A, 1, function(a) matrix(a, ncol=2, nrow=2))
B <- alply(A, 1, function(a) matrix(a, ncol=2, nrow=2))
mapply(function(a,b) a%*%b, A, B, SIMPLIFY=FALSE)

我认为这比我上面的内容更直接,但我仍然希望听到更好的想法。