7

この質問に関連していますが、少し異なり、うまくいけばもっと明確になります。

私は、S4クラスとS3クラスの両方のメソッドを正式に登録するためのクリーンな方法を探していますが、ディスパッチするためにひどいS3-dot-naming-schemeに依存することはありません。例:

setClass("foo");
setClass("bar");

setGeneric("test", function(x, ...){
    standardGeneric("test");
});

setMethod("test", "bar", function(x, ...){
    return("success (bar).");
});

obj1 <- 123;
class(obj1) <- "bar";
test(obj1);

この例は、関数に名前を付ける必要なしに、testクラスのS3オブジェクトのメソッドを登録する方法を示しています。これはすばらしいことです。ただし、この方法でメソッドを登録すると、オブジェクトの最初のS3クラスにのみディスパッチされるという制限があります。例えば:bartest.bar

obj2 <- 123;
class(obj2) <- c("foo", "bar");
test(obj2);

fooS4メソッドディスパッチはクラスとそのスーパークラスのみを試行するため、これは機能しません。この例を拡張して、適切なメソッドが見つからなかった場合にtestメソッドを自動的に選択するようにするにはどうすればよいでしょうか。たとえば、S3スタイルのディスパッチですが、すべての名前付けに戻る必要はありませんか?barfootest.footest.bar

要約すると、形式手法ディスパッチを使用するジェネリック関数を作成する方法ですが、さらに、複数のクラスを持つS3オブジェクトのオブジェクトの2番目、3番目などのクラスにフォールバックします。

4

2 に答える 2

3

?setOldClass答えを与えるでしょう:

setOldClass(c("foo", "bar"))

setGeneric("test", function(x, ...)standardGeneric("test"))
setMethod("test", "bar", function(x, ...)return("success (bar)."))
于 2012-08-24T16:19:13.523 に答える
2

あなたはメソッドを書くことができます

test = function(x, ...) UseMethod("test")

setGeneric("test")

.redispatch = function(x, ...)
{
    if (is.object(x) && !isS4(x) && length(class(x)) != 1L) {
        class(x) = class(x)[-1]
        callGeneric(x, ...)
    } else callNextMethod(x, ...)
}

setMethod(test, "ANY", .redispatch)

しかし、私は個人的にこのようにS3とS4を混ぜることはしませんでした。

于 2012-08-25T12:14:13.247 に答える