J's blog

趣味で統計•データ解析をしています

Rの関数の中身を知りたい

Rの関数の中身を知りたい時のお話です。


基本的には、
> 関数名
としてしまえば下のmatrix関数のように参照することができます。

> matrix
function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL) 
{
    if (is.object(data) || !is.atomic(data)) 
        data <- as.vector(data)
    .Internal(matrix(data, nrow, ncol, byrow, dimnames, missing(nrow), 
        missing(ncol)))
}
<bytecode: 0x7f8ffc2bad78>
<environment: namespace:base>


しかし、aggregate関数のように

> aggregate
function (x, ...) 
UseMethod("aggregate")
<bytecode: 0x7fa16dab4f18>
<environment: namespace:stats>

と参照できない場合があります。このような関数は総称的関数といい、様々なクラスに対応させるため、引数に入れる変数のクラスごとの関数(メソッドという)をまとめた関数になります。これは総称的関数の中に複数のメソッドを含む形となります。総称的関数を実行すると、その時に入れた引数のクラスによって適切なメソッドが選択され、実行されます。
UseMethodにあるのが総称的関数ですので、その中のメソッドを見るためにはmethods関数で呼び出しましょう。

> methods(aggregate)
[1] aggregate.data.frame aggregate.default    aggregate.formula*   aggregate.ts        

   Non-visible functions are asterisked

これで、aggregate関数はaggregate.data.frame、aggregate.default、aggregate.formula*、aggregate.tsの4つのメソッドで構成されていることがわかりました。
このうち、「*」のついているメソッドは中身が隠蔽されており、matrix関数のように参照することができません。この場合は、getS3method関数で(またはgetAnywhere関数)
> getS3method("メソッド名", "クラス名")
とすると参照できます。

> getS3method("aggregate", "formula")
function (formula, data, FUN, ..., subset, na.action = na.omit) 
{
    if (missing(formula) || !inherits(formula, "formula")) 
        stop("'formula' missing or incorrect")
    if (length(formula) != 3L) 
 # 以下略