如何在 R 中将 `foreach` 和 `%dopar%` 与 `R6` 类一起使用?

2023-12-11

我在尝试使用时遇到了问题%dopar% and foreach()与一个R6班级。四处搜索,我只能找到两个与此相关的资源,一个未答复所以问题和一个开放的GitHub问题 on the R6存储库。

在一条评论(即 GitHub 问题)中,建议通过重新分配parent_env类的SomeClass$parent_env <- environment()。我想了解到底是什么environment()指的是这个表达式(即SomeClass$parent_env <- environment()) 内被调用%dopar% of foreach?

这是一个最小的可重现示例:

Work <- R6::R6Class("Work",

    public = list(
        values = NULL,


        initialize = function() {
            self$values <- "some values"
        }
    )
)

现在,以下Task类使用Work构造函数中的类。

Task <- R6::R6Class("Task",
    private = list(
        ..work = NULL
    ),


    public = list(
        initialize = function(time) {
            private$..work <- Work$new()
            Sys.sleep(time)
        }
    ),


    active = list(
        work = function() {
            return(private$..work)
        }
    )
)

In the Factory类,该Task类被创建并且foreach实施于..m.thread().

Factory<- R6::R6Class("Factory",

    private = list(
        ..warehouse = list(),
        ..amount = NULL,
        ..parallel = NULL,


        ..m.thread = function(object, ...) {
            cluster <- parallel::makeCluster(parallel::detectCores() -  1)
            doParallel::registerDoParallel(cluster)

            private$..warehouse <- foreach::foreach(1:private$..amount, .export = c("Work")) %dopar% {
                # What exactly does `environment()` encapsulate in this context?
                object$parent_env <- environment()
                object$new(...) 
            }

            parallel::stopCluster(cluster)
        },


        ..s.thread = function(object, ...) {
            for (i in 1:private$..amount) {
               private$..warehouse[[i]] <- object$new(...)
            }
        },


        ..run = function(object, ...) {
            if(private$..parallel) {
                private$..m.thread(object, ...)
            } else {
                private$..s.thread(object, ...)
            }
        }
    ),


    public = list(
        initialize = function(object, ..., amount = 10, parallel = FALSE) {
            private$..amount = amount
            private$..parallel = parallel

            private$..run(object, ...)
        }
    ),


    active = list(
        warehouse = function() {
            return(private$..warehouse)
        }
    )
)

然后,它被称为:

library(foreach)

x = Factory$new(Task, time = 2, amount = 10, parallel = TRUE)

没有以下行object$parent_env <- environment(),它会抛出一个错误(即,如其他两个链接中提到的):Error in { : task 1 failed - "object 'Work' not found".

我想知道,(1)分配时有哪些潜在的陷阱parent_env inside foreach(2)为什么它首先有效?


更新1:

  • 我回来了environment()从内部foreach(),使得private$..warehouse捕捉这些环境
  • using rlang::env_print()在调试会话中(即browser()声明紧随其后foreach已结束执行)它们的组成如下:
Browse[1]> env_print(private$..warehouse[[1]])

# <environment: 000000001A8332F0>
# parent: <environment: global>
# bindings:
#  * Work: <S3: R6ClassGenerator>
#  * ...: <...>

Browse[1]> env_print(environment())

# <environment: 000000001AC0F890>
# parent: <environment: 000000001AC20AF0>
# bindings:
#  * private: <env>
#  * cluster: <S3: SOCKcluster>
#  * ...: <...>

Browse[1]> env_print(parent.env(environment()))

# <environment: 000000001AC20AF0>
# parent: <environment: global>
# bindings:
#  * private: <env>
#  * self: <S3: Factory>

Browse[1]> env_print(parent.env(parent.env(environment())))

# <environment: global>
# parent: <environment: package:rlang>
# bindings:
#  * Work: <S3: R6ClassGenerator>
#  * .Random.seed: <int>
#  * Factory: <S3: R6ClassGenerator>
#  * Task: <S3: R6ClassGenerator>

免责声明:我在这里所说的很多内容都是基于我所知道的有根据的猜测和推论, 我不能保证一切都是100%正确的。

我觉得可能会有很多陷阱 哪一种适用实际上取决于你做什么。 我认为你的第二个问题更重要 因为如果你明白这一点, 您将能够自己评估一些陷阱。

题目比较复杂, 但你可能可以先阅读有关R 的词法作用域。 本质上,R 有一种环境层次结构, 当执行R代码时, 在当前环境中找不到其值的变量 (这是什么environment()回报) 正在寻求在parent环境 (不要与调用者环境混淆)。

根据您链接的 GitHub 问题,R6生成器保存对其父环境的“引用”, 他们希望他们的类可能需要的一切都可以在所述父级或环境层次结构中的某个位置找到, 从该父母开始并“向上”。

您使用的解决方法有效的原因是您正在将生成器的父环境替换为当前环境中的父环境foreach在并行工作者内部调用 (可能是不同的R进程,不一定是不同的线程), 并且,考虑到你的.export规范可能会导出必要的值, 然后,R 的词法作用域可以从以下位置开始搜索缺失值:foreach在单独的线程/进程中调用。

对于您链接的具体示例, 我发现有一种更简单的方法可以让它发挥作用 (至少在我的 Linux 机器上) 是要做到以下几点:

library(doParallel)

cluster <- parallel::makeCluster(parallel::detectCores() -  1)
doParallel::registerDoParallel(cluster)
parallel::clusterExport(cluster, setdiff(ls(), "cluster"))

x = Factory$new(Task, time = 1, amount = 3)

but离开..m.thread功能为:

..m.thread = function(object, amount, ...) {
    private$..warehouse <- foreach::foreach(1:amount) %dopar% {
        object$new(...) 
    }
}

(并手动调用stopCluster完成后)。

The clusterExport调用应该具有类似于*的语义: 从主 R 进程的全局环境中获取所有内容,除了cluster, 并使其在每个并行工作人员的全局环境中可用。 这样,里面的任何代码foreach当词法作用域到达各自的全局环境时,调用可以使用生成器。foreach可以很聪明,自动导出一些变量 (如 GitHub 问题所示), 但它有局限性, 并且词法作用域期间使用的层次结构可能会变得非常混乱。

*我说“类似于”是因为我不知道如果使用分叉,R 到底会做什么来区分(全局)环境, 但由于需要出口, 我认为它们确实是相互独立的。

PS:我会打电话给on.exit(parallel::stopCluster(cluster))如果您在函数调用中创建工作人员, 这样,您就可以避免留下进程,直到它们在发生错误时以某种方式停止。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 R 中将 `foreach` 和 `%dopar%` 与 `R6` 类一起使用? 的相关文章

  • R:如何找到向量的模式[重复]

    这个问题在这里已经有答案了 下面是我的data frame我想知道每个内存类别 1 到 8 的模式是什么 gt dput d structure list MEMORY1 c 5 5 7 1 5 6 4 5 4 5 5 4 1 5 5 2
  • R data.table 连接不等式条件

    我想使用 data table 包根据多个不等式条件对数据进行子集化 data table 手册中的示例展示了如何使用字符变量执行此操作 但不显示数字不等式 我还了解了如何使用子集函数来执行此操作 但我真的很想利用 data table 二
  • 删除缺失的数据值

    我删除了原始帖子 以便能够发布更大版本的数据集 实际上总共有 418 行 这是我正在进行的生存分析的数据 第一列是 ID 号 其他列标记为 V2 V20 有很多缺失的数据 用 表示 我用coxph 函数来获取以下内容 Saves survi
  • R 错误:无法更改锁定绑定的值

    我试图估计无限数字流的平均值和标准差 当我运行代码时 出现错误消息 无法更改锁定绑定的值 我做了一些研究 发现这个错误与我使用全局变量有关 但我无法弄清楚 任何帮助将非常感激 在此先感谢您的帮助 define global variable
  • 如何总结此R问题中的销售数量、售出酒类数量和花费金额

    我使用以下代码在 R 上上传我的数据 if file exists ames liquor rds url lt https github com ds202 at ISU materials blob master 03 tidyvers
  • RStudio 不会通过 rPython 调用加载所有 Python 模块

    我从 Bash 和 RStudio 中运行相同的脚本时出现一些意外行为 请考虑以下事项 我有一个文件夹 rpython 包含两个脚本 test1 R library rPython setwd rpython python load tes
  • 空间数据xyz到矩阵

    我有一个大数据框 100 000 行 其中包含 LON LAT VALUE 我想将其转换为矩阵 EPSG 中的坐标 3035 我使用以下命令尝试了 reshape2 包 acast df lon lat value var value 效果
  • 函数“[<-”将_替换_一个元素,但不会追加_元素_

    我在使用时注意到以下几点 lt 我成功于替换元素但不位于追加向量的一个元素 例子 VarX lt integer VarX 1 lt 11 lt VarX 2 22 VarX 1 11 Expected the value of VarX
  • 如何从数据框中删除少于 5 个观察值的个体 [重复]

    这个问题在这里已经有答案了 为了澄清这个问题 我将简要描述数据 中的每一行data frame是一个观察值 列代表与该观察值相关的变量 包括 观察到什么个体 观察时间 观察地点等 我想排除 过滤观察值少于 5 个的个体 换句话说 如果 in
  • 通过 R 中的数据子集执行计算

    我想对数据框的 PERMNO 列中的每个公司编号进行计算 其摘要可以在此处查看 gt summary companydataRETS PERMNO RET Min 10000 Min 0 971698 1st Qu 32716 1st Qu
  • R data.table 1.9.2 关于 setkey 的问题

    这似乎是 1 8 10 后引入的一个错误 与包含列表的 DT 的 setkey 相关 运行下面两个代码来查看问题 library data table dtl lt list dtl 1 lt data table scenario 1 p
  • 如何确定 R 包的作者?

    如何确定包的作者是谁 鉴于我们拥有这个广泛使用的代码库 我认为参考我在分析中使用的软件是合适的 有没有办法以编程方式检索作者和任何其他相关信息 在伪代码中 我想执行以下操作 references base 我怎样才能做到这一点 为了能够引用
  • 按不规则时间间隔对数据进行分组求和(R语言)

    我正在看这里的 stackoverflow 帖子 R 计算一组内的观察次数 https stackoverflow com questions 65366412 r count number of observations within a
  • R 中的龙卷风图

    我正在尝试在 R 中绘制龙卷风图 又名敏感性图 目标是可视化某些变量增加 10 和减少 10 的效果 到目前为止我已经得到这个结果 这是我正在使用的代码 Tornado plot data lt matrix c 0 02 0 02 0 0
  • 如何从 R 数据框中提取关键字

    我是 R 中文本挖掘的新手 我想从数据框的列中删除停用词 即提取关键字 并将这些关键字放入新列中 我尝试制作一个语料库 但它对我没有帮助 df C3是我目前拥有的 我想添加栏目df C4 但我无法让它工作 df lt structure l
  • 在 igraph 中为社区分配颜色

    我在 igraph 中使用 fastgreedy community 检测算法在 R 中生成社区 代码返回 12 个社区 但是在绘图时很难识别它们 因为它返回的图的颜色数量有限 我怎样才能用十二种不同的颜色绘制这个图表 l2 lt layo
  • 当有很多列时,使用 readr::read_csv() 导入数据时覆盖列类型

    我正在尝试使用 R 中的 readr read csv 读取 csv 文件 我导入的 csv 文件大约有 150 列 我只包含示例的前几列 我希望将第二列从默认类型 我执行 read csv 时为日期 覆盖为字符或其他日期格式 GIS Jo
  • R - 与 SpatialPolygonsDataFrame 对象相交的 SpatialLinesDataFrame 列表的嵌套循环

    我有一系列需要完成的步骤SpatialLinesDataFrame 此处的 线 基于对象与多特征中各个特征的关系SpatialPolygonsDataFrame 多边形 对象 简而言之 每个线列表元素源自单个面要素内部 并且可能会也可能不会
  • 无法部署 ShinyApp:readTableHeader 在“raw”上发现不完整的最后一行(使用默认值:en_US)

    我已经拼命尝试部署我的闪亮应用程序大约一周了 但不幸的是我无法停止收到以下消息 Warning message Error detecting locale Error in read table file file header head
  • 通过使用 navbarPanel() 并隐藏导航栏构建多页闪亮应用程序用户端(在 ui.R 中)?

    我想构建一个多页闪亮应用程序 我可以在其中控制用户可以看到哪个页面 迪安 阿塔利确实这个演示应用程序中有类似的东西 https github com daattali advanced shiny tree master multiple

随机推荐

  • 使用队列触发器和消费计划上的 functionAppScaleLimit 进行 Azure Functions 扩展和并发

    我在 Linux 消费计划上有一个 Azure Function 应用程序 它有两个队列触发器 两个队列触发器都有batchSize参数设置为1因为它们每个都可以使用大约 500 MB 的内存 而我不想超过 1 5 GB 内存限制 所以应该
  • 如何禁用 JTextArea Swing 上的文本选择

    我不希望用户选择上的内容JTextArea 我用setEditable false 但它不起作用 如何禁用此功能JTextArea成分 你能给我建议吗 谢谢 如果您只想禁用任何摆动控件上的文本选择 例如JtextArea您可以使用下面的编码
  • “内联”函数定义的目的是什么? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中内联函数的好处 有什么区别 include
  • 如何将SQL Server中没有分隔符的日期时间字符串转换为日期时间?

    我希望转换这样的字符串 20160520191959550 这实际上是日期时间2016 05 20 19 19 59 我尝试使用CAST as datetime在 SQL 语句中 但出现此错误 从字符串转换日期和 或时间时转换失败 这是 S
  • Google Chrome 扩展的 onBrowserClose 事件?

    我正在为 Google Chrome 开发一个扩展 我的后台脚本每次都会在使用 XMPP API 的服务器上进行授权 并订阅 PubSub 节点 我需要在退出时取消订阅 否则虚拟订阅将保留在服务器上 有没有onBrowserCloseGoo
  • 带有 pabot 的机器人框架:是否可以在两个测试中将两个不同的值传递给变量

    例子 我有file1 robot and file2 robot并且每个都有 var 作为变量 我可以将两个不同的值传递给这个值吗 var 在命令行中 就像是pabot v var one two file1 robot file2 rob
  • 经典 ASP 日期之间的工作日数

    经典 ASP VBScript 中有没有办法获取两个日期之间的工作日数 显然 我们有DateDiff 函数 但这会拉回总天数 但我想省略周末 你说得对 DateDiff 不包括这一点 但它可以与WeekDay 计算出是否Day适逢周末 通过
  • 如何对发送到服务器的http请求进行加密?

    是否可以隐藏 或加密 HTTP 请求的内容 以便授权人员之外的其他人无法查看它 例如 如果一个用户只是在登录页面中提交数据 即使使用 http post 那么也可以在 firebug 类工具中看到请求标头中包含的用户名和密码等内容 我知道客
  • 条件 DB2 SQL 查询

    假设我有一个名为 Company 的表 其键为 CompanyID 还有另一个名为 CompanyAddress 的相关表 它具有 CompanyID 外键 因此可以轻松建立连接 此 CompanyAddress 表可以具有给定公司的多个地
  • 从 cs 文件加载脚本并访问主机方法、属性等?

    我只是在和罗斯林玩 但不确定如何执行以下操作 为了保持简单 假设我有一个主机程序 它有一个像这样的方法 public void DisplayMessage string message MessageBox Show message 然后
  • 确定数组是否包含 n...n+m 的算法?

    我在 Reddit 上看到这个问题 但没有给出积极的解决方案 我认为在这里问这个问题是一个完美的问题 这是关于面试问题的帖子 编写一个方法 该方法接受大小为 m 的 int 数组 如果该数组包含数字 n n m 1 该范围内的所有数字以及仅
  • 实现自定义配置节处理程序

    从各种来源 包括 stackOverlflow 收集的信息 但是当我开始使用它时 我收到以下错误消息 配置属性 deviceconfig 可能不是从 ConfigurationSection 派生的 我现在已经在这个问题上挣扎了一整天 而且
  • 在java程序中执行bash命令

    自从我寻找以来已经有一段时间了 但我没有找到解决方案 我正在尝试在 Linux 上的 jar 文件中执行 bash 命令 为此 我尝试了很多方法 包括 Process p new ProcessBuilder java jar M1 MIA
  • 当变量值丢失时,Django 模板中的 Javascript 语法错误

    我有一个带有 AJAX 菜单的 Django 模板 单击不同的菜单项会重新加载页面的一部分 每次菜单单击都会通过 AJAX 调用 Django 视图函数并返回一些要在页面上显示的数据 我只加载主页中所有菜单项所需的所有 JS 据我所知 AJ
  • SerialPort.Read(....) 不尊重 ReadTimeOut

    与支付终端通信的一些旧代码中存在错误 在新的付款开始之前 代码会尝试清除串行端口的内部读取缓冲区 我将代码削减到最低限度 它使用 NET SerialPort 类型 设置读取超时为 50ms 然后它读取 512 字节并继续这样做 直到不再读
  • 是否可以在 C# 中返回对变量的引用? [复制]

    这个问题在这里已经有答案了 例如 我可以返回对双精度值的引用吗 这就是我想做的 ref double GetElement Calculate x y z return ref doubleArray x y z 像这样使用它 void f
  • socket.io 的 C 客户端

    我正在尝试使用socket io 建立从C 程序到节点服务器的连接 我能想到的唯一方法是从 C 程序向节点服务器发出 http 请求 所以我已经对此部分进行了一些介绍 现在我需要从C程序接收来自节点服务器的一些信息 是否有任何 c 客户端库
  • Python 凯撒密码解码器

    在我的课程中 我的任务是创建一个凯撒密码解码器 该解码器接受输入字符串并使用字母频率找到最佳可能的字符串 如果不确定这有多大意义 但让我们提出问题 编写一个执行以下操作的程序 首先 它应该读取一行输入 这是编码消息 由大写字母和空格组成 您
  • 使用 SALib 工具箱对测量数据进行 Python 敏感性分析

    我想了解 如何使用 SALib python 工具箱进行 Sobol 敏感性分析 研究参数和交叉参数影响 从最初的例子我应该这样做 from SALib sample import saltelli from SALib analyze i
  • 如何在 R 中将 `foreach` 和 `%dopar%` 与 `R6` 类一起使用?

    我在尝试使用时遇到了问题 dopar and foreach 与一个R6班级 四处搜索 我只能找到两个与此相关的资源 一个未答复所以问题和一个开放的GitHub问题 on the R6存储库 在一条评论 即 GitHub 问题 中 建议通过