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 <huber@ebi.ac.uk> 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 <huber@ebi.ac.uk<mailto:
>> huber@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@burns-stat.com <mailto:patrick@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@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]]

