Reputation: 934
I need a function that subsets a multidimensional array in R; the catch is I don't know which dimension or the length along that dimension until the function is called.
# subset a 3-d array; leave dims 1 and 2, but start 3rd dim at its 11th value
mydim <- dim(myarr)
myarr[, , 11:mydim[3]]
# subset a 4-d array; leave dims 1, 3 and 4, but start 2rd dim at its 8th value
mydim <- dim(myarr)
myarr[, 8:mydim[2], , ]
I always need to subset along exactly one dimension, and the subsetting is always to start at some value other than 1. I also need to preserve the array structure, so matrix indexing into arrays does not look appealing. Thanks in advance.
Upvotes: 5
Views: 144
Reputation: 19454
Here's an option that takes advantage of the possibility of subsetting an array based on a matrix:
myarr <- array(1:(2*3*4), dim = c(2, 3, 4))
myfun <- function(arr, from, len, Dim){
dimArr <- dim(arr)
if(missing(len)){
subIdx <- from:dimArr[Dim]
} else {
subIdx <- from:(from + len - 1)
}
arrD <- lapply(as.list(dimArr), seq_len)
arrD[[Dim]] <- subIdx
subMat <- as.matrix(do.call(expand.grid, arrD))
array(arr[subMat], dim = lapply(arrD, length))
}
> myfun(myarr, 2, 1, 3)
, , 1
[,1] [,2] [,3]
[1,] 7 9 11
[2,] 8 10 12
> myfun(myarr, 2, Dim = 3)
, , 1
[,1] [,2] [,3]
[1,] 7 9 11
[2,] 8 10 12
, , 2
[,1] [,2] [,3]
[1,] 13 15 17
[2,] 14 16 18
, , 3
[,1] [,2] [,3]
[1,] 19 21 23
[2,] 20 22 24
Upvotes: 1
Reputation: 55350
Here we go! Tested too...
sampleArray <- function(myarr, dm, start, leng) {
## arguments:
## dm is the dimension selected
## start is where in dm to being
## leng is how far in from dm to go
## start+leng <= dim(myarr)[dm]
leng <- leng-1
# error check
if (start+leng > dim(myarr)[dm])
warning("leng too long by ", start+leng - dim(myarr)[dm], ".")
#initialize a vector of all TRUE
indx <- as.list(rep(TRUE, length(dim(myarr))))
# change the required dimension to the required sequence
indx[[dm]] <- seq(start, start+leng)
indx <- paste(indx, collapse=",")
expr <- paste0("myarr[", indx, "]")
# return the appropriate sample
eval(parse(text=expr))
}
example:
# sample array
myarr <- array(1:2250, dim=c(15, 10, 15))
# example call
sampleArray(myarr, dm=2, start=4, leng=3)
Upvotes: 1