将R对象从父函数使用MCMAPLY调用的嵌套函数中保存到全局环境

将R对象从父函数使用MCMAPLY调用的嵌套函数中保存到全局环境,r,parallel-processing,nested,scoping,mapply,R,Parallel Processing,Nested,Scoping,Mapply,我正在尝试编写一个R脚本,它使用嵌套函数将多个data.frames(并行)保存到全局环境中。下面的示例代码在Windows中运行良好。但是,当我将相同的代码移动到Linux服务器时,函数-get\u output()中的save()操作不会捕获函数-prepare\u output()保存到全局环境中的对象 在Linux和Windows中,mcmapply如何影响作用域方面,我是否遗漏了一些根本不同的东西 library(data.table) library(parallel) #Func

我正在尝试编写一个R脚本,它使用嵌套函数将多个data.frames(并行)保存到全局环境中。下面的示例代码在Windows中运行良好。但是,当我将相同的代码移动到Linux服务器时,函数-get\u output()中的save()操作不会捕获函数-prepare\u output()保存到全局环境中的对象

在Linux和Windows中,mcmapply如何影响作用域方面,我是否遗漏了一些根本不同的东西

library(data.table)
library(parallel)

#Function definitions
default_case <- function(flag){
  if(flag == 1){
    create_input()
    get_output()
  }else{
    Print("select a proper flag!")
  }
}

create_input <- function(){
  dt_initial <<- data.table('col1' = c(1:20), 'col2' = c(21:40)) #Assignment to global envir
}


get_output<- function(){

  list1 <- c(5,6,7,8)
  dt1 <- data.table(dt_initial[1:15,])

  prepare_output<- function(cnt){
    dt_new <- data.table(dt1)
    dt_new <- dt_new[col1 <= cnt,  ]
    assign(paste0('dt_final_',cnt), dt_new, envir =  .GlobalEnv )
    #eval(call("<<-",paste0('dt_final_',cnt), dt_new))

    print('contents in global envir inside:')
    print(ls(name = .GlobalEnv)) # This print all object names dt_final_5 through dt_final_8 correctly
  }

  mcmapply(FUN = prepare_output,list1,mc.cores = globalenv()$numCores)


  print('contents in global envir outside:')
  print(ls(name = .GlobalEnv)) #this does NOT print dataframes generated and assigned to global in function prepare_output

  save( list = ls(name = .GlobalEnv)[ls(name = .GlobalEnv) %like% 'dt_final_' ], file = 'dt_final.Rdata')
}

if(Sys.info()['sysname'] == "Windows"){numCores <- 1}else{numCores <- parallel::detectCores()}
print('numCores:')
print(numCores)

#Function call
default_case(1)

库(data.table)
图书馆(平行)
#函数定义
默认情况下(对不起,我将把它写为“答案”,因为注释框太简短了)

解决问题的最佳方法是确保将生成的对象返回,而不是尝试将它们从函数内部分配到外部环境[edit 2020-01-26],因为并行工作人员无法访问主R进程的环境,因此外部环境在并行处理中永远不起作用


在R中有一条非常好的经验法则可以帮助您实现这一点:永远不要使用
assign()
我认为您的答案没有足够清楚地说明工人无法访问主R会话的全局环境,因此OP的方法无法与
mcmapply
@Roland一起使用。我怀疑是这样的,但很高兴看到这个问题如此有效地表达出来。可以在for循环中使用assign给.globalenv赋值,但正如尼克松所说的“这是不对的”。@HenrikB感谢您的建议。我修改了函数,将data.frames列表返回到调用环境。然后从列表中提取所有输出并合并它们以形成所需的输出。它解决了我以前在范围界定方面遇到的问题。