【问题标题】:Data frame creation inside Parlapply in R在 R 中的 Parlapply 内创建数据框
【发布时间】:2022-01-13 17:38:44
【问题描述】:

我正在尝试一些非常简单的事情,想要并行运行一堆回归。当我使用以下数据生成器(第 1 部分)时,并行部分不起作用并给出下面列出的错误

#PART 1
p <- 20; rho<-0.7;
cdc<- diag(p)
for( i in 1:(p-1) ){ for( j in (i+1):p ){
  cdc[i,j] <- cdc[j,i] <- rho^abs(i-j)
}}
my.data <- mvrnorm(n=100, mu = rep(0, p), Sigma = cdc)

以下并行部分确实有效,但如果我将数据生成为第 2 部分

# PART 2
my.data<-matrix(rnorm(1000,0,1),nrow=100,ncol=10)

我将要并行运行的函数配置为...

parallel_fun<-function(obj,my.data){
  p1 <- nrow(cov(my.data));store.beta<-matrix(0,p1,length(obj))
  count<-1
  for (itration in obj) {
    my_df<-data.frame(my.data)
    colnames(my_df)[itration] <- "y"
    my.model<-bas.lm(y ~ ., data= my_df, alpha=3,
                     prior="ZS-null", force.heredity = FALSE, pivot = TRUE)
    cf<-coef(my.model, estimator="MPM") 
    betas<-cf$postmean[-1]
    store.beta[ -itration, count]<- betas
    count<-count+1
  }
  result<-list('Beta'=store.beta)
}

所以我写了下面的parlapply运行方式


{
  no_cores <- detectCores(logical = TRUE)  
  myclusternumber<-(no_cores-1)
  cl <- makeCluster(myclusternumber)  
  registerDoParallel(cl)
  p1 <- ncol(my.data)
  obj<-splitIndices(p1, myclusternumber) 
  clusterExport(cl,list('parallel_fun','my.data','obj'),envir=environment())
   clusterEvalQ(cl, {
    library(MASS)
    library(Matrix)
    library(BAS)
  })
  newresult<-parallel::parLapply(cl,obj,fun = parallel_fun,my.data)
  stopCluster(cl)
  
}

但是每当我在做第 1 部分时,我都会收到以下错误

checkForRemoteErrors(val) 中的错误: 7个节点产生错误;第一个错误:找不到对象“my_df”

但这不应该发生,应该创建数据框,我不知道为什么会发生这种情况。任何帮助表示赞赏。

【问题讨论】:

  • 对象是在哪里创建的?也许您想在 my.model 调用中使用 data=my_df
  • @runr 我编辑了玩具代码。
  • 编辑后是否仍然出现错误?我能够毫无问题地复制您的代码。我不确定结果是否符合预期,但没有找到任何对象的错误
  • 尝试在新的 R 实例中运行示例代码。先运行rm(list = ls()) 以清理环境,看看是否仍然出现错误。
  • 发布了一个“hack”,看看它是否有效。我不是&lt;&lt;-assigns 的粉丝,应该有一种更简单的方法来适当管理环境,但我不是那里的专家

标签: r dataframe parallel-processing doparallel


【解决方案1】:

将此作为一种可能的解决方法发布,看看它是否有效:

parallel_fun<-function(obj,my.data){
  p1 <- nrow(cov(my.data));store.beta<-matrix(0,p1,length(obj))
  count<-1
  for (itration in obj) {
    my_df<-data.frame(my.data)
    colnames(my_df)[itration] <- "y"
    my_df <<- my_df
    my.model<-bas.lm(y ~ ., data= my_df, alpha=3,
                     prior="ZS-null", force.heredity = FALSE, pivot = TRUE)
    cf<-BAS:::coef.bas(my.model, estimator="MPM") 
    betas<-cf$postmean[-1]
    store.beta[ -itration, count]<- betas
    count<-count+1
  }
  result<-list('Beta'=store.beta)
}

问题似乎与BAS:::coef.bas 函数有关,该函数调用eval 以获取my_df,但在并行调用时未能做到这一点。这里的“hack”是通过调用my_df &lt;&lt;- my_df 来强制my_df 进入父环境。

应该有更好的方法来做到这一点,但&lt;&lt;- 可能是最快的方法。通常,&lt;&lt;- 可能会导致不希望的行为,尤其是在循环中使用时。在导出之前分配唯一的变量名(并且不要忘记在使用后删除)是解决它们的一种方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-24
    • 2022-12-13
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多