使S4对象充当S3类?

cbo*_*tig 8 r class s4

我想写一个S4对象,以便它可以传递给只接受S3对象的方法.(似乎setOldClass()可能与此有关,但我从文档中不清楚这一点?)

例如,对于一个最小的例子,想象一下我有S3类和函数:

myS3 <- list(a = 1, b = 2)
class(myS3) <- "myS3class"
myS3function.myS3class <- function(x) x$a + x$b
Run Code Online (Sandbox Code Playgroud)

我有S4对象

setClass("myS4class", representation(a = "numeric", b = "numeric"))
obj <- new("myS4class", a = 1, b = 2)
Run Code Online (Sandbox Code Playgroud)

有什么我可以这样做的吗?

myS3function.myS3class(obj) 
Run Code Online (Sandbox Code Playgroud)

给了我同样的东西

myS3function.myS3class(myS3) 
Run Code Online (Sandbox Code Playgroud)

通过仅修改S4类

编辑我这种方法的基本原理是利用S3类的所有现有方法(通常可能来自其他包等),而不必重写它们.我意识到一种方法只是编写一个强制方法(setAs()),将我的S4对象转换为S3对象,但用户总是必须手动执行此步骤.(虽然它有效,但我也有点不清楚使用setAs()S4类到S3类是否是不好的做法,而不是在S4类之间进行映射).

从我阅读文档的方式来看setOldClass,听起来这可以使S3对象像S4对象一样?那是对的吗?如果是这样,我的问题是,是否可以反过来(可能是通过prototype在S4类中设置?).

如果这是不可能的,那么解释为什么这会是一个坏主意的理由呢?

Ric*_*ton 3

向 S4 类添加一个方法,将其转换为 S3 类。

setGeneric(
  "as.myS3class", 
  function(object)
  {
    standardGeneric("as.myS3class")
  }  
)

setMethod(
  "as.myS3class",
  signature(object = "myS4class"),
  function(object)
  {
    structure(list(a = object@a, b = object@b), class = "myS3class")
  }
)
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样调用S3方法:

myS3function(as.myS3class(obj))
Run Code Online (Sandbox Code Playgroud)