在 R 编程中使用 S4方法什么时候会有回报

我经常在专业环境下使用 R 语言编程,我也为客户或同事编写软件包。这里的一些程序员有 Java 背景,并坚持使用 S4方法以面向对象的方式完成所有工作。另一方面,我的经验是,当试图让代码做您想让它做的事情时,S4实现常常表现得更差,并且会造成更多的麻烦。

我完全同意在某些情况下,您必须能够构造复杂的对象或者以受控的方式附加现有的对象。但是大多数时候,S4实现也可以很容易地使用经典列表来完成,而不必像定义标准泛型、方法、构造函数、初始化器等等那样麻烦。

您什么时候考虑为 R 编写 S4实现?

编辑: 为了清晰起见,我非常欣赏 R 中关于 OO 的答案和讨论,在 R 中可以通过多种方式进行 OOP 的讨论,但是我的问题实际上是针对具体使用 S4方法的附加值。

5151 次浏览

我的经验和你的一致,所以我只使用 S3。

澄清一下: S4有一些漂亮的特性(例如对多个参数进行分派和插槽类型检查) ,但我还没有遇到过这样的情况: 特性超过了成本。成本的例子包括: 任何槽的更改都需要完整的对象副本,以及(可能更糟的)对 S4方法的持续更改。

简而言之,我喜欢 S4背后的想法,但我会等到它成熟之后再在我自己的代码中使用它。

好问题! 我希望能引起一些深思熟虑的讨论..。

我从未使用过,也不打算使用,原因如下:

  1. 表演
  2. 我没有耐心去完全理解 S4和它与 S3的关系。
  3. 语法上的保留: 我宁愿使用 object.method ()而不是 method (object)。

我喜欢糖,我能说什么呢!

S4类在空间统计(sensu 包 sp)中发挥了重要作用,在这里,从一种类型的数据到另一种类型的数据的转换似乎是无缝的。这样做的缺陷是调试,以我的经验来看,调试充其量是乏味的。 到目前为止,我已经使用了 S3,但将来可能会考虑使用 S4。

随着时间的推移,随着事情变得越来越多,我相信它们至少会在 R 的各个领域的核心特征(可能是空间分析、计量经济学、环境计量学... ...)中发挥重要作用

不要忘记还有 R.OO (在 CRAN 上) ,它提供了在 R.中进行 OO 的第三种方法。在我看来,这提供了一个面向对象系统,对于从其他系统迁移过来的程序员来说,这个系统可能更为熟悉——特别是,它没有泛型函数(这样 print (foo)就必须分派 foo 类) ,而是将方法绑定到对象上,所以可以使用 foo $print ()——就像在 python 或 C + + 中使用 foo.print ()一样。

我假设这并不直接适用于你,但是如果你正在为 Bioiconductor 开发软件包,那么你就有动力使用 S4,因为他们积极鼓励使用它,并且已经使用了十年的大部分时间——所以所有的核心软件包都大量使用 S4。

我发现所有的额外开销都很麻烦—— setGeneric、 setMethod、处理 NAMESPACE 等等。尽管如此,我发现它所强加的结构、可扩展性的潜力以及其他诸如此类的东西都是值得的。和所有事情一样,这里面也有权衡。我认为它可以干净得多——我不喜欢 s3方法被变数命名原则(foo.class)所掩盖。尽管如此,我倾向于避免在自己的代码中大量使用 S4,除非有人告诉我这样做。

我学习 S4是为了扩展动物轨迹数据的空间(sp)类。它是可用选项中的最佳选择(最一致、通用和与许多 GIS 定义密切匹配) ,以避免从头开始编写所需的所有内容。我并不像很多人说的那样觉得 S4很繁琐,但是我现在已经习惯于探索类似这样的对象的底层结构。性能也很好,我认为它可以做得很好,尽管当做得不好的时候会有性能陷阱。

如果您对空间数据感兴趣,spatstat 是一个很好的例子,说明如何在 S3中做很多与 sp 类似的事情,尽管(似乎所有的空间... ...)在不同软件的数据结构之间几乎没有清晰的类比。

从前,Roxygen2不喜欢 S4方法。到2017年(至少) ,它们一起工作。

我不幸地创建了一些需要方法来处理 S3和 S4类的函数。多年来,让这些代码继续工作是一件非常痛苦的事情,因为 R-core 已经多次更改了关于这些系统如何交互、名称空间如何工作以及 Rcmd 检查如何工作的细节。

如果你不喜欢 Google 的风格指南,那么考虑一下这些著名的 R 软件包开发人员在 救命上的评论

Frank Harrell “如果你热爱计算机科学胜过珍惜自己的时间,那么就使用 S4。”

Terry Therneau 写道: 对于我所做的90% 的事情,我强烈地喜欢松散的(S3)而不是刚性的(S4)类... ... 我对 S4和 S3的总结

中四学生在以下方面的升幅较大: 1. 写作麻烦 2. 调试困难 能够写出晦涩难懂的代码 4. 设计

中四收益: 5. 指导自动转换的能力 验证类对象的内容