Reputation: 188
I have a three-dimensional array in R, e.g.
a <- array(1:24, dim=c(2,3,4))
I'll refer to the dimensions of this array as rows, columns and layers. I have a second variable, b, which is intended to provide an index to that array, e.g.
b <- array(c(1,4,3,2,2,1), dim=c(2,3))
I would like to get a two-dimensional variable, d that contains the value from 3D variable a in the layer specified by b for each row and column in a and b. So for example, d[1, 1] <- a[1, 1 , b[1, 1]]
and d[2, 3] <- a[2, 3, b[2, 3]]
and so on. In this example, I should end up with:
d == array(c(1, 20, 15, 10, 11, 6), dim=c(2, 3))
What's the most efficient way to do this?
Upvotes: 0
Views: 388
Reputation: 79288
The fastest way you can do this:
structure(a[cbind(c(row(b)),c(col(b)),c(b))],.Dim=dim(b))
[,1] [,2] [,3]
[1,] 1 15 11
[2,] 20 10 6
Upvotes: 2
Reputation: 1138
I'd suggest using expand.grid
as well, but I would generate an index matrix to adress every entry of a
at once.
ind <- as.matrix(expand.grid(1:nrow(b), 1:ncol(b)))
d <- matrix(a[cbind(ind, b[ind])], ncol = ncol(b), nrow = nrow(b))
I think this is slightly more efficient
Upvotes: 1
Reputation: 389105
We can use expand.grid
to get all combinations of rows and columns in b
and then use mapply
to get the corresponding output from a
using indexing. We use relist
to make the d
matrix same as b
.
df <- expand.grid(row = 1:nrow(b), col = 1:ncol(b))
d <- relist(mapply(function(x, y) a[x, y, b[x, y]], df$row, df$col), b)
d
# [,1] [,2] [,3]
#[1,] 1 15 11
#[2,] 20 10 6
where df
is
row col
#1 1 1
#2 2 1
#3 1 2
#4 2 2
#5 1 3
#6 2 3
Upvotes: 1