在函数中使用jags.parallel(get(name,envir=envir)中的R语言错误:找不到对象

在函数中使用jags.parallel(get(name,envir=envir)中的R语言错误:找不到对象,r,parallel-processing,r2jags,jags.parallel,R,Parallel Processing,R2jags,Jags.parallel,从命令行或脚本中使用jags.parallel可以很好地工作。我可以很好地运行这个修改后的示例 # An example model file is given in: model.file <- system.file(package="R2jags", "model", "schools.txt") #=================# # initialization # #=================# # data J <- 8.0 y <

从命令行或脚本中使用jags.parallel可以很好地工作。我可以很好地运行这个修改后的示例

# An example model file is given in:
  model.file <- system.file(package="R2jags", "model", "schools.txt")
#=================#
# initialization  #
#=================#

  # data
  J <- 8.0
  y <- c(28.4,7.9,-2.8,6.8,-0.6,0.6,18.0,12.2)
  sd <- c(14.9,10.2,16.3,11.0,9.4,11.4,10.4,17.6)

  jags.data <- list("y","sd","J")
  jags.params <- c("mu","sigma","theta")
  jags.inits <- function(){
    list("mu"=rnorm(1),"sigma"=runif(1),"theta"=rnorm(J))
  }


#===============================#
# RUN jags and postprocessing   #
#===============================#
#  jagsfit <- jags(data=jags.data, inits=jags.inits, jags.params, 
#    n.iter=5000, model.file=model.file)

  # Run jags parallely, no progress bar. R may be frozen for a while, 
  # Be patient. Currenlty update afterward does not run parallelly

  print("Running Parallel") 
  jagsfit <- jags.parallel(data=jags.data, inits=jags.inits, jags.params, 
    n.iter=5000, model.file=model.file)
有没有更好的办法解决这个问题

谢谢,, 格雷格

附言


我正在为其他人编写此代码,因此我不想更改R2jags包中的内容以允许我通过环境进行导出,尽管我计划向包的作者推荐它。

如果您在Parralel中大量使用JAGS,我可以建议您将包
rjags
与包结合使用
dclone
。我认为
dclone
非常强大,因为syntax与
rjags
完全相同。 我从来没见过你对这个包裹有什么问题

如果您想使用
R2jags
我认为您需要将变量和init函数传递给具有该函数的worker:


clusterExport(cl,list(“jags.data”、“jags.params”、“jags.inits”))
在不更改
R2jags
代码的情况下,您仍然可以使用
list2env
以更简单的方式将这些数据变量分配给全局环境

显然,存在一个问题,即这些变量名可能会在全局环境中被覆盖,但您可能可以对此进行控制

下面的代码与原始帖子中给出的示例相同,只是我将数据放入一个列表,并使用
list2env
函数将该列表的数据发送到全局环境中。(我还取出了函数中未使用的“out”变量。)这对我来说目前运行良好;不过,您可能需要添加更多的链和/或添加更多的迭代来查看并行性

testparallel <- function(){

    library(R2jags)

    model.file <- system.file(package="R2jags", "model", "schools.txt")

    # Make a list of the data with named items.
    jags.data.v2 <- list(
        J=8.0, 
        y=c(28.4,7.9,-2.8,6.8,-0.6,0.6,18.0,12.2),
        sd=c(14.9,10.2,16.3,11.0,9.4,11.4,10.4,17.6) )

    # Store all that data explicitly in the globalenv() as
    # was previosly suggesting using the assign(...) function.
    # This will do that for you.
    # Now R2jags will have access to the data without you having 
    # to explicitly "assign" each to the globalenv.
    list2env( jags.data.v2, envir=globalenv() )

    jags.params <- c("mu","sigma","theta")
    jags.inits <- function(){
        list("mu"=rnorm(1),"sigma"=runif(1),"theta"=rnorm(J))
    }

    jagsfit <- jags.parallel(
        data=names(jags.data.v2), 
        inits=jags.inits, 
        jags.params, 
        n.iter=5000, 
        model.file=model.file)

    return(jagsfit)
}

testparallel所以我联系了R2jags的作者,他在jags.parallel中添加了一个附加参数,允许您传递envir,然后将其传递到clusterExport


除了允许我的数据名称与jags.parallel函数中的变量之间发生冲突外,这项功能运行良好。

clusterExport调用位于jags.parallel内部。问题是clusterExport会自动导出全局环境。因为我是从另一个函数中调用jags.parallel,所以变量(jags.data等)在函数环境中,而不是全局环境中。因此,处理器不会获取变量,并抛出我引用的错误。clusterExport确实有一个可选参数用于选择要导出的环境,但jags.parallel没有。我建议修改作者。我正在为其他人编写这段代码,我不想自己编辑这个包。我看到了dclone,但我对jags和R都是新手,并且正在编写大量先前存在的代码,因此我正在寻找一种方法来并行化需要最少更改的代码。如果您知道一个学习RJAG和如何使用dclone的好来源,我将进一步研究它。感谢您的回答。在检查了
jags.parallel
函数后,我认为它们没有您需要的参数来找到问题的解决方案。但是使用
dclone
包,
makeSOCKcluster
函数不在
jag.parfit
函数中。因此,您可以控制变量的环境。与
jags.parallel
等效的功能是
jags.parfit
。参数的主要区别在于
cl
(在运行函数之前创建的集群)。我认为jags手册和
jags.parfit
函数的示例都是相对丰富的。谢谢。我的问题是我不喜欢将变量设置为全局变量,但很高兴有更好的方法将它们设置为全局变量。
J <- 8.0
y <- c(28.4,7.9,-2.8,6.8,-0.6,0.6,18.0,12.2)
sd <- c(14.9,10.2,16.3,11.0,9.4,11.4,10.4,17.6)
  assign("J",8.0,envir=globalenv()) 
  assign("y",c(28.4,7.9,-2.8,6.8,-0.6,0.6,18.0,12.2),envir=globalenv()) 
  assign("sd",c(14.9,10.2,16.3,11.0,9.4,11.4,10.4,17.6),envir=globalenv()) 
testparallel <- function(){

    library(R2jags)

    model.file <- system.file(package="R2jags", "model", "schools.txt")

    # Make a list of the data with named items.
    jags.data.v2 <- list(
        J=8.0, 
        y=c(28.4,7.9,-2.8,6.8,-0.6,0.6,18.0,12.2),
        sd=c(14.9,10.2,16.3,11.0,9.4,11.4,10.4,17.6) )

    # Store all that data explicitly in the globalenv() as
    # was previosly suggesting using the assign(...) function.
    # This will do that for you.
    # Now R2jags will have access to the data without you having 
    # to explicitly "assign" each to the globalenv.
    list2env( jags.data.v2, envir=globalenv() )

    jags.params <- c("mu","sigma","theta")
    jags.inits <- function(){
        list("mu"=rnorm(1),"sigma"=runif(1),"theta"=rnorm(J))
    }

    jagsfit <- jags.parallel(
        data=names(jags.data.v2), 
        inits=jags.inits, 
        jags.params, 
        n.iter=5000, 
        model.file=model.file)

    return(jagsfit)
}