Skip to content

Instantly share code, notes, and snippets.

@goldingn
Created October 8, 2014 10:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goldingn/407bb7b9eb602eb60b81 to your computer and use it in GitHub Desktop.
Save goldingn/407bb7b9eb602eb60b81 to your computer and use it in GitHub Desktop.
return the elements of an array of unknown dimension at the ith index on the first dimension
geti <- function (x, i) {
# return the elements of an array `x` of unknown dimension
# at the ith index of its first dimension
# throw an error if x isn't an array
stopifnot(is.array(x))
# get the dimension of x
k <- length(dim(x))
# build an expression as text
expr <- paste('x[i,',
paste(rep(',', k - 2), collapse = ' '),
']')
# evaluate it
ans <- eval(parse(text = expr))
# return this
return (ans)
}
# # test it
# # make an array
# arr <- array(rnorm(3 * 4 * 2),
# dim = c(3, 4, 2))
# # print it
# arr
#
# # get the elements at 2 on the first dimension
# geti(arr, 2)
@richfitz
Copy link

richfitz commented Oct 8, 2014

Eew. Nasty problem. From the look of ?"[" there is no "right" way to do this, which is weird. But I guess arrays come in small enough numbers of dimensions you could probably just work with if/else blocks.

Here's marginally less hacky version that avoids eval(parse()) (see fortunes::fortune("parse")):

geti <- function(x, i, dim=1L) {
  k <- length(dim(x))
  idx <- rep(alist(,)[1], k) # dirty hack
  idx[dim] <- i
  eval(as.call(c(list(quote(`[`), x), idx)))
}

(this generalises your solution so passing a number other than 1 in to the dim argument subsets the dim'th dimension, so geti(x, 1, 2) gets the first slice through the second dimension).

@goldingn
Copy link
Author

goldingn commented Oct 8, 2014

Thanks!

@BenBondLamberty pointed me towards the abind package, wherein the asub function does the trick, in the same style as your answer. So the simplest solution seems to be:

library(abind)
asub(x, i, 1)

For an array x and index i on the first dimension

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment