Re: [R] creating objects with a slot of class formula, using new

From: Martin Maechler <maechler_at_stat.math.ethz.ch>
Date: Thu 19 Jan 2006 - 19:20:11 EST

>>>>> "Gabor" == Gabor Grothendieck <ggrothendieck@gmail.com> >>>>> on Thu, 19 Jan 2006 00:27:42 -0500 writes:

    Gabor> Create a virtual class that can either be a formula or be NULL:

    > setClassUnion("formulaOrNULL", c("formula", "NULL"))
    > setClass("a",representation(b="list",c="formulaOrNULL"))
    > new("a", b = list(7))

that's one possibility, and probably closest to what Steve was asking for, however read on

    Gabor> On 1/18/06, Steven Lacey <slacey@umich.edu> wrote:
>> Hi,
>>
>> .....
>>
>> But, now suppose you want a slot to accept an object of class formula...

>> >setClass("a",representation(b="list",c="formula"))
>> >new("a",b=list(7))
>> >Error in validObject(.Object) : invalid class "a" object: invalid object
>> for slot "c" in class "a": got class "NULL", should be or extend class
>> "formula"
>>
>> Why can't new handle this? Why must the slot be defined?

the 'c' slot need not be defined, but it must be initialized to an object of class "formula"

>> If I call new without any named arguments, it works fine
>> > new("a")
>> An object of class "a"
>> Slot "b":
>> list()
>>
>> Slot "c":
>> NULL
No, it does not "work fine"; it has created an *invalid* object, since, for efficiency reasons,
the internal equivalent of validObject() is not called in all cases of object creation {and that is good: basic object creation should be fast}:

  > (aa <- new("a"))
  An object of class "a"
  Slot "b":
  list()

  Slot "c":
  NULL   > validObject(aa)## gives an error as it should   Error in validObject(aa) : invalid class "a" object: invalid object for slot "c" in class "a": got class "NULL", should be or extend class "formula"

>> If I call new with only a formula, it works fine.
>> > new("a",c=formula(x~y))
>> An object of class "a"
>> Slot "b":
>> list()
>>
>> Slot "c":
>> x ~ y

yes, since 'c' now *is* a formula, and BTW, even the simpler

     new("a", c = x~y)

is sufficient {recurring topic of yesterday: 'y ~ x' *is* a formula

	       and does not need an as.formula(.) or formula(.)
	       around it !!}

>> How can I get R to do this?
>> >setClass("a",representation(b="list",c="formula"))
>> >new("a",b=list(7))
>> An object of class "a"
>> Slot "b":
>> [[1]]
>> [1] 7

>> Slot "c":
>> NULL
you can't and shouldn't be able to: If slot 'c' is defined to be a formula, it should be a formula and not NULL. So you need to change the class definition.

Apart from Gabor's possibility which I consider a bit unelegant and not ideal here, I'd strongly suggest you make use of the 'prototype' argument when you define the class, e.g. :

  > setClass("a", representation(b = "list", f = "formula"),   + prototype = prototype(b = list(), f = y ~ x))   [1] "a"
  > (aa <- new("a"))
  An object of class "a"
  Slot "b":
  list()

  Slot "f":
  y ~ x

  > validObject(aa)
  [1] TRUE
  >

--
Martin Maechler, ETH Zurich

______________________________________________
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Received on Thu Jan 19 19:31:07 2006

This archive was generated by hypermail 2.1.8 : Thu 19 Jan 2006 - 22:05:06 EST