Jim Maas
Jim Maas

Reputation: 1729

error when preparing nested foreach loops for R package compile

Easiest way to describe this is show the code. I have a nested foreach loop that works fine, trying to prepare to compile as an R package, thus remove "library(foreach)" in the code. My function looks like this:

Calcs <- function (...) {
results <- data.frame (foreach::foreach (j = 1:NumSim, .combine = acomb,
                                .options.mpi=opts1)
                       %:%
                       foreach::foreach (i = 1:PopSize, .combine=rbind,
                                .options.mpi=opts2,
                                .export = c (ls(globalenv())),
                                .packages = c("zoo", "msm", "FAdist"))
                       foreach::`%dopar%` {


                           output <- if(rbinom(1,1,ProSecPos) > 0)
                                  replicate(DayNum, eval(call("PrbInfBep")))
                                  else rep(0, DayNum)

                           output2 <- data.frame(khf(output))
                       }
                       )

}

I get an "unexpected symbol" error at the start of the second "foreach:foreach" statement like this.

  ./functions/Parallel.R:19:28: unexpected symbol
18:                                     .packages = c("zoo", "msm", "FAdist"))
19:                            foreach
                               ^

For some strange reason it seems happy with the "%:%", or it just hasn't worked back to that error yet. Do I need something clever like foreach::foreach::%dopar%`

Upvotes: 1

Views: 694

Answers (2)

F. Priv&#233;
F. Priv&#233;

Reputation: 11738

I think foreach use some non-standard evaluation so that it is not straightforward to use in a package just by adding foreach:: before everything. What you could easily do instead is to use #' @import foreach in the roxygen2 documentation.

If you really want to use foreach::, you could but it is not pretty. For example, if you want to transform

library(foreach)
test1 <- foreach::foreach (j = 1:20, .combine = c) %:%
  foreach::foreach(i = 1:10, .combine = c) %do% {
    i * j 
  }

you can do

test2 <- foreach::`%do%`(
  foreach::`%:%`(foreach::foreach(j = 1:20, .combine = c),
                 foreach::foreach(i = 1:10, .combine = c)), 
  {
    i * j 
  }
)

all.equal(test1, test2)

PS: you will have a NOTE complaining about i and j. To remove it, you can add globalVariables(c("i", "j")) somewhere in your package.

Upvotes: 1

Jesus
Jesus

Reputation: 462

Int he second foreach you dont have a %:% after it. Please try with this notation...

For nested foreach you should use always:

matrix<-foreach()%:%
foreach()%:%
foreach()%dopar%{

}

Upvotes: 1

Related Questions