# [Rd] x[1,], x[1,,], x[1,,,], ...

Tony Plate tplate at acm.org
Thu Nov 24 03:33:46 CET 2005

```Henrik Bengtsson wrote:
> Hi, thanks everyone.
>
>
> Peter Dalgaard wrote:
>
>>Henrik Bengtsson <hb at 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 <- "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[] <- 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[] <- i', but 'i' is typically much smaller
> than 'x' so this should be of minor importance.
>
>
>    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)
 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).

-- Tony Plate

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

```