r - `as.matrix` 和 `as.data.frame` S3 方法与 S4 方法

标签 r methods r-s4

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

为什么方法定义为 S3 或 S4 方法很重要?

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仅当在由数据构建的环境中计算公式时才会发生强制转换,这是一个具有相同行为的更简单的情况:

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 定义却有效。

最佳答案

我从评论中得知,lm只是显式调用as.data.frame。如果你看一下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 泛型,并来自 methods documentation

An S4 method alone will not be seen if the S3 generic function is called directly. However, >primitive functions and operators are exceptions: The internal C code will look for S4 >methods if and only if the object is an S4 object. In the examples, the method for [ for >class "myFrame" will always be called for objects of this class.

关于r - `as.matrix` 和 `as.data.frame` S3 方法与 S4 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15593021/

相关文章:

r - 在 ggplot 中创建半离散颜色条

r - 错误 : evaluation nested too deeply: infinite recursion/options(expressions=)?

java - 帮助简单的方法,Java

r - 使用S3虚拟类作为S4类的插槽,出现错误: got class "S4",应该是或扩展类 "nls.lm"

R 中的类 : S3 vs S4

r - 使用 dynlm 和 lm 的不同回归输出

R Data.table 用于计算多列的摘要统计信息

java - 如何检查当前方法的参数是否具有注释并在 Java 中检索该参数值?

PHP, fatal error : Call to undefined method, 为什么?

json - 写入/读取递归结构 S4 对象