In R, let's have an array and a matrix:
a <- array(rep(1:3, each = 4), dim = c(2, 2, 3))
b <- matrix(seq(0, 1, length.out = 6), nrow = 2, ncol = 3)
I want to use an function that utilises matrices from a
along the 3rd dimension and columns in b
as its two arguments. For this example, we can assume that my function is:
myfunc <- function(x, y) { x * y }
I want the operation to return a 3D array. My current solution is to use sapply
for indices and transform the resulting list into an array subsequently:
res <- sapply(1:dim(a)[[3]], FUN = \(x) myfunc(a[, , x], b[, x]), simplify = FALSE)
res <- abind::abind(res, along = 3)
Is there another way how to achieve this operation that would directly result in a 3D array? I experimented with sweep
, but failed.
A possible approach is to change your 3D array and matrix into lists and use mapply
. Here I wrote a simple function (to_list()
) which does the array to list transformation (by default along the last array dimension).
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')
The sapply
line does the same thing as your abind
line.