[R] filling an array, vectorized

Brandt, T. (Tobias)
Fri, 17 Nov 2006 14:16:11 -0000

Hi all

I don't know much about R internals and what goes on behind the scenes but
to me it would seem that

lapply(dim(a), function(i) seq(length=i))

accomplishes the same as

jj <- function(i) seq_len(dim(a)[i])
lapply(seq_len(length(dim(a))), jj)

and might be easier to read. Is there a performance penalty for this? In R
2.4 you could probably use

lapply(dim(a), seq_len)

but I'm still using R 2.3.1.


I would also think that the subsetting on the left hand side of

a[index] <- apply(index, 1, f)

might cause unnecessary overhead, and since the use of expand.grid has
already ensured that all the numbers are in the correct order we could
simply use

array(apply(index, 1, f), dim=dim(a))

Thus this could all be put together in the following one liner which seems
to me to accomplish the same as do.index

do.index3 <- function(a, f) {
    array( apply( as.matrix(expand.grid(lapply(dim(a), function(i)
seq(length=i)))) ,1,f) , dim=dim(a))
    }


f <- function(l){
   sum(unlist(l))
}

a <- array(0,c(2,3,4))
b <- array(0,c(2,2,2,2))

do.index(a,f)
do.index3(a,f)

do.index(b,f)
do.index3(b,f)


>-----Original Message-----
>From: r-help-bounces@stat.math.ethz.ch
>[mailto:r-help-bounces@stat.math.ethz.ch] On Behalf Of Martin Maechler
>Sent: 16 November 2006 06:04 PM
>To: Robin Hankin
>Cc: R-help mailing list
>Subject: Re: [R] filling an array, vectorized
>
>>>>>> "Robin" == Robin Hankin
<r.hankin@noc.soton.ac.uk>
>>>>>>     on Thu, 16 Nov 2006 11:54:38 +0000 writes:
>
>    Robin> Gabor
>    Robin> Tamas
>
>    Robin> yet again I find myself trumped by Gabor because I
>forget that
>    Robin> TRUE is a perfectly acceptable argument to "[".
>
>    Robin> Heh.
>
>
>    Robin> I'll stick do.index2() in the magic package.
>
>[ calling it 'do.index' - not 'do.index2' hopefully. ]
>
>Note that there are two things I'd further change:
>
>1) expand.grid() had grown a 'KEEP.OUT.ATTRS' argument recently
>   which you want to set to FALSE for efficiency
>2) jj(TRUE) maybe short and cute, but I find it ugly that it
>   really relies on
>   seq(<integer-vector>) |--> seq(along = <integer-vector>)
>   and would prefer the more efficient and clearer
>       seq_len(length(dim(a)))
>
>
>Note however that for typical cases these two changes don't
>make the result (noticeably) faster at all
>
>
>do.indexM <- function(a,f) {
>    jj <- function(i) seq_len(dim(a)[i])
>    index <- as.matrix(expand.grid(lapply(seq_len(length(dim(a))), jj),
>                                   KEEP.OUT.ATTRS = FALSE) )
>    a[index] <- apply(index, 1, f)
>    a
>}
>
>Martin
>
>    Robin> best wishes
>
>
>    Robin> rksh
>
>
>    Robin> On 16 Nov 2006, at 11:27, Gabor Grothendieck wrote:
>
>    >> Here is minor simplification:
>    >>
>    >> do.index2 <- function(a,f){
>    >> jj <- function(i) seq(dim(a)[i])
>    >> index <- as.matrix(expand.grid(lapply(jj(TRUE), jj)))
>    >> a[index] <- apply(index, 1, f)
>    >> a
>    >> }
>    >>
>    >> # test
>    >> a <- array(0,c(2,3,4))
>    >> identical(do.index(a, f), do.index2(a, f))
>    >> b <- array(0,c(2,2,2,2))
>    >> identical(do.index(b, f), do.index2(b, f))
>    >>
>    >>
>    >> On 11/16/06, Robin Hankin <r.hankin@noc.soton.ac.uk>
wrote:
>    >>> Tamas
>    >>>
>    >>> first of all, Thank You for a really well-posed,
>interesting problem.
>    >>> Answer follows.
>    >>>
>    >>>
>    >>>
>    >>> do.index <- function(a,f){
>    >>> jj <- function(i){seq_len(dim(a)[i])}
>    >>> index <- as.matrix(expand.grid(sapply(1:length(dim
>    >>> (a)),jj,simplify=FALSE)))
>    >>> a[index] <- apply(index,1,f)
>    >>> return(a)
>    >>> }
>    >>>
>    >>>
>    >>>
>    >>> f <- function(l){
>    >>> sum(unlist(l))
>    >>> }
>    >>>
>    >>> a <- array(0,c(2,3,4))
>    >>> b <- array(0,c(2,2,2,2))
>    >>>
>    >>> do.index(a,f)
>    >>> do.index(b,f)
>    >>>
>    >>>
>    >>>
>    >>> best wishes
>    >>>
>    >>> Robin
>    >>>
>    >>>
>    >>>
>    >>>
>    >>>
>    >>> On 15 Nov 2006, at 19:16, Tamas K Papp wrote:
>    >>>
>    >>> > Hi,
>    >>> >
>    >>> > I am sure this has come up before, but my searches
>of the archive
>    >>> > didn't give any results (maybe I didn't use
the
>right keywords,
>    >>> but if
>    >>> > I use too many, the search times out).
>    >>> >
>    >>> > I have a vector of dimensions n, length is not fixed,
eg
>    >>> >
>    >>> > n <- c(4,5,7)
>    >>> >
>    >>> > or
>    >>> >
>    >>> > n <- c(19,4,5,7)
>    >>> >
>    >>> > and a function f that takes a vector of indices,
>same length of
>    >>> n, and
>    >>> > gives a scalar.
>    >>> >
>    >>> > I would like to fill the array
>    >>> >
>    >>> > a <- array(dim=n)
>    >>> >
>    >>> > so that (... is just notation, not R's ...)
>    >>> >
>    >>> > a[i,j,k,...] <- f(list(i,j,k,...))
>    >>> >
>    >>> > I would use loops, but since n can have different
>lengths, I don't
>    >>> > know how many loops I would need beforehand.  Is
>there a way to do
>    >>> > this?
>    >>> >
>    >>> > Thanks,
>    >>> >
>    >>> > Tamas
>    >>> >
>    >>> > ______________________________________________
>    >>> > R-help@stat.math.ethz.ch 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.
>    >>>
>    >>>
>
>    Robin> --
>    Robin> Robin Hankin
>    Robin> Uncertainty Analyst
>    Robin> National Oceanography Centre, Southampton
>    Robin> European Way, Southampton SO14 3ZH, UK
>    Robin> tel  023-8059-7743
>
>    Robin> ______________________________________________
>    Robin> R-help@stat.math.ethz.ch mailing list
>    Robin> https://stat.ethz.ch/mailman/listinfo/r-help
>    Robin> PLEASE do read the posting guide
>http://www.R-project.org/posting-guide.html
>    Robin> and provide commented, minimal, self-contained,
>reproducible code.
>
>______________________________________________
>R-help@stat.math.ethz.ch 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.
>

********************
Nedbank Limited Reg No 1951/000009/06. The following link displays the names of
the Nedbank Board of Directors and Company Secretary. [
http://www.nedbank.co.za/terms/DirectorsNedbank.htm ]
This email is confidential and is intended for the addressee only. The following
link will take you to Nedbank's legal notice. [
http://www.nedbank.co.za/terms/EmailDisclaimer.htm ]
********************

	[[alternative HTML version deleted]]