使用正式方法定义为S3对象调度S3样式

Jer*_*oen 7 r cran s4

问题相关,但略有不同,希望更清楚.

我正在寻找一种干净的方式来正式注册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);
Run Code Online (Sandbox Code Playgroud)

这个例子展示了我们如何test为类的S3对象注册一个方法bar,而不需要命名该函数test.bar,这很好.但是,限制是如果我们以这种方式注册方法,它们将仅被分派到对象的第一个S3类.例如:

obj2 <- 123;
class(obj2) <- c("foo", "bar");
test(obj2);
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为S4方法调度只会尝试类foo及其超类.如何扩展此示例,test以便bar在找不到合适的方法时自动选择方法foo?例如S3风格调度,但无需返回命名一切test.footest.bar

总结一下:如何创建一个使用形式方法调度的泛型函数,但另外还要回到具有多个类的S3对象的对象的第二,第三等类.

Mar*_*gan 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)
Run Code Online (Sandbox Code Playgroud)

但我个人不会以这种方式混合S3和S4。