[R] S4 Classes and Initialize methods
Martin Morgan
mtmorgan at fhcrc.org
Tue Feb 5 19:13:03 CET 2013
On 02/05/2013 04:42 AM, Franck Doray wrote:
> Hello,
>
> I am trying to improve my skill on S4 classes. But there's something
> strange (to me) happening with "initialize" methods. This is probably a
> normal behaviour... but... something is unclear in my mind
>
> I declare two classes, namely "A", and "B", which has a slot of type A. The
> class "A" has an initialize method. What I do not understand is that the
> Class A initialize-method is run when defining the Class B
> Here is the code .
>> setClass("A",representation=representation(a="numeric"))
>> setMethod("initialize","A",function(.Object){cat("*** initialize A
> ***\n");return(.Object)})
> [1] "initialize"
>>
>>
>> setClass("B",representation=representation(a="A",b="numeric"))
>> setClass("B",representation=representation(a="A",b="numeric"))
> *** initialize A ***
>>
>
> Actually I do not understand the line *** initialize A ***. What the need
> to initialize A just in a (simple) definition of the class B?
Hi Franck --
That's probably not a useful question to ask, it's an implementation detail, but
I think because S4 classes have a prototype, and the default prototype for class
B's slot 'a' is constructed by calling new("A"):
> getClassDef("B")@prototype
<S4 Type Object>
attr(,"a")
An object of class "A"
Slot "a":
numeric(0)
attr(,"b")
numeric(0)
Maybe you came across this issue in some context? A couple of thoughts...
>> setMethod("initialize","A",function(.Object){cat("*** initialize A
> ***\n");return(.Object)})
> [1] "initialize"
Usually one wants to add '...' to the initialize method, and to callNextMethod()
inside initialize. This is because the default method fills in slots with named
arguments, so derived (perhaps even 'A') classes with simple slot initialization
do not need an initialize method at all. Thus
setMethod(initialize, "A", function(.Object, ...) {
message("initialize,A-method")
callNextMethod(.Object, ...)
})
C = setClass("C", contains="A", representation=representation(x="numeric"))
C(a=1:5, x=5:1)
with
> C(a=1:5, x=5:1)
initialize,A-method
An object of class "C"
Slot "x":
[1] 5 4 3 2 1
Slot "a":
[1] 1 2 3 4 5
(this uses a feature added in a relatively recent R, where setClass returns a
constructor which is basically a call to 'new').
> C
class generator function for class "C" from package '.GlobalEnv'
function (...)
new("C", ...)
Since my initialize,A-method doesn't actually do anything useful, I would
normally not implement it. If I were to write an initialize method, e.g,.
coercing 'x' to their absolute value, I'd write it so that (a) there is a
default value to 'x', so that new("A") with no arguments works and (b) make sure
that the argument 'x' came after ..., so that unnamed arguments are used in the
initialize method's copy construction mode. I try to illustrate this below
A <- setClass("A",representation=representation(a="numeric"))
setMethod(initialize, "A", function(.Object, ..., a=numeric()) {
callNextMethod(.Object, ..., a=abs(a))
})
And then
> ## no-arg constructor
> A()
An object of class "A"
Slot "a":
numeric(0)
> ## constructor with arg
> (a1 = A(a=-(1:5)))
An object of class "A"
Slot "a":
[1] 1 2 3 4 5
> ## copy constructor
> initialize(a1, a=-(5:1))
An object of class "A"
Slot "a":
[1] 5 4 3 2 1
The above is with
> R.version.string
[1] "R Under development (unstable) (2013-02-02 r61819)"
Martin
>
> Thanks in advance
> Franck
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
--
Computational Biology / Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N.
PO Box 19024 Seattle, WA 98109
Location: Arnold Building M1 B861
Phone: (206) 667-2793
More information about the R-help
mailing list