8

特定のS4ジェネリック関数/メソッドに関連付けられているすべてのS4メソッドが、特定のデフォルト値を持つことになっている仮引数を共有しているとします。直感的には、S4ジェネリックの定義でそのような議論を述べます(私には多少冗長に見える各メソッド定義でそれを述べるのとは対照的です)。

ただし、この方法では、仮引数のデフォルト値がメソッドにディスパッチされていないように見え、エラーがスローされるため、問題が発生していることに気付きました。

これは、ジェネリックとメソッドの組み合わせを持つという考えにいくらか反対ではありませんか?デフォルト値が常に同じであるのに、なぜ各メソッドで仮引数を個別に記述しなければならないのですか?どういうわけか、正式な引数のデフォルト値を明示的にディスパッチできますか?


以下に、動作の簡単な図を示します。

ジェネリック関数

setGeneric(
    name="testFoo",
    signature=c("x", "y"),
    def=function(
        x,
        y,
        do.both=FALSE,
        ...
    ) {
    standardGeneric("testFoo")       
    }
)

方法

setMethod(
    f="testFoo", 
    signature=signature(x="numeric", y="numeric"),
    definition=function(
        x,
        y
    ) { 
    if (do.both) {
        out <- list(x=x, y=y)
    } else {
        out <- x
    }
    return(out)
    }
)

エラー

> testFoo(x=1, y=2)
Error in .local(x, y, ...) : object 'do.both' not found

do.bothそれを修正する冗長なステートメント

setMethod(
    f="testFoo", 
    signature=signature(x="numeric", y="numeric"),
    definition=function(
        x,
        y,
        do.both=FALSE
    ) { 
    if (do.both) {
        out <- list(x=x, y=y)
    } else {
        out <- x
    }
    return(out)
    }
)

> testFoo(x=1, y=2)
[1] 1
4

1 に答える 1

9

を呼び出すとtestFoo(x=1, y=2)、最初に S4 ​​ジェネリックによって処理されます。S4 ジェネリックはメソッドを探して見つけ、次のような呼び出しをディスパッチしますtestFoo(x=1, y=2, do.both=FALSE, ...)

の言葉で?standardGeneric

'standardGeneric' は、'f' という名前のジェネリック関数に対して定義されたメソッドを、それが呼び出されたフレーム内の実引数を使用してディスパッチします。

その呼び出しをディスパッチするメソッドが引数を取らない場合、そのメソッドは ---他の R 関数と同様に--- エラーをスローします。関数定義に (a) 仮引数または (b)任意の提供された引数を吸収できる「ドット」引数が含まれていない限り、関数は引数を含む呼び出しを処理できません。do.bothfoofoo...

基本的に、あなたが試したことは次のものと同じですが、同様に失敗しますが、おそらく見やすい方法です。

testFooGeneric <- function(x=1, y=2, do.both=FALSE, ...) {
    ## The line below does essentially what standardGeneric() does
    if(is.numeric(x) & is.numeric(y)) {
        testFooMethod(x=x, y=y, do.both=do.both)
    }
}

testFooMethod <- function(x, y) {
    cat("Success!\n")
}

testFooGeneric(x=1, y=2)
# Error in testFooMethod(x = x, y = y, do.both = do.both) : 
#   unused argument(s) (do.both = do.both)

上記を修正するには、次の 2 つの方法のいずれかで再定義する必要がありtestFooMethod()ます。どちらの方法でも S4 メソッドを修正できます。

## Option 1
testFooMethod <- function(x, y, do.both) {
    cat("Success!\n")
}
testFooGeneric(x=1, y=2)
# Success!

## Option 2
testFooMethod <- function(x, y, ...) {
    cat("Success!\n")
}
testFooGeneric(x=1, y=2)
## Success!
于 2012-09-18T22:20:57.370 に答える