【问题标题】:R: Passing a data frame by referenceR:通过引用传递数据帧
【发布时间】:2012-06-27 18:44:03
【问题描述】:

R 具有按值传递的语义,可以最大限度地减少意外副作用(一件好事)。但是,当代码被组织成许多函数/方法以实现可重用性/可读性/可维护性时,以及当代码需要通过例如大数据帧、通过一系列转换/操作来操作大型数据结构时,传递值语义会​​导致大量的数据复制和大量的堆颠簸(一件坏事)。例如,在作为函数参数传递的堆上占用 50Mb 的数据帧将至少复制与函数调用深度相同的次数,并且调用堆栈底部的堆大小将为 N* 50MB。如果函数从调用链的深处返回一个转换/修改的数据帧,那么复制会增加另一个 N。

SO 问题What is the best way to avoid passing a data frame around? 涉及该主题,但措辞方式避免直接询问传递引用问题,而获胜的答案基本上是说:“是的,传递值是 R 的工作方式”。这实际上并不是 100% 准确的。 R 环境支持按引用传递语义,而 OO 框架(例如 proto)广泛使用此功能。例如,当一个 proto 对象作为函数参数传递时,它的“魔术包装器”是按值传递的,对于 R 开发人员来说,语义是按引用传递的。

似乎通过引用传递大数据框将是一个常见问题,我想知道其他人如何处理它以及是否有任何库可以实现这一点。在我的搜索中,我没有发现一个。

如果没有可用的东西,我的方法是创建一个包装数据框的原型对象。我会很感激有关应该添加到该对象以使其有用的语法糖的指针,例如,重载 $ 和 [[ 运算符,以及我应该注意的任何陷阱。我不是 R 专家。

与 R 完美集成的与类型无关的按引用传递解决方案的奖励积分,尽管我的需求完全是数据帧。

【问题讨论】:

  • 我认为您问题中的前提不正确。 R 仅在更改时复制,因此只要不更改对象,您就可以愉快地将参数传递到调用堆栈而无需创建新副本。我会在一分钟内尝试为您找到一些关于此的参考资料。
  • 查看例如这个问题及其@matthewdowle 的回答:stackoverflow.com/q/10225098/602276
  • 安德烈是对的。很惊讶您在搜索大型 data.frame 时没有找到 data.table。你搜索了什么?
  • @Andrie,感谢您指出这一点。我很惊讶它没有在R 编程的艺术 等书籍中提及。它似乎是一个基本的语言特征。您推荐的关于 R 内部的最佳读物是什么?

标签: performance r dataframe data.table proto


【解决方案1】:

问题的前提(部分)不正确。 R 以传递承诺的方式工作,只有在传递承诺时对数据帧进行进一步分配和更改时,才会以您概述的方式重复复制。因此,副本的数量将不是 N*size,其中 N 是堆栈深度,而是其中 N 是进行分配的级别数。但是,您是对的,环境可能很有用。我看到你已经找到了'proto'包的链接。还有一个相对较新的“参考类”,有时称为“R5”,其中 R/S3 是在 R 中复制的 S3 的原始类系统,而 R4 将是最近的类系统,似乎主要支持BioConductor 软件包开发。

以下是 Steve Lianoglou 的示例链接(在讨论引用类优点的线程中),该示例将环境嵌入到 S4 对象中以避免复制成本:

https://stat.ethz.ch/pipermail/r-help/2011-September/289987.html

Matthew Dowle 的 'data.table' 包创建了一个新的数据对象类,其使用“[”的访问语义与常规 R data.frames 的访问语义不同,它实际上是作为传递引用工作的。它具有卓越的访问和处理速度。它也可以依靠数据帧语义,因为在后来的几年中,这些对象现在继承了“data.frame”类。

您可能还想调查Hesterberg's dataframe package

【讨论】:

  • 和 +1 用于链接到数据框包,现在已合并(或至少在哲学中)到 R 2.15-1
  • @DWin,感谢您提供的信息。 Pass-by-promise 作为一种优化是有意义的,尽管它对我的情况没有帮助,即多个步骤对同一数据帧进行操作以将其从“原始”变为可处理。通常,修改是在处理管道的不同步骤中执行的,但在某些情况下,它们是在同一调用链中执行的,因为具有不同不变量的抽象边界被交叉。我会研究你推荐的包。
猜你喜欢
  • 2017-04-18
  • 1970-01-01
  • 2016-01-16
  • 2022-01-21
  • 2018-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-19
相关资源
最近更新 更多