Skip to Content

How to index a multidimensional R array dynamically?

I am working on some data in R that consist of four-dimensional arrays composed of three spatial dimensions and a time dimension: x, y, z, t. For some of my analyses, I would like to obtain all of the data in the time dimension for a set of spatial coordinates x, y, z. Thus far, I have used the which function to obtain the indices of the spatial locations of interest. But when I go to obtain all relevant data in the time dimension corresponding to the spatial locations, I cannot find an elegant R solution and have resorted to using repmat, a ported MATLAB function.

a4d <- array(rnorm(10000), rep(10,4)) #x, y, z, t
 
#arbitrary set of 3d spatial indices x, y, z (here, using high values at first timepoint)
indices <- which(a4d[,,,1] > 2, arr.ind=TRUE)
str(indices)
 
# int [1:20, 1:3] 10 2 6 5 8 2 6 8 2 10 ...
# - attr(*, "dimnames")=List of 2
# ..$ : NULL
# ..$ : chr [1:3] "dim1" "dim2" "dim3"
 
#Now, I would like to use these indices to get data x, y, z for all t
 
#Intuitive, but invalid, syntax (also not clear what the structure of the data would be)
#a4d[indices,]
 
#Ugly, but working, syntax
library(pracma)
 
#number of timepoints
nt <- dim(a4d)[4]
 
#create a 4d lookup matrix
lookup <- cbind(repmat(indices, nt, 1), rep(1:nt, each=nrow(indices)))
 
#obtain values at each timepoint for indices x, y, z
result <- cbind(lookup, a4d[lookup])

This solution works okay for the stated purpose, but seems ugly conceptually. Ideally, I would like a 2-dimensional matrix at the end: index x time. So, in this case, with 20 x, y, z coordinates in the lookup, and 10 timepoints, a 20 x 10 matrix would be ideal where rows represent each row of indices (don't need to preserve the x, y, z, values necessarily) and each column is a timepoint.

Is there is a good way to do this in R? I have played around with do.call("[", list ...
etc. and using outer and prod, but these haven't worked as I had hoped.

Thanks for any suggestions!
Michael