我想知道如何将S3对象作为数据成员包含在S4对象中,即使用 composition 而不是 inheritance 。这是我的代码段。
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)
这将导致错误消息:
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")
答案 0 :(得分:4)
一种选择是仅使用“ ANY”作为插槽类型。这样可以避免类型检查
setClass("TestManager", slots = c(
hp = "numeric",
rfObj = "ANY")
)
否则,您可以使用
setOldClass("randomForest")
让S4识别randomForest类类型。但是在您的示例中,您似乎没有在初始化该插槽,并且没有“空”随机森林对象之类的东西,因此在初始化时仍然会收到错误。如果要允许NULL值,则可以构建联合类
setOldClass("randomForest")
setClassUnion("randomForestOrNULL", c("randomForest", "NULL"))
setClass("TestManager", slots = c(
hp = "numeric",
rfObj = "randomForestOrNULL")
)
然后这些将起作用
obj <- new("TestManager", hp = 100)
obj@rfObj # NULL
obj <- doIt(obj)
obj@rfObj