6

我正在编写一个 S3 方法,我想使用任何R 对象,包括 S4 对象。

我不明白的第一件事是 S4 类似乎不是从 S4 基类派生的,所以鉴于f <- function(x) UseMethod("f")我不能只声明一个f.S4调度方法并让它拾取所有 S4 对象。(虽然如果你unclass是一个 S4 对象,它似乎被赋予了 class S4。)我应该如何管理调度?

似乎处理这些 S4 对象的最简单方法是将它们转换为列表。不幸的是,as.list抛出一个错误(“没有将这个 S4 类强制为向量的方法”)。

这是我的测试 S4 对象:

library(gWidgetstcltk)
win <- gwindow()

包中的函数S3Part和函数看起来很有希望,但是当我在. 所以,问题 2 是:是否有将 S4 对象转换为列表的通用方法?S3Classmethodswin

4

1 回答 1

8

S4 是一个不能直接用于调度的超类(虚拟类,无论如何,请有人用正确的名称插话)。顺便说一句,S3 也一样。您可以像处理 S3 类一样为 S4 类进行 S3 调度。在旁注中,如果未指定任何内容,则调用myfunS4 对象只会导致 .default 函数。:

myfun <- function(object, ...) UseMethod("myfun")

myfun.default <- function(object,...){
    cat("default method.\n")
    print(object)
}

myfun.gWindow <- function(object,...){
    cat("Here here...")
    print(object)
}

x <- 1:10
myfun(x)
myfun(win)
rm(myfun.gWindow)
myfun(win)

如果你想捕获所有 S4 方法,你可以在你的 .default 函数或通用函数中手动调度,使用isS4(). 在 .default 函数中添加调度允许自动 S3 调度到某些 S4 类。如果将其添加到泛型中,则只需派发到所有 S4 no-matter-what :

    myfun.default <- function(object,...){
        if(isS4(object)) myfun.S4(object,...)
        else {
          cat("default method.\n")
          print(object)
        }
    }

    myfun.S4 <- function(object,...){
        cat("S4 method\n")
        print(object)
    }

x <- 1:10
myfun(x)
myfun(win)

关于你的第二个问题:gWindow是一个特例。尝试使用时也会返回错误str(win)。我不知道确切的结构,但它绝对不是一个普通的 S4 对象。

于 2011-05-06T15:25:39.407 回答