【问题标题】:How do you get S3 methods to work with S4 objects?如何让 S3 方法与 S4 对象一起工作?
【发布时间】:2011-05-06 14:47:27
【问题描述】:

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

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

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

这是我的测试 S4 对象:

library(gWidgetstcltk)
win <- gwindow()

methods 包中的 S3PartS3Class 函数看起来很有希望,但是当我在 win 上使用它们时它们都会抛出错误。那么,问题 2 是:有没有一种通用的方法可以将 S4 对象转换为列表?

【问题讨论】:

    标签: oop r r-s3 r-s4


    【解决方案1】:

    S4 是一个不能直接用于调度的超类(虚拟类,无论如何,请有人用正确的名称插话)。顺便说一句,S3 也一样。您可以像处理 S3 类一样为 S4 类进行 S3 调度。在旁注中,如果未指定任何内容,则在 S4 对象上调用 myfun 只会导致 .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 方法,您可以使用 isS4() 在您的 .default 函数或泛型函数中手动调度。在 .default 函数中添加调度允许自动 S3 调度到某些 S4 类。如果你将它添加到泛型中,你只需派发到所有 S4 无事:

        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对象。

    【讨论】:

    • 谢谢。调度现在更有意义了。看起来我偶然发现了一个棘手的测试用例;将不得不尝试其他一些并进一步调查。
    • gwindow 对象确实是一个不好的例子。我相信我为 gWidgets 对象定义的长度方法弄乱了 str。 gwindow 对象有两个插槽,一个用于保存工具包(gWidgetsXXX 包用于方法分派),另一个用于gWidgetsXXX 包中的对象。然而,Joris 正在展示该怎么做。 gWindow 有一个超类,可以用来捕捉其他人。
    • @John:感谢您的澄清。我将首先专注于解决更简单的案例。
    猜你喜欢
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    • 2020-12-13
    • 2012-02-02
    相关资源
    最近更新 更多