什么时候在R编程中使用S4方法值得


72

我经常在专业环境下用R编程,也为客户或同事编写程序包。这里的一些程序员具有Java背景,并坚持使用S4方法以面向对象的方式进行所有操作。另一方面,我的经验是,在尝试使代码执行您想要执行的操作时,S4实现通常会执行得更糟,并且导致更多的麻烦。

我绝对同意,在某些情况下,您必须能够以受控的方式构造复杂的对象或追加现有对象。但是在大多数情况下,也可以使用经典列表轻松完成S4实现,而无需像定义standardGeneric,方法,构造函数,初始化程序之类的麻烦。

您何时考虑为R编写S4实现?

编辑:为清楚起见,我确实很欣赏R中有关OO的答案和讨论。OOP可以在R中以多种方式完成,但我的问题确实是针对使用S4方法的附加价值。


但是S3是合法的面向对象!它比S4更为现代和灵活。
2010年

2
@Joris多重继承?可以通过将对象及其类与合并来完成c。正式验证?没有人说必须通过严格的输入来完成OOP。Smalltalk是一个很好的例子。总的来说,我认为OOP只是一种方式,因此没有“规范的” OOP(尽管人们通常会选择他们喜欢的语言并说它定义了这种语言)。
2010年

1
@mbq:好的,然后您要明白什么是OOP,什么不是。您可以通过仅使用列表并手动设置所有属性来轻松地编程面向对象的方式。 我的同事来自Java背景,如果它迫使您以面向对象的方式进行操作,则称其为OOP。S3不会,S4会为他们做,我也一样。您的里程可能会有所不同,但我认为您确实同意S3和S4是两种不同的野兽。我想对使用S4的一些想法,不是一些语义讨论究竟什么是OOP中R.
里斯Meys

2
我认为部分问题是S3和S4都没有提供一种OO结构,而这种结构实际上与Java / C ++类型的世界中的某人将要习惯的东西相似,对于那些精于此的人来说,这似乎都是陌生的风格的OO与暴露于Lisp,Dylan等的人相比
geoffjentry 2010年

1
@geoffjentry好点!这并不能使它们“减少OO”。
mbq 2010年

Answers:


25

我假设这并不直接适用于您,但是如果您正在为Bioconductor开发软件包,则有一种使用S4的动机,因为他们积极鼓励使用S4,并且在现在的十年中大部分时间都在使用-因此,所有核心软件包大量使用了S4。

我发现所有额外的开销都很痛苦-setGeneric,setMethod,处理NAMESPACE等。话虽如此,我发现它所强加的结构,可扩展性以及其他类似的东西是值得的。与所有内容一样,也要进行权衡。我认为它可以使工作更清洁-我不喜欢S3方法是如何简单地通过命名约定(foo.class)伪装的。话虽这么说,除非我被告知这样做,否则我倾向于避免在自己的代码中大量使用S4。


27

我的经验与您的经验一致,因此我仅使用S3。

需要说明的是:S4具有一些巧妙的功能(例如,在多个参数上分派和插槽类型检查),但是我还没有遇到过这些功能超过成本的情况。成本的示例包括:任何插槽更改都需要完整的对象副本,以及(可能更糟的)正在进行的S4方法更改。

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


1
因此,五年后……您是否继续坚持使用S3?
同构2015年

4
@isomorphismes:是的。我对R6替代S4感兴趣。
Joshua Ulrich

1
@JoshuaUlrich:您是说R6是S4的替代品,还是有不同的用例?
histelheim

9

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

我从未使用过它,也没有打算出于以下原因:

  1. 性能
  2. 我没有耐心完全理解S4及其与S3的关系。
  3. 语法概述:我宁愿有object.method()而不是method(object)。

我喜欢苏加尔,我能说什么!


4
我也不使用S4,因为我喜欢object.method()。Google的R风格说:“除非有充分的理由使用S4对象或方法,否则请使用S3对象和方法。S4对象的主要理由是直接在C ++代码中使用对象。S4泛型/方法是分派两个参数”
Vince 2010年

12
FWIW,为什么Google拥有R风格的权威?R-core不应在此问题上具有更高的权威吗?(不是R-core在此问题上似乎是统一的,而是...)。正是由于这个原因,Google R风格指南的狂热使我有些恼火。
geoffjentry,2010年

4
@geoffjentry我的一部分感觉完全像说的一样……但是,我很高兴人们正在一点点地考虑样式。而且,如果在PDF上带有GOOG徽标,则让某些经济学家(或统计学家等)阅读该徽标,那么我全力以赴。我厌倦了尝试阅读由于格式和样式而难以解析的代码。
JD

3
当然,如果R-core愿意,他们可以轻松解决此问题,因此,我想他们要么满意,要么根本不在乎Google准则。编辑:从该线程(tinyurl.com/3ydaa89)判断,Dalgaard和Murdoch都在回答,我猜这更像是冷漠的角度。
geoffjentry,2010年

9

我学习了S4,以便扩展动物跟踪数据的Spatial(sp)类。这是可用选项中的最佳选择(最一致,最通用且与许多GIS定义最匹配),以避免从头开始编写所有内容。我发现S4并不像许多人所说的那么繁重,但是我现在已经习惯于探索这样的对象的底层结构。性能也不错,我认为可以做得很好,尽管做得不好也会有性能陷阱。

如果您对空间数据感兴趣,那么spatstat就是一个很好的例子,它说明了如何在S3中执行许多与sp相似的操作,尽管(似乎所有空间都是……)在不同软件中的数据结构之间几乎没有清晰的类比。


6

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

随着时间的流逝,随着事情的发展,我相信它们至少会在R的各个领域的核心特征中发挥重要作用(例如空间分析,计量经济学,环境计量学……)


2
实际上,R的不断增长的部分在S4类中进行了重新编码,但是在使用这些软件包时我遇到了越来越多的问题。文档旨在直接使用,但缺乏编程用途。如您所知,在使用许多程序包的S4编码方法评估函数参数时,我也遇到麻烦。因此,我倾向于远离它们,我希望有人可以向我展示一个很好的用途。
乔里斯·梅斯

5

不要忘记,还有R.oo(在CRAN上)提供了第三种在R中进行OO的方法。在我看来,这提供了一个从其他系统迁移的程序员可能更熟悉的OO系统-特别是没有通用的函数(这样print(foo)然后必须在foo类上分派)方法绑定到对象,因此您将执行foo $ print()-就像在python或C ++中一样,您将执行foo.print ()。


我以前见过,但我一直想知道额外的增值是什么。除了语义之外,我与S3编程没有任何区别。但老实说,我还没有深入研究它。
乔里斯·梅斯

4

很久以前,Roxygen2不喜欢S4方法。截至2017年(至少),他们一起工作。

我很不幸地创建了一些需要使用S3和S4类的方法的函数。由于R-core已多次更改有关这些系统如何交互,命名空间如何工作以及Rcmd检查如何工作的详细信息,多年来保持此代码的工作非常痛苦。

如果您不喜欢Google的样式指南,请在R-help上的该主题中考虑这些知名R包开发人员的评论。

弗兰克·哈雷尔(Frank Harrell)“如果您对计算机科学的热爱超过了对自己时间的重视,请使用S4。”

特里·特内(Terry Therneau)写道:对于我所做的90%的工作,我强烈喜欢松散(S3)而不是严格(S4)类....我对S4 vs S3的总结

S4在以下方面有很大的增长:1.编写麻烦的代码2.调试困难3.编写非常晦涩的代码的能力4.设计

S4收益:5.能够进行自动转换6.验证类对象的内容


很久以前的更新:现在可以了
Joris Meys '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.