如何让 S3 方法与 S4 对象一起使用?

发布于 2024-11-05 11:57:30 字数 601 浏览 6 评论 0原文

我正在编写一个 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 看起来很有前途,但是当我使用它们时,它们都会抛出错误获胜。所以,问题 2 是:是否有将 S4 对象转换为列表的通用方法?

I'm writing an S3 method that I want to work with any R object, including S4 objects.

The first thing I don't understand is that S4 classes don't appear to derive from an S4 base class, so given f <- function(x) UseMethod("f") I can't just declare an f.S4 dispatch method and have it pick up all S4 objects. (Although if you unclass an S4 object, it does seem to be given class S4.) How should I manage the dispatching?

It seems that the easiest way to deal with these S4 objects would be to convert them to be lists. Unfortunately, as.list throws an error ("no method for coercing this S4 class to a vector").

This is my test S4 object:

library(gWidgetstcltk)
win <- gwindow()

The functions S3Part and S3Class in the methods package looked promising, but they both throw errors when I use them on win. So, question 2 is: Is there a general way of converting S4 objects to lists?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眼泪都笑了 2024-11-12 11:57:30

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

S4 is a superclass (virtual class, whatever, somebody please chime in with the correct name) that cannot be used directly dispatching. Same for S3 by the way. You can do S3-dispatching for S4 classes the way you do with S3 classes. On a sidenote, if nothing is specified then calling myfun on an S4 object will just lead to the .default function. :

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)

If you want to catch all S4 methods, you can dispatch manually in your .default function or generic function, using isS4(). Adding the dispatching in the .default function allows for automatic S3 dispatching to some S4 classes. If you add it in the generic, you just dispatch to all 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)

Regarding your second question: gWindow is a special case. It also returns an error when tried with str(win). I don't know the exact structure, but it's definitely not a normal S4 object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文