Sam Sam - 1 year ago 26
R Question

R: Using Mapply to avoid loop

I have following code which I perform with for loop to generate a 3D array "newarr".

n1<-c(1,2,3,4,5)
n2<-c(3,4,5,6,7)
n3<- c(4,5,6,7,8)

afun <- function(y,p,q,r){
calc=1/(1+(((y-p)/q)^(2*r)))
return(calc)
}

newarr<- array(dim = c(4,5,5))
Amat<-matrix(data=c(1:20),nrow = 4,ncol = 5)

for(i in 1:5){
res<-afun(Amat,n1[i],n2[i],n3[i])
newarr[,,i]<- res
}


I want to use
Mapply
(or any apply function) instead of
for
loop.

Qmat<-matrix(rep(1),nrow = 4,ncol = 5)
arr2 <- array((mapply(function(x,y,n1,n2,n3) if(x==1) afun(y,n1,n2,n3) else 0,Qmat,Amat,n1,n2,n3)),c(4,5,5))


But it generates 2D matrix and repeating for 5 times. Is it that mapply only generates a 2D matrix?
Can anyone help me in this?
Thanks!!

Answer Source

This will give you the desired result:

newarr <- array(mapply(afun, n1,n2,n3, MoreArgs = list(y=Amat)), c(4,5,5))

this is using the implicit SIMPLIFY=TRUE of mapply(). With SIMPLIFY=TRUE each result is reduced to a vector. (a matrix is a vector with a dimension attribute)
Another variant is

array(unlist(mapply(afun, n1,n2,n3, MoreArgs = list(y=Amat), SIMPLIFY = FALSE)), c(4,5,5))

here you will get a list of matrices as result from mapply(). You have to unlist.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download