繁体   English   中英

从函数内部使用jags.parallel(R语言get(name,envir = envir)中的错误:未找到对象'y')

[英]Using jags.parallel from within a function (R language Error in get(name, envir = envir) : object 'y' not found)

从命令行或脚本使用jags.parallel可以正常工作。 我可以从http://www.inside-r.org/packages/cran/R2jags/docs/jags运行这个修改好的示例

# 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)

但是如果我将其包装在函数中

testparallel <- functions(out){
# An example model file is given in:
    .
    .
    .
jagsfit <- jags.parallel(data=jags.data, inits=jags.inits, jags.params, 
  n.iter=5000, model.file=model.file)
print(out)
return(jagsfit)
}

然后我得到错误:get(name,envir = envir)中的错误:找不到对象'y'根据在这里找到的内容我知道这是导出到集群的环境的问题,并且通过更改进行了修复

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()) 

有更好的方法来解决这个问题吗?

谢谢你,格雷格

PS

我正在为其他人编写此代码,因此我确实不想更改R2jags软件包中的内容以让我通过环境进行导出,尽管我打算建议该软件包的作者。

因此,我联系了R2jags的作者,他在jags.parallel中添加了一个附加参数,使您可以传递envir,然后将其传递给clusterExport。

效果很好,除了它允许我的数据名称与jags.parallel函数中的变量发生冲突。

如果您在parrallel中大量使用JAGS,建议您将rjags软件包与dclone软件包组合使用。 我认为dclone是真的强大,因为syntaxe是完全一样rjags 我从未见过您的与此包有关的问题。

如果您想使用R2jags我认为您需要通过以下函数将变量和init函数传递给worker:

clusterExport(cl, list("jags.data", "jags.params", "jags.inits"))

在不更改R2jags代码的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)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM