clusterExport,环境和可变范围 [英] clusterExport, environment and variable scoping

查看:297
本文介绍了clusterExport,环境和可变范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个定义变量和加载对象的函数.这是一个简化的版本:

I wrote a function in which I define variables and load objects. Here's a simplified version:

fn1 <- function(x) {
  load("data.RData") # a vector named "data"
  source("myFunctions.R")
  library(raster)
  library(rgdal)

  a <- 1
  b <- 2
  r1 <- raster(ncol = 10, nrow = 10)
  r1 <- init(r1, fun = runif)
  r2 <- r1 * 100
  names(r1) <- "raster1"
  names(r2) <- "raster2"
  m <- stack(r1, r2) # basically, a list of two rasters in which it is possible to access a raster by its name, like this: m[["raster1"]]

  c <- fn2(m)
}

可以在"myFunctions.R"中找到函数"fn2",并将其定义为:

Function "fn2" is can be found in "myFunctions.R" and is defined as:

fn2 <- function(x) {
  fn3 <- function(y) {
   x[[y]] * 100 * data
  }

  cl <- makeSOCKcluster(8)   
  clusterExport(cl, list("x"), envir = environment()) 
  clusterExport(cl, list("a", "b", "data")) 
  clusterEvalQ(cl, c(library(raster), library(rgdal), rasterOptions(maxmemory = a, chunksize = b))) 
  f <- parLapply(cl, names(x), fn3)  
  stopCluster(cl)
}

现在,当我运行fn1时,出现如下错误:

Now, when I run fn1, I get an error like this:

Error in get(name, envir = envir) : object 'a' not found

根据我对?clusterExport的了解,envir的默认值为.GlobalEnv,因此我假设fn2可以访问"a"和"b".但是,事实并非如此.如何访问"a"和"b"所属的环境?

From what I understand from ?clusterExport, the default value for envir is .GlobalEnv, so I would assume that "a" and "b" would be accessible to fn2. However, it doesn't seem to be the case. How can I access the environment to which "a" and "b" belong?

到目前为止,我发现的唯一解决方案是将"a"和"b"作为参数传递给fn2.有没有一种方法可以在fn2中使用这两个变量而不将其作为参数传递?

So far, the only solution I have found is to pass "a" and "b" as arguments to fn2. Is there a way to use these two variables in fn2 without passing them as arguments?

非常感谢您的帮助.

推荐答案

调用clusterExport(cl, list("a", "b", "data"))时出现错误,因为clusterExport试图在.GlobalEnv中查找变量,但fn1不是在.GlobalEnv中但在其自己的本地环境中进行设置.

You're getting the error when calling clusterExport(cl, list("a", "b", "data")) because clusterExport is trying to find the variables in .GlobalEnv, but fn1 isn't setting them in .GlobalEnv but in its own local environment.

另一种方法是将fn1的本地环境传递给fn2,并将该环境指定给clusterExport.对fn2的调用将是:

An alternative is to pass the local environment of fn1 to fn2, and specify that environment to clusterExport. The call to fn2 would be:

c <- fn2(m, environment())

如果fn2的参数是function(x, env),则对clusterExport的调用将是:

If the arguments to fn2 are function(x, env), then the call to clusterExport would be:

clusterExport(cl, list("a", "b", "data"), envir = env)

由于环境是通过引用传递的,因此这样做不会出现性能问题.

Since environments are passed by reference, there should be no performance problem doing this.

这篇关于clusterExport,环境和可变范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆