as.matrix和as.data.frame S3方法与S4方法 [英] `as.matrix` and `as.data.frame` S3 methods vs. S4 methods

查看:425
本文介绍了as.matrix和as.data.frame S3方法与S4方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到将as.matrixas.data.frame定义为S4类的S3方法 使例如lm (formula, objS4)prcomp (object)开箱即用.如果将它们定义为S4方法,则无法使用.

I noticed that defining as.matrix or as.data.frame as S3 methods for an S4 class makes e.g. lm (formula, objS4) and prcomp (object) work out of the box. This doesn't work if they are defined as S4 methods.

为什么将这些方法定义为S3或S4方法都重要?

Why does it matter whether the methods are defined as S3 or S4 method?

as.data.frame的示例:

setClass ("exampleclass", representation (x = "data.frame"))
object <- new ("exampleclass", x = iris)

setMethod ("as.data.frame", signature="exampleclass", definition= function (x, ...) x@x )
## [1] "as.data.frame"

as.data.frame (object)
## Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 1            5.1         3.5          1.4         0.2     setosa
## 2            4.9         3.0          1.4         0.2     setosa
## 3            4.7         3.2          1.3         0.2     setosa
## ...snip...

lm (Petal.Length ~ Petal.Width, object)
## error in as.data.frame.default(data) : 
##   cannot coerce class 'structure("exampleclass", package = ".GlobalEnv")' into a data.frame

as.data.frame.exampleclass <- function (x, ...) x@x

lm (Petal.Length ~ Petal.Width, object)
## Call:
##   lm(formula = Petal.Length ~ Petal.Width, data = object)
## 
## Coefficients:
##   (Intercept)  Petal.Width  
## 1.084        2.230  

由于lm的情况可能有点复杂,其中强制仅在从数据构造的环境中对公式进行求值时才会发生,这是一种更简单的情况,具有相同的行为:

As the situation may be a bit complicated with lm where the coercion will only occur when the formula is evaluated in an environment constructed from the data, here is a more simple case whith the same behaviour:

setMethod ("as.matrix", signature="exampleclass", definition= function (x, ...) as.matrix (x@x[, 1:4]) )
prcomp (object)
## error in as.vector(data) : 
##   No method to coerce this S4 class into a vector
as.matrix.exampleclass <- function (x, ...) as.matrix (x@x [, 1:4])
prcomp (object)
##   Standard deviations:
##     [1] 2.0562689 0.4926162 0.2796596 0.1543862
##   
## Rotation:
##   PC1         PC2         PC3        PC4
## Sepal.Length  0.36138659 -0.65658877  0.58202985  0.3154872
## Sepal.Width  -0.08452251 -0.73016143 -0.59791083 -0.3197231
## Petal.Length  0.85667061  0.17337266 -0.07623608 -0.4798390
## Petal.Width   0.35828920  0.07548102 -0.54583143  0.7536574

在这里,调用stats:::prcomp.default,它以普通的x <- as.matrix (x)开头.对于上述S4定义,此操作将失败,但可与S3定义一起使用.

Here, stats:::prcomp.default is called, which starts with a plain x <- as.matrix (x). This fails with the above S4 definition, but works with the S3 definition.

推荐答案

我从lm简单地显式调用as.data.frame的注释中得出结论.如果您查看as.data.frame:

I take it from the comments that lm simply calls as.data.frame explicitly. If you look at as.data.frame:

> as.data.frame
function (x, row.names = NULL, optional = FALSE, ...) 
{
    if (is.null(x)) 
        return(as.data.frame(list()))
    UseMethod("as.data.frame")
}
<bytecode: 0x29140b8>
<environment: namespace:base>

您将看到它调用了S3泛型,并且来自方法文档

You'll see that it calls the S3 generic, and from the methods documentation

如果直接调用S3泛型函数,将不会看到仅一个S4方法.但是,>原始函数和运算符是一个例外:当且仅当对象是S4对象时,内部C代码才会查找S4>方法.在示例中,对于此类"myFrame"的对象,始终会调用[的方法.

这篇关于as.matrix和as.data.frame S3方法与S4方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆