与this问题相关,但略有不同,希望更清楚。
我正在寻找一种 clean 方式来正式注册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对象注册bar
方法,而无需将函数命名为test.bar
,这很棒。但是,限制是如果我们以这种方式注册方法,它们将仅被分派到对象的第一个S3类。 E.g:
obj2 <- 123;
class(obj2) <- c("foo", "bar");
test(obj2);
这不起作用,因为S4方法调度只会尝试类foo
及其超类。如果找不到test
的适当方法,如何扩展此示例以便自动为bar
选择foo
方法?例如。 S3样式调度,但无需返回命名所有内容test.foo
和test.bar
?
总结:如何创建一个使用形式方法调度的泛型函数,但另外还要回到具有多个类的S3对象的对象的第二,第三等类。
答案 0 :(得分:3)
?setOldClass
会给出答案:
setOldClass(c("foo", "bar"))
setGeneric("test", function(x, ...)standardGeneric("test"))
setMethod("test", "bar", function(x, ...)return("success (bar)."))
答案 1 :(得分: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。