user1665355
user1665355

Reputation: 3393

Assign function output with assign

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

Upvotes: 0

Views: 1277

Answers (1)

Theja Tulabandhula
Theja Tulabandhula

Reputation: 921

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

Upvotes: 1

Related Questions