Returning to the old question ... > Is it possible to subset an n-dimensional array by a > vector of n dimensions?
On Sat, Jul 12, 2008 at 1:34 AM, Wolfgang Huber <[EMAIL PROTECTED]> wrote: > > 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 > This is the Something Clever I thought of, but it's actually not the same as x[1,2,] : TRUE is a (recycled) logical index ... but what is the "nothing" after the second comma and before the closing ] ? as.list(quote(x[])) is.name(quote(x[])[[3]]) .. it seems to be an empty name (``) but there seems to be no way to construct it other than something like quote(x[])[[3]] or alist(,)[[1]] -- but this is sufficient to rewrite Richard's subsetArray function without using parse: sa2 <- function(x, Subset, Eval=TRUE) { Subset <- lapply(Subset, function(x) if(length(x)==1 & all(is.na(x))) alist(,)[[1]] else x) ex <- quote(x[]) Tail <- 3:(2+length(Subset)) ex[Tail] <- Subset if(Eval) eval(ex) else ex } This is more general than subsetArray because "Subset" can be a list -- to allow thing like x[1:10,,c(3,9,7)] to be "translated". ... And a replacement function: `sa2<-` <- function(x, Subset, value){ ex <- sa2(x, Subset, Eval = FALSE) ex[[1]] <- `[<-` ex$value <- value eval(ex) } ... and some related discoveries: > is.name(alist(,)[[1]]) [1] TRUE > X<-alist(,)[[1]] > is.name(X) Error: argument "X" is missing, with no default > dump("X","") X <- quote() > X<-quote() Error in quote() : 0 arguments passed to 'quote' which requires 1 > as.character(X) Error: argument "X" is missing, with no default > as.character(alist(,)[[1]]) [1] "" Kenn > > > 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 <[EMAIL PROTECTED]<mailto: >> [EMAIL PROTECTED]>> 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 >> [EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]> >> +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@r-project.org <mailto: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. >> >> >> [[alternative HTML version deleted]] ______________________________________________ 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.