Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save results of foreach loop in a matrix

Tags:

foreach

r

I am trying to adapt a for loop to use it in parallel as a foreach loop. For the for loop I create an empty matrix then fill it with the values generated by the for loop. But this approach doesn't work in the foreach loop,

results<-matrix(nrow=length(classes),ncol=length(files))
dimnames(results)[[1]]<-classes
dimnames(results)[[2]]<-files

ptime<-system.time({
    foreach(z = 1:length(files),.packages="raster") %dopar% {
      raster <- raster(paste(folder,files[z],sep=""))
      data<-getValues(raster)
      clp <- na.omit(data)
      for(i in 1:length(classes)){
        results[i,z]<-length(clp[clp==classes[i]])/length(clp)
        print(z)
      }
    }
})

My results matrix is still just filled with na's, it doesn't get populated.

z is a raster file, i is a vector of numerical classes. I want the number of cells in raster z for each class i, and then divide this by the total number of cells in raster z to get this as a proportion.

Any advice on how I can save this as a matrix/dataframe in a foreach loop?

Thank you in advance.


Follow up of this previous question

like image 497
Karen Avatar asked Dec 20 '13 14:12

Karen


1 Answers

You haven't understood how foreach works. It isn't the same as a for loop. Please study the package vignettes. Here are two simple examples:

library(foreach)
#you need to assign the loop result
res <- foreach(z = 1:5, .combine=c) %do% {
  a <- z
  a #return value for the iterations
}

res
#[1] 1 2 3 4 5


res <- foreach(z = 1:5, .combine=cbind) %:% foreach(i = 10:13, .combine=c) %do% {
  a <- z+i
  a
}
res
#      result.1 result.2 result.3 result.4 result.5
# [1,]       11       12       13       14       15
# [2,]       12       13       14       15       16
# [3,]       13       14       15       16       17
# [4,]       14       15       16       17       18

Note that you should always test your loop without parallelization first. Also, it doesn't make sense to use print inside the loop. You won't see the printed values anyway when you run the loop in parallel.

like image 62
Roland Avatar answered Nov 14 '22 14:11

Roland