R找不到函数“%dopar%”

nnsrf1az  于 2023-05-20  发布在  其他
关注(0)|答案(2)|浏览(300)

在Windows 10的RStudio中,我编写了一个并行执行计算的函数,如下所示:

doSomething = function(a, b, c) {

    # Inner function that does the actual work when parallelised
    work = function (a, b, c) {
        # Do something
        e = func1(a, b)
        f = func2(c)
        result = e + f

        return(result)
    }

    # Carry out work in parallel
    cl = makeCluster(6)
    registerDoParallel(cl)
    output = foreach(i = 1:10, .packages=c("foo", "bar")) %dopar%
        work(a, b, c)
    stopCluster(cl)

    return(output)
}

如果我从R脚本将函数加载到内存中,这将工作得很好;但是,我想把它包含在我正在编写一个包中。因此,在包文件中,我小心地标识外部函数的名称空间,并在DESCRIPTION文件中引用它们的包。例如:

doSomething = function(a, b, c) {

    # Inner function that does the actual work when parallelised
    work = function (a, b, c) {
        # Do something
        e = foo::func1(a, b)
        f = bar::func2(c)
        result = e + f

        return(result)
    }

    # Carry out work in parallel
    cl = parallel::makeCluster(6)
    doParallel::registerDoParallel(cl)
    output = foreach::foreach(i = 1:10, .packages=c("foo", "bar")) %dopar%
        work(a, b, c)
    parallel::stopCluster(cl)

    return(output)
}

DESCRIPTION文件中:

...
Imports:
    foo,
    bar,
    doParallel,
    foreach,
    parallel

(编辑)NAMESPACE文件包含以下内容:

# Generated by roxygen2 (4.1.1): do not edit by hand

export(doSomething)

问题是,当我构建我的包并在包外运行函数时,我得到以下错误并停止执行:

Error in doSomething(a, b, c):
    could not find function "%dopar%"

由于%dopar%是一个操作符,而不是一个函数,所以我不能在包函数中将foreach::作为前缀。
我不知道我需要做什么才能让它正常工作。此外,我所读到的类似问题中有95%是由于.packages()的遗漏导致的错误,而不是%dopar%运算符本身无法识别。这似乎不是这里的原因。
救命啊!

jqjz2hbq

jqjz2hbq1#

快速修复foreach %dopar%的问题是重新安装这些软件包:

install.packages("doSNOW")

install.packages("doParallel") 

install.packages("doMPI")

上述包负责R中的并行性。这些软件包的旧版本中存在的错误现在已被删除。我应该提到的是,即使你没有直接在你的项目/包中使用这些包,它也很可能会有帮助。

vsnjm48y

vsnjm48y2#

我发现自己处于类似的情况,我在做foreach::%dopar%之类的事情时遇到了困难。所以,使用Mr. Flick's注解,我更新了我的函数文档,包含了像@importFrom foreach %dopar%这样的行。换句话说,你的函数可以看起来像这样,所以你可以使用%dopar%而不使用::运算符:

#' Do a thing
#'
#' @param first
#' @param second
#' @returns stuff
#' @export
#' @importFrom foreach %dopar%
foo <- function(first, second){

  # I can just use %dopar% without :: operator
  cl <- parallel::makeCluster(parallel::detectCores() - 1)
  doParallel::registerDoParallel(cl)
  # foreach::`%dopar%`(
  foreach::foreach(i = 1:nrow(everyCombo), .combine = 'c') %dopar% {
    .
    .
    .
  }
  parallel::stopCluster(cl)

}

然后调用devtools::document(),它会处理剩下的事情。

相关问题