Hi, On ocasion, you need to subscript an array that has an arbitrary (ie. not known in advance) number of dimensions. How do you deal with these situations? It appears that it is not possible use a list as an index, for instance this fails:> x <- array(NA, c(2,2,2)) > x[list(TRUE,TRUE,2)]Error in x[list(TRUE, TRUE, 2)] : invalid subscript type 'list' The only way I know is using do.call() but it's rather ugly. There must be a better way!!> do.call('[', c(list(x), TRUE, TRUE, 2))[,1] [,2] [1,] NA NA [2,] NA NA Any idea? Regards, Ernest
On 02/11/11 11:14, Ernest Adrogu? wrote:> Hi, > > On ocasion, you need to subscript an array that has an arbitrary > (ie. not known in advance) number of dimensions. How do you deal with > these situations? > It appears that it is not possible use a list as an index, for > instance this fails: > >> x<- array(NA, c(2,2,2)) >> x[list(TRUE,TRUE,2)] > Error in x[list(TRUE, TRUE, 2)] : invalid subscript type 'list' > > The only way I know is using do.call() but it's rather ugly. There > must be a better way!! > >> do.call('[', c(list(x), TRUE, TRUE, 2)) > [,1] [,2] > [1,] NA NA > [2,] NA NA > > Any idea?It's possible that matrix subscripting might help you. E.g.: a <- array(1:60,dim=c(3,4,5)) m <- matrix(c(1,1,1,2,2,2,3,4,5,1,2,5),byrow=TRUE,ncol=3) a[m] [1] 1 17 60 52 You can build "m" to have the same number of columns as your array has dimensions. It's not clear to me what result you want in your example. cheers, Rolf Turner
Leaving the indices empty should give you what I'm guessing you want/expect. x[,,2] #. TRUE would also work, just not in a list. David. On Nov 1, 2011, at 6:14 PM, Ernest Adrogu? <nfdisco at gmail.com> wrote:> Hi, > > On ocasion, you need to subscript an array that has an arbitrary > (ie. not known in advance) number of dimensions. How do you deal with > these situations? > It appears that it is not possible use a list as an index, for > instance this fails: > >> x <- array(NA, c(2,2,2)) >> x[list(TRUE,TRUE,2)] > Error in x[list(TRUE, TRUE, 2)] : invalid subscript type 'list' > > The only way I know is using do.call() but it's rather ugly. There > must be a better way!! > >> do.call('[', c(list(x), TRUE, TRUE, 2)) > [,1] [,2] > [1,] NA NA > [2,] NA NA > > Any idea? > > Regards, > Ernest > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
Here's a hack, but perhaps you might want to rethink what type of output you want. # Function: g <- function(arr, lastSubscript = 1) { n <- length(dim(arr)) commas <- paste(rep(',', n - 1), collapse = '') .call <- paste('arr[', commas, lastSubscript, ']', sep = '') eval(parse(text = .call)) } # Examples: a1 <- array(1:8, c(2, 2, 2)) a2 <- array(1:16, c(2, 2, 2, 2)) a3 <- array(1:32, c(2, 2, 2, 2, 2)) g(a1, 2) g(a2, 2) g(a3, 2) Notice the subscripting in the last two examples - if you only want one submatrix returned, then try this: h <- function(arr, lastSubscript = c(1)) { n <- length(dim(arr)) subs <- if(length(lastSubscript) > 1) paste(lastSubscript, collapse = ',') else lastSubscript .call <- paste('arr[,,', subs, ']', sep = '') eval(parse(text = .call)) } h(a2, c(1, 1)) h(a3, c(2, 1, 1)) These functions have some ugly code, but I think it does what you were looking for. Hopefully someone can devise a more elegant solution. Dennis HTH 2011/11/1 Ernest Adrogu? <nfdisco at gmail.com>:> Hi, > > On ocasion, you need to subscript an array that has an arbitrary > (ie. not known in advance) number of dimensions. How do you deal with > these situations? > It appears that it is not possible use a list as an index, for > instance this fails: > >> x <- array(NA, c(2,2,2)) >> x[list(TRUE,TRUE,2)] > Error in x[list(TRUE, TRUE, 2)] : invalid subscript type 'list' > > The only way I know is using do.call() but it's rather ugly. There > must be a better way!! > >> do.call('[', c(list(x), TRUE, TRUE, 2)) > ? ? [,1] [,2] > [1,] ? NA ? NA > [2,] ? NA ? NA > > Any idea? > > Regards, > Ernest > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
2011/11/1 Ernest Adrogu? <nfdisco at gmail.com>:> Hi, > > On ocasion, you need to subscript an array that has an arbitrary > (ie. not known in advance) number of dimensions. How do you deal with > these situations? > It appears that it is not possible use a list as an index, for > instance this fails: > >> x <- array(NA, c(2,2,2)) >> x[list(TRUE,TRUE,2)] > Error in x[list(TRUE, TRUE, 2)] : invalid subscript type 'list' > > The only way I know is using do.call() but it's rather ugly. There > must be a better way!! > >> do.call('[', c(list(x), TRUE, TRUE, 2)) > ? ? [,1] [,2] > [1,] ? NA ? NA > [2,] ? NA ? NA > > Any idea?> library("R.utils") > x <- array(1:8, dim=c(2,2,2)) > x, , 1 [,1] [,2] [1,] 1 3 [2,] 2 4 , , 2 [,1] [,2] [1,] 5 7 [2,] 6 8> extract(x, "3"=2), , 1 [,1] [,2] [1,] 5 7 [2,] 6 8 For more details/examples, see help("extract.array", package="R.utils"). It doesn't to assignments, but could be achieved by: idxs <- array(seq(along=x), dim=dim(x)) idxs <- extract(idxs, "3"=2) x[idxs] <- ... base::arrayInd() may also be useful. /Henrik> > Regards, > Ernest > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >