Re: [R] Subsetting an array by a vector of dimensions

From: Wolfgang Huber <huber_at_ebi.ac.uk>
Date: Fri, 11 Jul 2008 23:34:06 +0100

Kenn Konstabel wrote:
> What is "wrong" is, I think, that you can't write a substitute for
> x[1,2,] this way. (Or, in general, empty indexes won't work.)
>
> A related question - Is there a way to replace x[1,2,] with "["(1,2,
> *something clever*) ?
>
> Kenn

Dear Kenn,

I can:

 > do.call("[", list(x,1,2,TRUE))
[1] 3 9 15 21

See also http://134.148.236.121/R/help/06/01/19403.html

In principle this works also for assignment, but the following benchmark shows a big performance hit:

x = array(1:1e6, dim=c(100,100,100))

system.time({

   for(i in 1:100) x = do.call("[<-", list(x, i, 2, TRUE, pi)) })

system.time({

   for(i in 1:100) x[i, 2, ] <- pi
})

The first takes ~2sec on my computer, the second 8ms, and I wonder whether someone knows how to use the "clever" behaviour of "[<-" also when it is called with do.call?

  Best wishes

        Wolfgang



Wolfgang Huber, EMBL-EBI,
http://www.ebi.ac.uk/huber

>
>
> On Sat, Jul 12, 2008 at 12:48 AM, Wolfgang Huber <huber@ebi.ac.uk
> <mailto:huber_at_ebi.ac.uk>> wrote:
>
>
> Hi Richard,
>
> what is wrong with Patrick's suggestion? I get
>
>
> x <- array(1:24, dim=2:4)
> x[rbind(c(1,1,2))]
> ## [1] 7
> x[rbind(c(1,1,2))] <- 13
> x[rbind(c(1,1,2))]
> ## [1] 13
>
> And you could also do
>
> do.call("[", list(x,1,1,2))
>
> These should be a bit quicker than the eval/parse constructs - see
> also
> library("fortunes")
> fortune(106)
>
> Also note that your "subsetArray<-" function will afaIu each time
> copy (and then modify) the whole array, which may be quite
> inefficient. I believe that the "[<-" function has been optimized to
> avoid that in some cases. Try
>
> x=numeric(1e6); system.time({for (i in 1:1000) x[i]=12})
>
> versus
>
> x=numeric(1e6); system.time({for (i in 1:1000) {y=x; y[i]=12}})
>
> Best wishes
> Wolfgang
>
> ----------------------------------------------------
> Wolfgang Huber, EMBL-EBI, http://www.ebi.ac.uk/huber
>
>
>
>
>
> Richard Pearson wrote:
>
> In case anyone's still interested, I now have (I think!) a
> complete solution (thanks to a quick look at my new favourite
> document - S Poetry :-)
>
> subsetArray <- function(x, subset) {
> subsetString <- paste(subset, collapse=",")
> subsetString <- gsub("NA","",subsetString)
> evalString <- paste(expression(x), "[", subsetString, "]")
> eval(parse(text=evalString))
> }
>
> "subsetArray<-"<- function(x, subset, value) {
> subsetString <- paste(subset, collapse=",")
> subsetString <- gsub("NA","",subsetString)
> evalString <- paste(expression(x), "[", subsetString, "] <-",
> expression(value))
> eval(parse(text=evalString))
> x
> }
>
> x <- array(1:24, dim=2:4)
> subsetArray(x, c(1,1,2))
> subsetArray(x, c(1,1,2)) <- 25
> x
>
> Thanks to Pat!
>
> Richard
>
>
> Richard Pearson wrote:
>
> My understanding of matrix subscripting is that this can be
> used to access arbitrary elements from an array and return
> them as a vector, but I don't understand how that helps me
> here. I've now written a function that seems to do what I
> originally wanted, but I've also realised I want to do
> assignment too. I need to read up more on writing assignment
> functions to do this. However, I'm thinking that someone has
> already solved this, in a far more elegant way than my
> hacking :-). Here's my function for anyone interested:
>
> subsetArray <- function(x, subset) {
>
> + subsetString <- paste(subset, collapse=",")
> + subsetString <- gsub("NA","",subsetString)
> + evalString <- paste(expression(x), "[", subsetString, "]")
> + eval(parse(text=evalString))
> + }
>
> x <- array(1:24, dim=2:4)
> subsetArray(x, c(1,1,2))
>
> [1] 7
>
> subsetArray(x, c(1,NA,2))
>
> [1] 7 9 11
>
> subsetArray(x, c(1,NA,NA))
>
> [,1] [,2] [,3] [,4]
> [1,] 1 7 13 19
> [2,] 3 9 15 21
> [3,] 5 11 17 23
>
>
> subsetArray(x, c(1,1,2)) <- 25
>
> Error in subsetArray(x, c(1, 1, 2)) <- 25 : could not find
> function "subsetArray<-"
>
> Best wishes
>
> Richard.
>
>
> Patrick Burns wrote:
>
> I think you are looking for subscripting with a
> matrix:
>
> x[cbind(1,1,2)]
>
> See, for instance, the subscripting section of chapter 1
> of S Poetry.
>
>
> Patrick Burns
> patrick_at_burns-stat.com <mailto:patrick_at_burns-stat.com>
> +44 (0)20 8525 0696
> http://www.burns-stat.com
> (home of S Poetry and "A Guide for the Unwilling S User")
>
> Richard Pearson wrote:
>
> Hi
>
> Is it possible to subset an n-dimensional array by a
> vector of n dimensions? E.g. assume I have

>
> x <- array(1:24, dim=2:4)
> x[1,1,2]
>
> [1] 7
>
> dims <- c(1,1,2)
>
>
> I would like a function that I can supply x and dims
> as parameters to, and have it return 7. Also, I
> would like to do something like:
>
> x[1,1,]
>
> [1] 1 7 13 19
>
> dims2<- c(1,1,NA)
>
>
> And have a function of x and dims2 that gives me
> back [1] 1 7 13 19
>
> Does such a thing exist?
>
> Thanks
>
> Richard
>
>
> ______________________________________________
> R-help_at_r-project.org <mailto: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.
>
>



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. Received on Fri 11 Jul 2008 - 22:45:45 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Thu 24 Jul 2008 - 21:33:05 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.

list of date sections of archive