Re: [Rd] x[1,], x[1,,], x[1,,,], ...

From: Tony Plate <tplate_at_acm.org>
Date: Thu 24 Nov 2005 - 02:33:46 GMT

Henrik Bengtsson wrote:
> Hi, thanks everyone.
>
> Some comments below:
>
> Peter Dalgaard wrote:
>

>>Henrik Bengtsson <hb@maths.lth.se> writes:
>>
>>
>>
>>>Hi,
>>>
>>>is there a function in R already doing what I try to do below:
>>>
>>># Let 'x' be an array with *any* number of dimensions (>=1).
>>>x <- array(1:24, dim=c(2,2,3,2))
>>>...
>>>x <- array(1:24, dim=c(4,3,2))
>>>
>>>i <- 2:3
>>>
>>>ndim <- length(dim(x))
>>>if (ndim == 1)
>>>  y <- x[i]
>>>else if (ndim == 2)
>>>  y <- x[i,]
>>>else if (ndim == 3)
>>>  y <- x[i,,]
>>>else ...
>>>
>>>and so on.  My current solution is
>>>
>>>ndim <- length(dim(x))
>>>args <- rep(",", ndim)
>>>args[1] <- "i"
>>>args <- paste(args, collapse="")
>>>code <- paste("x[", args, "]", sep="")
>>>expr <- parse(text=code)
>>>y <- eval(expr)
>>>
>>>Is there another way I can do this in R that I have overlooked?
>>
>>
>>I think this should work:
>>
>>x <- array(1:24, dim=c(3,2,2,2)) # not c(2,2,3,2)....
>>i <- 2:3
>>ndim <- length(dim(x))
>>ix <- as.list(rep(TRUE, ndim))
>>ix[[1]] <- i
>>do.call("[", c(list(x), ix))

>
>
> In my case, 'x' is huge, an I have to be careful with allocating memory.
> Doesn't the 'list(x)' statement enforce an extra copy of 'x'? Or will
> lazy evaluation be able to pull out 'x' from the list again without
> evaluating 'list(x)'? I don't think so, but I'm not sure. There is
> also some overhead in 'ix[[1]] <- i', but 'i' is typically much smaller
> than 'x' so this should be of minor importance.
>
> What about Andy's suggestion
>
> array(x[slice.index(x, 1) == 1], dim(x)[-1])?
>
> There 'slice.index(x, 1)' will create an array of same size as 'x'.
>
> I do not think the 'eval(parse(...))' has such overhead (correct me if
> I'm wrong), but on the other hand, it is a more "ugly" solution. I
> prefer not to use parse(), substitute() and friends in my code, if I
> don't have to.
>
> I just want to bring up this flavor of the problem too, because I often
> find myself having to choose from similar options in other situations.
> If you have further comments, I would appreciate those.
>

Here's the type of manipulation I often do to approach these problems:

 > x <- array(1:24, dim=c(4,3,2))
 > i <- 2:3
 > x[i,,]

, , 1

      [,1] [,2] [,3]
[1,] 2 6 10
[2,] 3 7 11

, , 2

      [,1] [,2] [,3]
[1,] 14 18 22
[2,] 15 19 23

 > xic <- Quote(x[i,])
 > xic
x[i, ]
 > length(xic)
[1] 4

 > # now duplicate the empty index argument the appropriate number of times
 > xic <- xic[c(1:3,4,4)]
 > xic

x[i, , ]
 > eval(xic)
, , 1

      [,1] [,2] [,3]
[1,] 2 6 10
[2,] 3 7 11

, , 2

      [,1] [,2] [,3]
[1,] 14 18 22
[2,] 15 19 23

 >

I do this type of manipulation for precisely the reasons you bring up. I do know that in S-PLUS, using do.call() in the most obvious manner can result in unnecessary multiple duplications of data objects (as you suspect). I don't think R is quite as bad, but I haven't done careful the experiments with R.

Do be careful though: this type of manipulation can expose a bug in R, which I don't think has been fixed (PR#7924).

> Thanks
>
> Henrik
>
> ______________________________________________
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>



R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Thu Nov 24 13:40:08 2005

This archive was generated by hypermail 2.1.8 : Thu 24 Nov 2005 - 08:21:36 GMT