如何在返回 3D 数组的同时对 3D 数组和矩阵执行操作?

问题描述 投票:0回答:2

在 R 中,我们有一个数组和一个矩阵:

a <- array(rep(1:3, each = 4), dim = c(2, 2, 3))
b <- matrix(seq(0, 1, length.out = 6), nrow = 2, ncol = 3)

我想使用一个函数,该函数利用

a
沿第三维的矩阵和
b
中的列作为其两个参数。对于这个例子,我们可以假设我的函数是:

myfunc <- function(x, y) { x * y }

我希望该操作返回一个 3D 数组。我当前的解决方案是使用

sapply
作为索引,然后将结果列表转换为数组:

res <- sapply(1:dim(a)[[3]], FUN = \(x) myfunc(a[, , x], b[, x]), simplify = FALSE) 
res <- abind::abind(res, along = 3)

是否有另一种方法可以实现直接生成 3D 数组的操作?我尝试过

sweep
,但失败了。

r multidimensional-array sapply
2个回答
1
投票

一种可能的方法是将 3D 数组和矩阵更改为列表并使用

mapply
。在这里,我编写了一个简单的函数(
to_list()
),它执行数组到列表的转换(默认情况下沿着最后一个数组维度)。

to_list <- function(x, along=length(dim(x))) {
  apply(x, along, identity, simplify=F)
}

res <- mapply(myfunc, to_list(b), to_list(a), SIMPLIFY=F)
res <- sapply(res, identity, simplify='array')

sapply
线与您的
abind
线执行相同的操作。


1
投票

我们可以使用

aperm
转置多维数组。

f <- \(A, m) aperm(aperm(A, c(3, 2, 1))*as.vector(t(m)), c(2, 3, 1))

f(a, b)
# , , 1
# 
#      [,1] [,2]
# [1,]  0.0  0.0
# [2,]  0.2  0.2
# 
# , , 2
# 
#      [,1] [,2]
# [1,]  0.8  0.8
# [2,]  1.2  1.2
# 
# , , 3
# 
#      [,1] [,2]
# [1,]  2.4  2.4
# [2,]  3.0  3.0

stopifnot(all.equal(res, f(a, b), check.attributes=FALSE))  ## res from OP
© www.soinside.com 2019 - 2024. All rights reserved.