开发R包,使用“foreach”进行测试,同时使用不同的包版本运行模拟

开发R包,使用“foreach”进行测试,同时使用不同的包版本运行模拟,r,parallel-processing,devtools,parallel-foreach,R,Parallel Processing,Devtools,Parallel Foreach,我几乎所有的R代码都是在工作包中编写的(并且使用git)。在更新包中使用的函数时,我大量使用devtools,尤其是load\u all等的捷径。我对devtools有一个粗略的了解,因为load\u all制作了一个包的临时副本,我非常喜欢这个用于测试包中功能更新的工作流 是否有一种简单的方法/工作流程可以根据软件包运行仿真,同时开发软件包,而不会“破坏”这些仿真 我怀疑有一个我忽略了的简单解决方案 现在我要做的是: 将包“mypackage”设置到可以运行模拟的位置。复制包含项目的整个文件夹

我几乎所有的R代码都是在工作包中编写的(并且使用git)。在更新包中使用的函数时,我大量使用
devtools
,尤其是
load\u all
等的捷径。我对
devtools
有一个粗略的了解,因为
load\u all
制作了一个包的临时副本,我非常喜欢这个用于测试包中功能更新的工作流

是否有一种简单的方法/工作流程可以根据软件包运行仿真,同时开发软件包,而不会“破坏”这些仿真

我怀疑有一个我忽略了的简单解决方案

现在我要做的是:

  • 将包“mypackage”设置到可以运行模拟的位置。复制包含项目的整个文件夹。使用新包名“mypackage2”在复制的文件夹中运行模拟。运行包含
    库(mypackage2)
    但不包含
    库(mypackage)
    的模拟脚本。这就意味着我需要更新
    library(mypackage)
    调用
    library(mypackage2)
    调用。如果我使用
    library(mypackage)
    运行模拟,并避免使用
    library(mypackage2)
    ,那么我需要确保
    mypackage
    的当前构建版本是“旧”版本,不反映第2版中的更新。下面(但下面2.也需要重建包!)。处理这一切会变得一团糟

  • 当模拟在复制的文件夹中运行时,我可以通过使用
    load\u all
    或重建包来更新“mypackage”中的函数。我经常需要重建软件包(即,在测试软件包更新时使用
    加载所有
    而不重建软件包不是可行的解决方案),因为我想测试使用
    doParallel
    foreach
    等(在windows上)运行小型并行模拟的函数,我修改并想要测试的任何函数都需要在子进程中使用最新构建的“mypackage”,这些子进程会生成新的R进程,称为“mypackage”。我知道,当在R中构建包时,它将存储在
    。\R\R-3.6.1\library
    ,并且当将来的R会话调用
    library(mypackage)
    时,它们将使用该版本的包

  • 理想情况下,我希望能够在相同的原始文件夹中,使用
    mypackage
    版本运行模拟,然后在模拟停止/启动时更新包中的代码,确信我的开发更改不会破坏运行特定版本包的模拟

    有没有一种简单的方法可以实现上述功能,而无需重新复制文件夹(并制作“mypackage2”之类的东西)

    谢谢

    这里描述的问题有点类似于我所面临的问题


    问题是,如果我使用“mypackage”运行一个需要几天时间的模拟,并多次调用
    foreach
    ,并在测试更改时更新和重新生成“mypackage”,那么来自模拟的未来
    foreach
    调用可能会获取新的更新版本的包,这将是一场灾难。

    我不完全理解您的用例(关于您为什么要这样做),但在测试一个包的两个版本时,我通常会将最新版本推送到GitHub中的
    dev
    分支,然后使用
    devtools::load_all()
    来测试我当前正在处理的内容。然后,通过使用
    remotes::install\u github()
    并指定开发分支,您可以使用
    mypackage::func
    运行github版本,使用
    func

    运行devtools版本,我不完全理解您的用例(至于为什么要这样做)但在测试一个包的两个版本时,我通常会将最新版本推送到GitHub中的
    dev
    分支,然后使用
    devtools::load_all()
    来测试我当前正在处理的内容。然后通过使用
    remotes::install\u github()
    并指定开发分支,您可以使用
    mypackage::func
    运行github版本,使用
    func

    运行devtools版本,我认为其他问题中的答案确实适用, 但是你需要做一些额外的步骤

    假设您有一个要测试的包的版本。 您仍然会为该版本创建一个特定的文件夹,但将其保留为空。 这里我将以
    /tmp/mypkg2
    为例。 在RStudio中打开项目时,执行:

    withr::with_libpaths(c("/tmp/mypkg2", .libPaths()), devtools::install())
    
    将该版本的软件包安装到提供的文件夹中

    然后你可以有一个包装器脚本, 说
    wrapper.R
    , 比如:

    pkg_path <- commandArgs(trailingOnly = TRUE)[1L]
    
    cat("Using package at", pkg_path, "\n")
    
    .libPaths(c(pkg_path, .libPaths()))
    
    library(doParallel)
    
    workers <- makeCluster(detectCores())
    registerDoParallel(workers)
    
    # We need to modify the lib path in each worker too
    parallel::clusterExport(workers, "pkg_path")
    parallel::clusterEvalQ(workers, .libPaths(c(pkg_path, .libPaths())))
    
    # ... Your code calling your package and doing stuff
    
    parallel::stopCluster(workers)
    
    这样,实际的测试代码可以保持不变 (包括调用
    ) R将自动在
    pkg_路径
    中首先搜索, 正在加载特定的软件包版本,
    然后在标准位置中搜索可能存在的任何依赖项。

    我认为另一个问题的答案确实适用, 但是你需要做一些额外的步骤

    假设您有一个要测试的包的版本。 您仍然会为该版本创建一个特定的文件夹,但将其保留为空。 这里我将以
    /tmp/mypkg2
    为例。 在RStudio中打开项目时,执行:

    withr::with_libpaths(c("/tmp/mypkg2", .libPaths()), devtools::install())
    
    将该版本的软件包安装到提供的文件夹中

    然后你可以有一个包装器脚本, 说
    wrapper.R
    , 比如:

    pkg_path <- commandArgs(trailingOnly = TRUE)[1L]
    
    cat("Using package at", pkg_path, "\n")
    
    .libPaths(c(pkg_path, .libPaths()))
    
    library(doParallel)
    
    workers <- makeCluster(detectCores())
    registerDoParallel(workers)
    
    # We need to modify the lib path in each worker too
    parallel::clusterExport(workers, "pkg_path")
    parallel::clusterEvalQ(workers, .libPaths(c(pkg_path, .libPaths())))
    
    # ... Your code calling your package and doing stuff
    
    parallel::stopCluster(workers)
    
    这样,实际的测试代码可以保持不变 (包括调用
    ) R将自动在
    pkg_路径
    中首先搜索, 正在加载特定的软件包版本,
    然后在标准位置中搜索您可能有的任何依赖项。

    谢谢您的反馈。当您想使用say
    foreach
    (带有更多t