S4 课程中是否可以有 S3 插槽?

Kin*_*son 5 r s4

我想知道如何将 S3 对象作为数据成员包含在 S4 对象中,即使用组合而不是继承。这是我的代码片段。

library(randomForest)
set.seed(1337)

setClass("TestManager", slots = c(
    hp = "numeric",
    rfObj = "randomForest")
)

setGeneric("doIt", function(obj) standardGeneric("doIt"))
setMethod("doIt", "TestManager", function(obj) {
    response <- rep(c(0, 1), times = 50) # a vector of length 100
    predictors <- matrix(runif(200), nrow = 100, ncol = 2) # a matrix of dimension 100 x 2

    # package "randomForest" has a function "randomForest"
    # that returns an object of S3 class "randomForest"
    obj@rfObj <- randomForest::randomForest(predictors, response) # <- ERROR!

    return(obj)
})

obj <- new("TestManager", hp = 100)
obj <- doIt(obj)
Run Code Online (Sandbox Code Playgroud)

这将导致错误消息:

Error in validObject(.Object) : 
  invalid class “TestManager” object: undefined class for slot "rfObj" ("randomForest")
In addition: Warning message:
 Error in validObject(.Object) : 
  invalid class “TestManager” object: undefined class for slot "rfObj" ("randomForest") 
Run Code Online (Sandbox Code Playgroud)

MrF*_*ick 5

一种选择是仅使用“ANY”作为插槽类型。这将避免类型检查

setClass("TestManager", slots = c(
    hp = "numeric",
    rfObj = "ANY")
)
Run Code Online (Sandbox Code Playgroud)

否则你可以使用

setOldClass("randomForest")
Run Code Online (Sandbox Code Playgroud)

让 S4 识别 randomForest 类类型。但在您的示例中,您似乎没有初始化该插槽,并且不存在“空”随机森林对象之类的东西,因此您仍然会在初始化时收到错误。如果你想允许NULL值,你可以建立一个union类

setOldClass("randomForest")
setClassUnion("randomForestOrNULL", c("randomForest", "NULL"))
setClass("TestManager", slots = c(
  hp = "numeric",
  rfObj = "randomForestOrNULL")
)
Run Code Online (Sandbox Code Playgroud)

然后这些就可以工作了

obj <- new("TestManager", hp = 100)
obj@rfObj # NULL
obj <- doIt(obj)
obj@rfObj
Run Code Online (Sandbox Code Playgroud)