[R] How to apply a function to a multidimensional array, based on its indices

Rui Barradas ruipbarradas at sapo.pt
Tue May 15 14:38:45 CEST 2012


Hello,

Your way is much better than to mess with the dim attribute, like I did. 
But,

"If you can create a data.frame or matrix that has the indices"
Actually, it must be a matrix, indices can't be of type list.


A way to avoid loops/apply altogether, and much faster, is the one 
creating K3
(K is the result from the op.)

n <- 20

t2 <- system.time({
K2 <- array(0,dim=c(n,n,n,n))
mtx <- data.matrix( expand.grid(x1=1:n,x2=1:n,y1=1:n,y2=1:n) )
K2[mtx] <- apply(mtx, 1, function(x) x["x1"]*x["y2"] - 
sin(x['x2']*x['y1']) )
})

t3 <- system.time({
K3 <- array(0,dim=c(n,n,n,n))
mtx <- data.matrix( expand.grid(x1=1:n,x2=1:n,y1=1:n,y2=1:n) )
K3[mtx] <- with(data.frame(mtx), x1*y2 - sin(x2*y1))
})


It's also woth noting that both use much more memory than the loop 
version because the index matrix can be large.

Rui Barradas
Em 15-05-2012 11:00, r-help-request at r-project.org escreveu:
> Date: Mon, 14 May 2012 13:22:11 -0400 From: David Winsemius 
> <dwinsemius at comcast.net> To: math_daddy <math_daddy at hotmail.com> Cc: 
> r-help at r-project.org Subject: Re: [R] How to apply a function to a 
> multidimensional array based on its indices Message-ID: 
> <155F48F0-04C2-4033-A7BE-FC5109224DFA at comcast.net> Content-Type: 
> text/plain; charset=US-ASCII; format=flowed; delsp=yes On May 14, 
> 2012, at 10:09 AM, math_daddy wrote:
>> >  Hello. I have a 4 dimensional array and I want to fill in the slots
>> >  with
>> >  values which are a function of the inputs. Through searching the
>> >  forums here
>> >  I found that the function "outer" is helpful for 2x2 matrices but
>> >  cannot be
>> >  applied to general multidimensional arrays. Is there anything which
>> >  can
>> >  achieve, more efficiently than the following code, the job I want?
>> >
>> >  K<- array(0,dim=c(2,2,2,2)) #dimensions will be much larger
>> >  for(x1 in 1:2)
>> >  {
>> >    for(y1 in 1:2)
>> >    {
>> >      for(x2 in 1:2)
>> >      {
>> >        for(y2 in 1:2)
>> >        {
>> >          K[x1,y1,x2,y2]<- x1*y2 - sin(x2*y1) #this is just a dummy
>> >  function.
>> >        }
>> >      }
>> >    }
>> >  }
>> >
> If you can create a data.frame or matrix that has the indices
> x1,x2,y1,y2 and the values you can use the:  K[cbind(index-vectors)]
> <- values construction:
>
> mtx<- data.matrix( expand.grid(x1=1:2,x2=1:2,y1=1:2,y2=1:2) )
> K[mtx]<- apply(mtx, 1, function(x) x["x1"]*x["y2"] -
> sin(x['x2']*x['y1']) )
> #----------------
>   >  K
> , , 1, 1
>
>            [,1]       [,2]
> [1,] 0.158529 0.09070257
> [2,] 1.158529 1.09070257
>
> , , 2, 1
>
>              [,1]     [,2]
> [1,] 0.09070257 1.756802
> [2,] 1.09070257 2.756802
>
> , , 1, 2
>
>            [,1]     [,2]
> [1,] 1.158529 1.090703
> [2,] 3.158529 3.090703
>
> , , 2, 2
>
>            [,1]     [,2]
> [1,] 1.090703 2.756802
> [2,] 3.090703 4.756802
>
>
>> >  Thank you in advance for any help.
>> >
>> >
>> >  --
>> >  View this message in context:http://r.789695.n4.nabble.com/How-to-apply-a-function-to-a-multidimensional-array-based-on-its-indices-tp4629940.html
>> >  Sent from the R help mailing list archive at Nabble.com.
>> >
>> >  ______________________________________________
>> >  R-help at r-project.org  mailing list
>> >  https://stat.ethz.ch/mailman/listinfo/r-help
>> >  PLEASE do read the posting guidehttp://www.R-project.org/posting-guide.html
>> >  and provide commented, minimal, self-contained, reproducible code.
> David Winsemius, MD
> West Hartford, CT
>



More information about the R-help mailing list