Nic*_*bbe 81
大多数相关信息都可以通过查看?S3或找到?UseMethod,但简而言之:
S3指的是方法调度的方案.如果你使用的R用了一段时间,你会发现有print,predict并summary进行了大量不同类型的对象的方法.
在S3中,这通过以下方式工作:
glm具有类glm)print),则一个点,然后将类名(例如:
print.glm)print工作,但是如果你只是想让自己符合现有的方法名称,你就不需要这个了(如果你做的话,请参阅我之前提到的帮助) ).对于旁观者的眼睛,特别是新创建的时髦模型配件包的使用者来说,能够打字predict(myfit, type="class")比使用更方便predict.mykindoffit(myfit, type="class").
还有更多,但这应该让你开始.这种基于对象的属性(类)调度方法的方式存在很多缺点(而且纯粹主义者可能会在晚上醒来时很恐怖),但在很多情况下,它的工作正常.使用当前版本的R,已经实现了更新的方法(S4和参考类),但是大多数人仍然(仅)使用S3.
Ric*_*ton 50
要开始使用S3,请查看该median函数的代码.打字median在命令提示符下显示,其在它的身上一条线,即
UseMethod("median")
Run Code Online (Sandbox Code Playgroud)
这意味着它是一种S3方法.换句话说,您可以median为不同的S3类使用不同的函数.要列出所有可能的中位数方法,请键入
methods(median) #actually not that interesting.
Run Code Online (Sandbox Code Playgroud)
在这种情况下,只有一个方法,即默认值,可以调用任何方法.您可以通过键入来查看该代码
median.default
Run Code Online (Sandbox Code Playgroud)
一个更有趣的例子是print函数,它有许多不同的方法.
methods(print) #very exciting
Run Code Online (Sandbox Code Playgroud)
请注意,某些方法*的名称旁边有.这意味着它们隐藏在某个包的命名空间中.使用find找出他们是在哪个包.例如
find("acf") #it's in the stats package
stats:::print.acf
Run Code Online (Sandbox Code Playgroud)
小智 37
来自http://adv-r.had.co.nz/OO-essentials.html:
R的三个OO系统在定义类和方法方面有所不同:
S3实现了一种称为泛型函数OO的OO编程风格.这与大多数编程语言不同,例如Java,C++和C#,它们实现消息传递OO.通过消息传递,消息(方法)被发送到对象,对象确定要调用的函数.通常,此对象在方法调用中具有特殊外观,通常出现在方法/消息的名称之前:例如canvas.drawRect("blue").S3是不同的.虽然计算仍然通过方法执行,但是一种称为泛型函数的特殊类型的函数决定调用哪个方法,例如drawRect(canvas,"blue").S3是一个非常随意的系统.它没有正式的类定义.
S4与S3的工作方式类似,但更为正式.S3有两个主要的区别.S4具有正式的类定义,它描述了每个类的表示和继承,并具有用于定义泛型和方法的特殊辅助函数.S4也有多个调度,这意味着泛型函数可以根据任意数量的参数类来选择方法,而不仅仅是一个.
参考类,简称RC,与S3和S4完全不同.RC实现消息传递OO,因此方法属于类,而不是函数.$用于分隔对象和方法,因此方法调用看起来像canvas $ drawRect("blue").RC对象也是可变的:它们不使用R的通常的复制修改语义,而是在适当的位置进行修改.这使得他们更难以推理,但允许他们解决难以用S3或S4解决的问题.
还有另外一个系统不是OO,但重要的是在这里提一下:
- 基本类型,作为其他OO系统基础的内部C级类型.基本类型主要使用C代码进行操作,但它们很重要,因为它们为其他OO系统提供构建块.
小智 9
尝试
methods(residuals)
Run Code Online (Sandbox Code Playgroud)
其中列出了"residuals.lm"和"residuals.glm".这意味着当您拟合线性模型,m和类型时residuals(m),将调用residuals.lm.当您拟合广义线性模型时,将调用residuals.glm.这种C++对象模型是颠倒的.在C++中,您定义了一个具有虚函数的基类,这些函数被派生的类重写.在R中,您定义了一个虚拟(也称为通用)函数,然后您决定哪些类将覆盖此函数(也称为定义方法).请注意,执行此操作的类不需要从一个公共超类派生.我不同意通常更喜欢S3而不是S4.S4有更多的形式(=更多的打字),这对某些应用来说可能太多了.但是,S4类可以像C++中的类或结构一样定义.您可以指定某个类的对象由字符串和两个数字组成,例如:
setClass("myClass", representation(label = "character", x = "numeric", y = "numeric"))
Run Code Online (Sandbox Code Playgroud)
使用该类的对象调用的方法可以依赖于具有这些成员的对象.这与S3类非常不同,后者只是一堆元素的列表.
使用S3和S4,您可以通过fun(object, args)而不是通过调用成员函数object$fun(args).如果您正在寻找类似后者的东西,请查看原型包.
以下是根据Hadley Wickham(RStudio 首席科学家)的“Advanced R,第 2 版”(CRC Press,2019 年)对众多R 对象系统进行更新的快速概述,该文档基于有关对象的章节,在此处有一个 Web 表示面向编程。
\n\n\n\n2015 年的第一版在这里有一个 Web 展示,这里有关于 OO 的相应章节。
\n\nHadley 定义了以下定义来区分两种不同的 OO 编程方法:
\n\n函数式 OOP:方法(可调用代码段)属于泛型函数(不要与 Java/C#泛型方法混淆)。将这些方法视为位于全局查找表中。运行时系统根据函数名称和传递给该函数的一个或多个参数的类型(或对象类)找到要执行的方法(这称为“方法分派”)。从语法角度来看,方法调用可能看起来像普通的函数调用:myfunc(object, arg1, arg2)。如果语言支持这一点。在 R 的 S3 中,通用函数的全名给出了(函数名,类)对。例如:mean.Date是计算日期平均值的方法。尝试methods("mean")列出具有函数名称的通用方法mean。例如,功能性 OOP 方法可以在 OO 先驱Smalltalk、Common Lisp 对象系统和Julia中找到。Hadley 指出,“与 R 相比,Julia\xe2\x80\x99s 实现已完全开发且性能极高。”
封装的 OOP:方法属于对象或类,方法调用通常类似于object.method(arg1, arg2). 这称为封装,因为对象封装了数据(字段)和行为(方法)。将该方法视为位于附加到对象或对象的类描述的查找表中。运行时根据方法名称以及可能的一个或多个参数的类型查找方法。这是“流行”的 OO 语言(如 C++、Java、C#)中采用的方法。
在这两种情况下,如果支持继承(可能是),运行时可能会向上遍历类层次结构,直到找到调用查找键的匹配项。
\n\nlibrary(sloop) # formerly, "pryr"\notype(mtcars)\n#> [1] "S3"\nRun Code Online (Sandbox Code Playgroud)\n\nlibrary(R6))self, private,访问实例super)和成员函数(分配给字段的函数,但不是方法,只是函数)还有其他的,比如R.oo(类似于 RC)、proto(基于原型,想想 JavaScript)和Mutatr。然而,《Advanced R》说:
\n\n\n\n\n除了广泛使用的 R6 之外,这些系统主要具有理论意义。它们确实有自己的优势,但很少有 R 用户知道并理解它们,因此其他人很难阅读并为您的代码做出贡献。
\n
请务必阅读“高级 R,第二版”中有关权衡的章节。
\n| 归档时间: |
|
| 查看次数: |
38720 次 |
| 最近记录: |