6

S4クラスのS3メソッドとして定義するas.matrixか、S3メソッドとして定義すると、たとえば、すぐに使用できることに気付きました。S4メソッドとして定義されている場合、これは機能しません。as.data.framelm (formula, objS4)prcomp (object)

メソッドが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定義では機能します。

4

1 に答える 1

2

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ジェネリックを呼び出していることがわかります。メソッドのドキュメントから

S3ジェネリック関数が直接呼び出された場合、S4メソッドだけは表示されません。ただし、プリミティブ関数と演算子は例外です。オブジェクトがS4オブジェクトである場合に限り、内部CコードはS4メソッドを検索します。例では、[for> class "myFrame"のメソッドは、常にこのクラスのオブジェクトに対して呼び出されます。

于 2013-03-29T19:21:11.787 に答える