简体   繁体   中英

apply function cycling through 2 out of 3 dimensions of an array in R

I have a 3D array of this form

n_rep<-1000
n_box<-9
pert<-array(,dim=c(9,4,n_rep), dimnames=list(box=LETTERS[1:n_box],perturbation=c('p1','p2','p3','p4'),replicate=1:n_rep))

set.seed(1235)
pert[,1,]<-round(runif(n_rep*n_box,-1,1),0)
pert[,2,]<-round(runif(n_rep*n_box,-2,2),0)
pert[,3,]<-round(runif(n_rep*n_box,-3,3),0)
pert[,4,]<-round(runif(n_rep*n_box,-4,4),0)

and I want to apply a function (eg MyFun ) to each column of each "layer" of the array. MyFun takes an argument that is a vector of 9 numbers (ie here the rows of the array) on which it does some operation. The function could be something like:

MyFun<- function(vect=NULL){
        res<-sum(10+vect)
        return(res)
}

So basically, I want to apply MyFun cycling through both the dimensions 'perturbation' and 'replicate' (ie the columns and the 3rd dimension respectively). Such as:

MyFun(vect=pert[,1,1])
MyFun(vect=pert[,2,1])
MyFun(vect=pert[,3,1])
MyFun(vect=pert[,4,1])
MyFun(vect=pert[,1,2])
MyFun(vect=pert[,2,2])

and so fort.

Is there a way to use apply to do this in a single call or should I nest 2 apply function (ie one that cicle through the columns and the other over the 3rd dimension)?

We can use apply with MARGIN specified as 2 and 3

out <- apply(pert, c(2, 3), FUN = MyFun)

which can also done with nested loops

out1 <- t(sapply(seq_len(dim(pert)[2]), function(j) 
       sapply(seq_len(dim(pert)[3]), function(k) MyFun(pert[, j, k]))))
all.equal(out, out1, check.attributes = FALSE)
#[1] TRUE

-checking

identical(out[1,1], MyFun(vect=pert[,1,1]))
#[1] TRUE
identical(out[4,1], MyFun(vect=pert[,4,1]))
#[1] TRUE

identical(out[2,2], MyFun(vect=pert[,2,2]))
#[1] TRUE

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM