Select along one of n dimensions in array
multidimensional-array, r
Solution
I spent quite a lot of time figuring out the fastest way to do this for plyr, and the best I could come up with was manually constructing the call to `[`:
index_array <- function(x, dim, value, drop = FALSE) {
# Create list representing arguments supplied to [
# bquote() creates an object corresponding to a missing argument
indices <- rep(list(bquote()), length(dim(x)))
indices[[dim]] <- value
# Generate the call to [
call <- as.call(c(
list(as.name("["), quote(x)),
indices,
list(drop = drop)))
# Print it, just to make it easier to see what's going on
print(call)
# Finally, evaluate it
eval(call)
}
(You can find more information about this technique at https://github.com/hadley/devtools/wiki/Computing-on-the-language)
You can then use it as follows:
A <- array(data=NA, dim=c(2,4,4), dimnames=list(c("x","y"),NULL,NULL))
index_array(A, 2, 2)
index_array(A, 2, 2, drop = TRUE)
index_array(A, 3, 2, drop = TRUE)
It would also generalise in a straightforward way if you want to extract based on more than one dimension, but you'd need to rethink the arguments to the function.
Problem
I have an array in R, created by a function like this: ``` A <- array(data=NA, dim=c(2,4,4), dimnames=list(c("x","y"),NULL,NULL)) ``` And I would like to select along one dimension, so for the example above I would have: ``` A["x",,] dim(A["x",,]) #[1] 4 4 ``` Is there a way to generalize if I do not know in advance how many dimensions (in addition to the named one I want to select by) my array might have? I would like to write a function that takes input that might formatted as A above, or as: ``` B <- c(1,2) names(B) <- c("x", "y") C <- matrix(1, 2, 2, dimnames=list(c("x","y"),NULL)) ``` Background The general background is that I am working on an ODE model, so for deSolve's ODE function it must take a single named vector with my current state. For some other functions, like calculating phase-planes/direction fields, it would be more practical to have a higher-dimensional array to apply the differential equation to, and I would like to avoid having many copies of the same function, simply with different numbers of commas after the dimension I want to select.