微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Foreach 循环在用户定义的函数中不起作用

如何解决Foreach 循环在用户定义的函数中不起作用

我在学习使用 foreach 包时遇到了一些问题。目标是拥有一个利用并行性的可调用用户定义函数(最终将是一个自动脚本)。

简而言之,如果我不在用户定义的函数中放置 foreach 部分,则一切正常,但是当我这样做并调用函数时,它会运行,但实际上并没有完成任何事情。

例如,所有这些都将保存到一个脚本中,然后根据需要获取调用该脚本。

list('names' = c('a','b','c') -> test.list # just making up some dataframes
for(names in test.list[['names']]{
   assign(paste0('dt.',name),data.frame('a' = 1:5)) # typically these dataframes would be 
parallel::makeCluster(parallel::detectCores() - 1) -> cl # retrieved from an API
doParallel::registerDoParallel(cl)
foreach(name = test.list$name,.errorhandling = 'remove') %dopar%
   save_file(name,path = desktop@location)
 }
doParallel::stopImplicitCluster()
}

save_file <- function(name,path){
   write.csv(get(paste0('df.',path = paste0(path,'/df.',name,'.csv'))
  }

这就是要点:有几个文件需要从 API 中检索,但每个文件都需要一些时间。所以我想并行化他们的检索以保存到磁盘上。

如果我像这样运行脚本,它就可以工作。但是如果我写一个像这样的脚本:

automatic_get <- function(){
  list('names' = c('a','c') -> test.list # just making up some dataframes
      for(names in test.list[['names']]{
        assign(paste0('dt.',data.frame('a' = 1:5)) # typically these dataframes would be 
      parallel::makeCluster(parallel::detectCores() - 1) -> cl # retrieved from an API
      doParallel::registerDoParallel(cl)
      foreach(name = test.list$name,.export = c('save_file'),# add the export for function
         .errorhandling = 'remove') %dopar%
       save_file(name,path = desktop@location)
      }
      doParallel::stopImplicitCluster()
     }
  }

  save_file <- function(name,path){
      write.csv(get(paste0('df.','.csv'))
       # normally there wouldn't need to be get component to this; the file would be retrieved 
       # from within this function and then saved within this function
     }

然后调用 automatic_get() 进程会运行,但实际上并没有运行。没有错误或任何提示,但没有文件被放置到磁盘上。

应该注意的是,调用的实际脚本是一个使用 reticulate 的 python 脚本,但同样,如果我不将所有内容都放在用户定义的函数中,它也可以工作。

任何帮助将不胜感激!

编辑:

我做的一个快速黑客是删除用户定义的函数部分,保存脚本。然后在另一个脚本(此处的脚本接收)中获取该特定脚本(带有 foreach 循环的脚本)。调用新创建的函数,该函数使用 foreach 获取脚本,而无需将 foreach 嵌套在用户定义的函数中,从而解决了该问题。但看起来,hacky?我还不得不重新安排脚本:

list('names' = c('a',data.frame('a' = 1:5)) # typically these 
                                 # dataframes would be retrieved via API                               
save_file <- function(name,'.csv'))
  }
# The parallel part had to be placed at the bottom of the script
parallel::makeCluster(parallel::detectCores() - 1) -> cl # retrieved from an API
doParallel::registerDoParallel(cl)
foreach(name = test.list$name,path = desktop@location)
 }
doParallel::stopImplicitCluster()
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。