Is there a way of elegantly specify a slice in a multidimensional array in R, whereby the number of dimensions is not known beforehand?
For instance, for a 5-dimensional array, slicing out the last dimension can be done using
fourdimslice <- fivedimarray[,,,,1]
but I'l like to code this for arbitrary dimensions, something like
slice <- arbitrarydimarray(dim=5, index=1)
I've not been able to understand if do.call('[', ...)
would be an approach. I've also tried named dimensions, but a[fifth=1]
is not interpreted the way I would want here.
I suppose functions like apply()
need to do similar things.
You can use asub
, from the abind
package.
# Sample data: a 5-dimensional array
x <- array(seq_len(prod(2:6)), dim=2:6)
library(abind)
str( asub(x, 1, 5) )
# int [1:2, 1:3, 1:4, 1:5] 1 2 3 4 5 6 7 8 9 10 ...
str( x[,,,,1] )
# int [1:2, 1:3, 1:4, 1:5] 1 2 3 4 5 6 7 8 9 10 ...
all( asub(x, 1, 5) == x[,,,,1] )
# [1] TRUE
If you don't want to use the abind
package, it looks like you can use a two-liner based on slice.index
. I don't know which is more efficient ...
x <- array(seq_len(prod(2:6)), dim=2:6)
library(abind)
str( y <- asub(x, 1, 5) )
Or:
z <- x[slice.index(x,5)==1]
This extracts the right elements but the dimensions get lost. To restore them:
dim(z) <- dim(x)[-5]
(You could obviously wrap this in an appropriate function.) Test:
all.equal(y,z) ## TRUE
Here is a bizarre solution to extract the first slice
your.array=array(runif(27),dim=c(3,3,3)) # this is to create an example of array from which you want a slice.
array(your.array[1:prod(dim(your.array)[-1])],dim(your.array)[-1])