[R] creating list with 200 identical objects

Rainer M Krug r.m.krug at gmail.com
Tue Jun 2 09:42:22 CEST 2009


Thanks a lot Wacek for this clear description of the problem - I was
not aware, that it is that complex.
I definitely did not consider the initialize() function in writing my code.

But as I only want to allocate the space for the objects, it does not
matter here. But when I write a simulation and want to initialize it
with two hundred different individuals, this definitely becomes
crucial - thanks again for this clarification and the very useful
references (especially [2] for the moment).

Am I right that all assignments of classes via <- or -> are by value
and NOT by reference? So when

setClass('foo',
       representation=representation(content='character'),
       prototype=list(content='foo'))

A <- new("foo")
B <- A

B is a different object then A, i.e. changes in B are not reflected in
A and vice versa, but they have the same content.

It seems that if foo has a slot O containing an object of class
"fooInFoo", this object O also copied by value. I.e. when, following
above,

setClass('foo2',
       representation=representation(content='character'),
       prototype=list(content='fooInFoo'))
setClass('foo',
       representation=representation(content='character', O='foo2'),
       prototype=list(content='foo', O=new('foo2')))
A <- new("foo")
B <- A

A at O@content <- "AAAAAAAAAAAAAA"
A at O@content
  [1] "AAAAAAAAAAAAAA"
B at O@content
  [1] "fooInFoo"

Is this always the case? and is there a way of copying by reference
(or passing an object to a function by reference)?

Rainer
Cheers

Rainer

On Mon, Jun 1, 2009 at 11:36 PM, Wacek Kusnierczyk
<Waclaw.Marcin.Kusnierczyk at idi.ntnu.no> wrote:
> Wacek Kusnierczyk wrote:
>>
>> consider:
>>
>>     setClass('foo',
>>        representation=representation(content='environment'))
>>     setMethod('initialize', 'foo', function(.Object) {
>>         .Object at content = new.env()
>>         .Object at content$name = 'foo'
>>         .Object })
>>
>>     foos = rep(list(new('foo')), 2)
>>     foos[[1]]@content$name = 'bar'
>>     foos[[2]]@content$name
>>     # 'bar'
>>
>> of course, because you have just one object twice on the list, its
>> content is an environment, and with environments r does not pretend to
>> be functional.  but:
>>
>>     foos = lapply(1:2, function(x) new('foo'))
>>     foos[[1]]@content$name = 'bar'
>>     foos[[2]]@content$name
>>     # 'foo'
>>
>> of course, because you have two distinct objects, and assignment to one
>> of them has no effect on the other.  similarly if 'foo' is defined as
>> follows:
>>
>>     setClass('foo',
>>        representation=representation(content='environment'))
>>     setMethod('initialize', 'foo', function(.Object) {
>>        .Object at content$name = 'foo'
>>        .Object })
>>
>> or as follows:
>>
>>     setClass('foo',
>>        representation=representation(content='environment'),
>>        prototype=list(content={
>>            e=new.env()
>>            e$name='foo'
>>            e }))
>>
>>
>
> actually, not the last one;  i got caught by that redefining 'foo' with
> setClass does not remove the initializer.  so here's another situation
> (best to execute in a fresh session) you should beware:
>
>    setClass('foo',
>        representation=representation(content='environment'),
>        prototype=list(content={
>            e=new.env()
>            e$name='foo'
>            e }))
>
>    foos = lapply(1:2, function(x) new('foo'))
>    foos[[1]]@content$name = 'bar'
>    foos[[2]]@content$name
>    # "bar"
>
> in this case, even if you're careful enough to create two objects, they
> share the representation because they both get it from the same prototype.
>
> vQ
>
>
>



-- 
Rainer M. Krug, Centre of Excellence for Invasion Biology,
Stellenbosch University, South Africa




More information about the R-help mailing list