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

Martin Maechler maechler at stat.math.ethz.ch
Thu Jan 19 09:20:11 CET 2006


>>>>> "Gabor" == Gabor Grothendieck <ggrothendieck at 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 at 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




More information about the R-help mailing list