as.matrix和as.data.frame S3方法与S4方法 [英] `as.matrix` and `as.data.frame` S3 methods vs. S4 methods
问题描述
我注意到将as.matrix
或as.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屋!