[R] building a subscript programatically
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@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.
Re: [R] building a subscript programatically
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 __ R-help@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.
Re: [R] building a subscript programatically
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é nfdi...@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@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. __ R-help@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.
Re: [R] building a subscript programatically
Yes,Ii did fail to read your post carefully and agree do.call seems roundabout, but alternatives look even more tortured. (You might want to include more context in the future.) On Nov 1, 2011, at 8:30 PM, Ernest Adrogué eadro...@gmx.net wrote: 1/11/11 @ 20:22 (-0400), Comcast escriu: 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. Exactly, but this only works if x has three dimensions. What I want is x[,,2] if x has three dimensions, x[,,,2] if it has four, and so forth. I cannot hard code [,,2] because I do not know how many dimensions x will have, instead the subscript has to be built on the fly. Ernest __ R-help@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.
Re: [R] building a subscript programatically
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é nfdi...@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@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. __ R-help@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.
Re: [R] building a subscript programatically
1/11/11 @ 20:22 (-0400), Comcast escriu: 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. Exactly, but this only works if x has three dimensions. What I want is x[,,2] if x has three dimensions, x[,,,2] if it has four, and so forth. I cannot hard code [,,2] because I do not know how many dimensions x will have, instead the subscript has to be built on the fly. Ernest __ R-help@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.
Re: [R] building a subscript programatically
2/11/11 @ 13:10 (+1300), Rolf Turner escriu: 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. Sorry for not stating my problem in a more clear way. What I want is, given an array of n dimensions, overwrite it by iteratating over its outermost dimension... OK, in the previous example, I would like to do x - array(NA, c(2,2,2)) for (i in 1:2) { x[,,i] - 0 } As you can see, the index I used in the loop only works in the case of three-dimensional arrays, if x was two dimensional I would have had to write for (i in 1:2) { x[,i] - 0 } So, when the dimensions of x are not known in advance, how would you write such a loop? Your solution of using a matrix might work (I haven't been able to check it yet). Cheers, Ernest __ R-help@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.
Re: [R] building a subscript programatically
On 02/11/11 13:43, Ernest Adrogué wrote: SNIP Sorry for not stating my problem in a more clear way. What I want is, given an array of n dimensions, overwrite it by iteratating over its outermost dimension... OK, in the previous example, I would like to do x- array(NA, c(2,2,2)) for (i in 1:2) { x[,,i]- 0 } As you can see, the index I used in the loop only works in the case of three-dimensional arrays, if x was two dimensional I would have had to write for (i in 1:2) { x[,i]- 0 } SNIP U, how does this differ from just setting *all* entries of x equal to 0, e.g.: x[] - 0 ??? cheers, Rolf Turner __ R-help@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.
Re: [R] building a subscript programatically
2011/11/1 Ernest Adrogué nfdi...@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,]13 [2,]24 , , 2 [,1] [,2] [1,]57 [2,]68 extract(x, 3=2) , , 1 [,1] [,2] [1,]57 [2,]68 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@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. __ R-help@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.