1) apply Use apply
over the indexes that do not correspond to B taking the first of each. This is concise, does not involve explicit reshaping and uses only base R.
apply(arr, which(vals != "B"), head, 1)
Tests
set.seed(123)
vals = c("A","B","C")
arr = array(runif(5^3), dim = c(5,5,5))
identical(apply(arr, which(vals != "B"), head, 1), arr[,1,])
## [1] TRUE
set.seed(123)
vals = c("A","C","B","D")
arr = array(runif(5^4), dim = c(5,5,5,5))
identical(apply(arr, which(vals != "B"), head, 1), arr[,,1,])
## [1] TRUE
set.seed(123)
vals = c("B","A","C","D","E")
arr = array(runif(5^5), dim = c(5,5,5,5,5))
identical(apply(arr, which(vals != "B"), head, 1), arr[1,,,,])
## [1] TRUE
2) extract_dim The listarrays package has a function to do this.
library(listarrays)
extract_dim(arr, which(vals == "B"), 1)
Tests
library(listarrays)
set.seed(123)
vals = c("A","B","C")
arr = array(runif(5^3), dim = c(5,5,5))
identical(extract_dim(arr, which(vals == "B"), 1) , arr[,1,])
## [1] TRUE
set.seed(123)
vals = c("A","C","B","D")
arr = array(runif(5^4), dim = c(5,5,5,5))
identical(extract_dim(arr, which(vals == "B"), 1), arr[,,1,])
## [1] TRUE
set.seed(123)
vals = c("B","A","C","D","E")
arr = array(runif(5^5), dim = c(5,5,5,5,5))
identical(extract_dim(arr, which(vals == "B"), 1), arr[1,,,,])
## [1] TRUE
3) aperm If we knew that arr
has at most 5 dimensions we could make each number of dimensions a separate case. Extend to the maximum if there can be more than 5. This only uses base R.
get_dim <- function(arr, vals, val = "B", i = 1) {
a <- aperm(arr, order(vals != val))
switch(length(dim(arr)), a[i], a[i,], a[i,,], a[i,,,], a[i,,,,], a[i,,,,,])
}
set.seed(123)
vals = c("A","B","C")
arr = array(runif(5^3), dim = c(5,5,5))
identical(get_dim(arr, vals) , arr[,1,])
## [1] TRUE
set.seed(123)
vals = c("A","C","B","D")
arr = array(runif(5^4), dim = c(5,5,5,5))
identical(get_dim(arr, vals), arr[,,1,])
## [1] TRUE
set.seed(123)
vals = c("B","A","C","D","E")
arr = array(runif(5^5), dim = c(5,5,5,5,5))
identical(get_dim(arr, vals), arr[1,,,,])
## [1] TRUE