In R S4 OOP, I'm aware of 2 ways so set default values for a particular class.
1.) Using prototype in setClass()
setClass("Person",
slots = c(
name = "character",
age = "numeric"
),
prototype = list(
name = "Jim",
age = 25
)
)
2.) Using initialize in setMethod()
setMethod("initialize", "Person",
function(.Object,
name,
age,
...) {
.Object@name <- "Jim"
.Object@age <- 25
validObject(.Object)
return(.Object)
}
)
assign("Person", Person, envir = .GlobalEnv)
Can anyone please elaborate on the distinction between these two i.e. why would we want to include a separate initialize method vs using prototype()
in setClass()
? What is S4 best practice?
Thank you in advance for the response.
The prototype is only able to handle simple cases; in particular the value of slots cannot depend on each other and the user cannot specify any dynamic values. For example, if you have a simple class
setClass("personInfo",
slots=list(
age="numeric",
ageSquared="numeric"
), prototype=prototype(
age=18,
ageSquared=18^2
) -> personInfo
then the prototype can only create 18-year old people. Instead, it is more useful to create an initialize method as a function of age
, which can then set both age
and ageSquared
to the relevant values.
Also note that if you assign the results of setClass
into an object (as I did in the example above, assigning it into an object called personInfo
then personInfo
becomes a call to initialize
and you can now call e.g.
personInfo(age=10,ageSquared=100)
(though this isn't ideal in this case as you have to explicitly supply ageSquared
when you could have had the method do that for you.)
I would recommend:
setClass
as an objectinitialize
if some slots depend on others (like ageSquared
here)