0

I am using

library(foreach)
library(doSNOW)

And I have a function mystoploss(data,n=14)

I then call it like that (I want to loop over n=14 for now):

registerDoSNOW(makeCluster(4, type = "SOCK"))

foreach(i = 14) %dopar% {assign(paste("Performance",i,sep=""),
mystoploss(data=mydata,n=i))}

I then try to find Performance14 from above, but it is not assigned.

Is there some way to assign so the output will be in Performance14?

And if I use

foreach(i = 14) %dopar% {assign(paste("Performance",i,sep=""),
    mystoploss(data=mydata,n=i),envir = .GlobalEnv)}

I get error :

Error in e$fun(obj, substitute(ex), parent.frame(), e$data) : 
  worker initialization failed: Error in as.name

Best Regards

1 Answer 1

1

This is because the assign operations are happening in the worker processes. The vaues of the variables are being sent back (see your R session console) but not with the names you assigned. You need to capture these values and assign them names again. See this related question.

The following is an alternative that may be of help: asign the output of foreach to an intermediate variable and assign it to your desired variables in the current 'master process' environment.

PerformanceAll <- foreach(i = 1:14,.combine="c") %dopar% { mystoploss(data=mydata,n=i) } #pick .combine appropriately
for(i in 1:14){ assign(paste("Performance",i,sep=""), PerformanceAll[i]) }

Here is the full example I tried:

library(foreach)
library(doSNOW)
mystoploss <- function(data=1,n=1){
  return(runif(data)) #some operation, returns a scalar
}
mydata <- 1
registerDoSNOW(makeCluster(4, type = "SOCK"))
PerformanceAll <- foreach(i = 1:14,.combine="c") %dopar% { mystoploss(data=mydata,n=i) }#pick .combine appropriately
for(i in 1:14){ assign(paste("Performance",i,sep=""), PerformanceAll[i]) }

Edit: If the output of mystoploss is a list, then do the following changes:

mystoploss <- function(data=1,n=1){#Example
  return(list(a=runif(data),b=1)) #some operation, return a list
}
PerformanceAll <- foreach(i = 1:14) %dopar% { mystoploss(data=mydata,n=i) }#remove .combine
for(i in 1:14){ assign(paste("Performance",i,sep=""), PerformanceAll[[i]]) } #double brackets
Sign up to request clarification or add additional context in comments.

3 Comments

Ok! My function returns a list so I would like to combine my results so the output is a nested list.
In that case, leave the .combine option out (the default behaviour here is that foreach %dopar% returns a list for each value of i). PerformanceAll will be a list of lists.
Great! Did not know that I could assign directly to an object with foreach, PerformanceAll <- foreach(..., like I mean you can't assign like that with a for-loop. Thanks for the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.