Let\'s say I have a multi-dimensional array called pi
, and its number of dimensions isn\'t known until the runtime:
dims <- rep(3, dim_count)
do.call()
is an option:
dim_count <- 5
indexes <- c(1, 2, 2, 2, 3)
dims <- rep(3, dim_count)
pi <- array(seq_len(prod(dims)), dims)
do.call(`[`, c(list(x = pi), as.list(indexes)))
Which gives:
> do.call(`[`, c(list(x = pi), as.list(indexes)))
[1] 202
> pi[1, 2, 2, 2, 3]
[1] 202
The tricky bit is getting the list of arguments in the right format. pi
should be the first argument to "["
(or named as argument x
, see ?"["
), whilst we want each element of indexes
itself to be a component of the supplied list, not a vector within that list. Hence the convoluted c(list(x = pi), as.list(indexes))
.
An alternative way to construct the argument list which might be easier to follow is:
ARGS <- vector("list", length = dim_count + 1)
ARGS[[1]] <- pi
ARGS[2:length(ARGS)] <- indexes
do.call("[", ARGS)
which gives
> do.call("[", ARGS)
[1] 202
> pi[1, 2, 2, 2, 3]
[1] 202
Making use of a little known usage of [
:
When indexing arrays by
[
a single argumenti
can be a matrix with as many columns as there are dimensions ofx
; the result is then a vector with elements corresponding to the sets of indices in each row ofi
.
you can simply do:
pi[matrix(indexes, 1)]
do.call("[",...)
seems to work.
indexes <- c(1,2,3,3,3)
pi[1,2,3,3,3] <- 17 ## so we know if we succeeded or not
do.call("[",c(list(pi),as.list(indexes)))
Note that your example wouldn't work -- your dimensions were all 3, but some of your index elements were >3 ...