Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to have an S3 slot in an S4 class?

Tags:

r

s4

I'm wondering how to include an S3 object as a data member in an S4 object, i.e. using composition instead of inheritance. Here's my code snippet.

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)

This would lead to an error message:

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") 
like image 334
biubiuty Avatar asked Dec 10 '19 20:12

biubiuty


1 Answers

One options is just to use "ANY" as the slot type. This would avoid the type checking

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

Otherwise you can use

setOldClass("randomForest")

to have S4 recognize the randomForest class type. But in your example you don't seem to be initializing that slot and there's no such thing as an "empty" random forest object so you would still get the error on initialization. If you want to allow NULL values, you can build a union class

setOldClass("randomForest")
setClassUnion("randomForestOrNULL", c("randomForest", "NULL"))
setClass("TestManager", slots = c(
  hp = "numeric",
  rfObj = "randomForestOrNULL")
)

Then these will work

obj <- new("TestManager", hp = 100)
obj@rfObj # NULL
obj <- doIt(obj)
obj@rfObj
like image 138
MrFlick Avatar answered Oct 22 '22 13:10

MrFlick