I'm trying to create a formal class that does the following:
1) accept objects of arbitrary class as .Data slot
2) provide a set of other slots that are of fixed type (as usual)
The following two approaches came to my mind:
A)
setClass("myclass", representation("ANY", x = "numeric", y
="numeric"))
new("myclass", 1:10) # works
new("myclass", "Test") # works
new("myclass", factor(1:10)) # fails
While I'm able to specify any object that has a formal class as data part
it won't work with factors or other non-formal classes.
B)
Since it is sufficient to use anything that inherits from "vector" and
"factor", I also tried the following one which seems to be cleaner than
using "ANY" directly.
setClassUnion("myunion", representation("vector", "factor")) #
works
setClass("myclass", representation("myunion", x="numeric",
y="numeric"))
new("myclass", 1:10) # fails
Now it isn't possible to assign anything as data part at all, as long as
the union contains any non-formal classes such as "factor". Replacing
"factor" with a formal class will do, of course.
I wonder if there is some way that does the trick because other
approaches aren't very straightforward. The obvious solution would be
a list as .Data part which can store anything but that isn't easy to
maintain. My goal is to have a formal class whose objects (i.e. .Data
part) can either be anything derived from "vector" or a factor (ordered).
I already played around with setIs() for implicit coercion but that doesn't
do anything as long as one of the classes is an S3 class.
Thanks for your help,
Torsten
Inheriting from factors + co.
5 messages · Uwe Ligges, Torsten Steuernagel
Torsten Steuernagel wrote:
I'm trying to create a formal class that does the following:
1) accept objects of arbitrary class as .Data slot
2) provide a set of other slots that are of fixed type (as usual)
The following two approaches came to my mind:
A)
setClass("myclass", representation("ANY", x = "numeric", y
="numeric"))
new("myclass", 1:10) # works
new("myclass", "Test") # works
new("myclass", factor(1:10)) # fails
Why do you think it fails? It works perfectly for me with R-1.8.1 for Windows. You haven't told anything about your R version, I suspect your are using an outdated one. Uwe Ligges
While I'm able to specify any object that has a formal class as data part
it won't work with factors or other non-formal classes.
B)
Since it is sufficient to use anything that inherits from "vector" and
"factor", I also tried the following one which seems to be cleaner than
using "ANY" directly.
setClassUnion("myunion", representation("vector", "factor")) #
works
setClass("myclass", representation("myunion", x="numeric",
y="numeric"))
new("myclass", 1:10) # fails
Now it isn't possible to assign anything as data part at all, as long as
the union contains any non-formal classes such as "factor". Replacing
"factor" with a formal class will do, of course.
I wonder if there is some way that does the trick because other
approaches aren't very straightforward. The obvious solution would be
a list as .Data part which can store anything but that isn't easy to
maintain. My goal is to have a formal class whose objects (i.e. .Data
part) can either be anything derived from "vector" or a factor (ordered).
I already played around with setIs() for implicit coercion but that doesn't
do anything as long as one of the classes is an S3 class.
Thanks for your help,
Torsten
______________________________________________ R-help at stat.math.ethz.ch mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
On 24 Feb 2004 at 21:38, Uwe Ligges wrote:
setClass("myclass", representation("ANY", x = "numeric", y
="numeric"))
new("myclass", 1:10) # works
new("myclass", "Test") # works
new("myclass", factor(1:10)) # fails
Why do you think it fails?
I was typing faster than thinking. It doesn't actually fail but what I get is
a numeric vector with a levels attribute. If I specify a factor as .Data
part I expect that the created object IS a factor and
is.factor(new("myclass", factor(1:10))) returns TRUE.
It works perfectly for me with R-1.8.1 for Windows. You haven't told anything about your R version, I suspect your are using an outdated one.
Sorry, forgot that one. I'm also using R 1.8.1 on Windows. Thanks, Torsten
Torsten Steuernagel wrote:
On 24 Feb 2004 at 21:38, Uwe Ligges wrote:
setClass("myclass", representation("ANY", x = "numeric", y
="numeric"))
new("myclass", 1:10) # works
new("myclass", "Test") # works
new("myclass", factor(1:10)) # fails
Why do you think it fails?
I was typing faster than thinking. It doesn't actually fail but what I get is
a numeric vector with a levels attribute. If I specify a factor as .Data
part I expect that the created object IS a factor and
is.factor(new("myclass", factor(1:10))) returns TRUE.
So you are going to handle/mix the S4 class like/with S3 classes?
Hmm. It can be either of class "myclass" or of class "factor".
I'd define a separate explicit slot for such a class:
setClass("myclass", representation(mainSlot = "ANY",
x = "numeric", y = "numeric"))
John Chambers might want to correct me...
Uwe
It works perfectly for me with R-1.8.1 for Windows. You haven't told anything about your R version, I suspect your are using an outdated one.
Sorry, forgot that one. I'm also using R 1.8.1 on Windows. Thanks, Torsten
______________________________________________ R-help at stat.math.ethz.ch mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
On 25 Feb 2004 at 10:00, Uwe Ligges wrote:
So you are going to handle/mix the S4 class like/with S3 classes? Hmm.
Yes, and there is the problem. With S4 classes, it works. Now I would expect that is(factor(S3object, "ANY") will be FALSE for factor and any other S3 class, but is(S3object, "ANY") always gives TRUE.
It can be either of class "myclass" or of class "factor". I'd define a separate explicit slot for such a class:
It is of class "myclass" but it should inherit from "factor" by the .Data
part if I specify a factor. That's what it does with S4 classes:
my1 <- new("myclass", 1:10)
class(my1) # "myclass"
is.numeric(my1) # TRUE
my2 <- new("myclass", "abc")
class(my2) # "myclass"
is.character(my2) # TRUE
In those cases the object actually is a numeric or a character and thus
can be treated accordingly.
setClass("myclass", representation(mainSlot = "ANY",
x = "numeric", y = "numeric"))
That works, of course. But that's not what I'm looking for. This requires
using the slot explicitly (not impossible, but I'd really prefer to have it in
the .Data part). One main drawback is that R just doesn't accept S3
classes as .Data part:
setClass("myclass", representation("factor"))
It creates a new class (although a warning is issued) and also extends
from "factor" but doesn't create the .Data slot. That's also the reason
why my second approach with setClassUnion() doesn't work as soon as
an S3 class is part of the union. I just don't understand why S3 classes
in explicit slots work perfectly well whereas it seems impossible to have
them in the .Data slot.
Torsten