is there a way to dynamically access an array dimension (ideally without reshaping)?
I have an n-dimensional array arr
as well as a named order of dimensions vals
.
Both the number of dimensions for arr
and the order of vals
may change. I always want to access the first entry of arr
for the dimension where vals
equals B
.
In the following I have provided three examples demonstrating what I want:
#Example 1
vals = c("A","B","C")
idx = grep("B",vals)
arr = array(runif(5^3), dim = c(5,5,5))
arr[,1,] # B is in second dimension
#Example 2
vals = c("A","C","B","D")
idx = grep("B",vals)
arr = array(runif(5^4), dim = c(5,5,5,5))
arr[,,1,] #B is in third dimension
#Example 3
vals = c("B","A","C","D","E")
idx = grep("B",vals)
arr = array(runif(5^5), dim = c(5,5,5,5,5))
arr[1,,,,] #B is in first dimension
I'm absolutely clueless how to approach this.
I think the simplest way is using asplit
(but seems not as efficient as eval
approach)
asplit(arr, idx)[[1]]
You can also try apply
like below
array(apply(arr, idx, c)[, 1], dim(arr)[-idx])
and verify it, for example
> set.seed(0)
> vals <- c("B", "A", "C", "D", "E")
> idx <- grep("B", vals)
> arr <- array(runif(5^5), dim = c(5, 5, 5, 5, 5))
> a <- arr[1, , , , ] # B is in first dimension
> b <- array(apply(arr, idx, c)[, 1], dim(arr)[-idx])
> all.equal(a, b)
[1] TRUE
If you are bothered by apply
and its indexing logic, you can parse the string like
b <- eval(str2lang(sprintf("arr[%s]", toString(replace(rep("", length(dim(arr))), idx, "1")))))
and you can obtain
> all.equal(a, b)
[1] TRUE