Hello!
I am developing a composition class, which represents a composition of
mixture of levels, say soil has three components and each component
accounts for 1/3 of the unit. I have tried with S4 class system and I
would appreciate any help here. I was hoping that I would be able to
include instance of my class into a data.frame. However, I encounter
problems.
Simple definition of class could be
setClass(Class="composition",
representation=representation(ratios="matrix"))
n <- 2
k <- 3
x <- new(Class="composition", ratios=matrix(data=rep(x=1/3, times=n*k),
nrow=n, ncol=k))
x
An object of class "composition"
Slot "ratios":
[,1] [,2] [,3]
[1,] 0.3333333 0.3333333 0.3333333
[2,] 0.3333333 0.3333333 0.3333333
tmp <- data.frame(id=1:2)
tmp$comp <- x
Error: object is not subsettable
As I understand this, my problem is that x is of length 1 as the
following works
tmp$comp <- c(x, x)
although I am not able to print tmp now
tmp
Error in unlist(x, recursive, use.names) :
argument not a list
but this is expected as I (probably) need show/print method for this.
How can I put my class into data.frame or how can I make my class behave
as a vector?
Thanks!
Lep pozdrav / With regards,
Gregor Gorjanc
----------------------------------------------------------------------
University of Ljubljana PhD student
Biotechnical Faculty
Zootechnical Department URI: http://www.bfro.uni-lj.si/MR/ggorjan
Groblje 3 mail: gregor.gorjanc <at> bfro.uni-lj.si
SI-1230 Domzale tel: +386 (0)1 72 17 861
Slovenia, Europe fax: +386 (0)1 72 17 888
----------------------------------------------------------------------
"One must learn by doing the thing; for though you think you know it,
you have no certainty until you try." Sophocles ~ 450 B.C.
Hello!
I am developing a composition class, which represents a composition of
mixture of levels, say soil has three components and each component
accounts for 1/3 of the unit. I have tried with S4 class system and I
would appreciate any help here. I was hoping that I would be able to
include instance of my class into a data.frame. However, I encounter
problems.
Simple definition of class could be
setClass(Class="composition",
representation=representation(ratios="matrix"))
n <- 2
k <- 3
x <- new(Class="composition", ratios=matrix(data=rep(x=1/3, times=n*k),
nrow=n, ncol=k))
x
An object of class "composition"
Slot "ratios":
[,1] [,2] [,3]
[1,] 0.3333333 0.3333333 0.3333333
[2,] 0.3333333 0.3333333 0.3333333
tmp <- data.frame(id=1:2)
tmp$comp <- x
Error: object is not subsettable
As I understand this, my problem is that x is of length 1 as the
following works
tmp$comp <- c(x, x)
although I am not able to print tmp now
tmp
Error in unlist(x, recursive, use.names) :
argument not a list
but this is expected as I (probably) need show/print method for this.
How can I put my class into data.frame or how can I make my class behave
as a vector?
Thanks!
Ferdinand Alimadhi
Programmer / Analyst
Harvard University
The Institute for Quantitative Social Science
(617) 496-0187
falimadhi at iq.harvard.edu
www.iq.harvard.edu
I "lose" class here and that is not what I want. Perhaps I should stick
with list instead of data.frame.
Gregor Gorjanc wrote:
Hello!
I am developing a composition class, which represents a composition of
mixture of levels, say soil has three components and each component
accounts for 1/3 of the unit. I have tried with S4 class system and I
would appreciate any help here. I was hoping that I would be able to
include instance of my class into a data.frame. However, I encounter
problems.
Simple definition of class could be
setClass(Class="composition",
representation=representation(ratios="matrix"))
n <- 2
k <- 3
x <- new(Class="composition", ratios=matrix(data=rep(x=1/3, times=n*k),
nrow=n, ncol=k))
x
An object of class "composition"
Slot "ratios":
[,1] [,2] [,3]
[1,] 0.3333333 0.3333333 0.3333333
[2,] 0.3333333 0.3333333 0.3333333
tmp <- data.frame(id=1:2)
tmp$comp <- x
Error: object is not subsettable
As I understand this, my problem is that x is of length 1 as the
following works
tmp$comp <- c(x, x)
although I am not able to print tmp now
tmp
Error in unlist(x, recursive, use.names) :
argument not a list
but this is expected as I (probably) need show/print method for this.
How can I put my class into data.frame or how can I make my class behave
as a vector?
Thanks!
Lep pozdrav / With regards,
Gregor Gorjanc
----------------------------------------------------------------------
University of Ljubljana PhD student
Biotechnical Faculty
Zootechnical Department URI: http://www.bfro.uni-lj.si/MR/ggorjan
Groblje 3 mail: gregor.gorjanc <at> bfro.uni-lj.si
SI-1230 Domzale tel: +386 (0)1 72 17 861
Slovenia, Europe fax: +386 (0)1 72 17 888
----------------------------------------------------------------------
"One must learn by doing the thing; for though you think you know it,
you have no certainty until you try." Sophocles ~ 450 B.C.
"Gregor" == Gregor Gorjanc <gregor.gorjanc at bfro.uni-lj.si>
on Sat, 04 Nov 2006 02:09:13 +0100 writes:
Gregor> Ferdinand Alimadhi wrote:
>> tmp$comp <- x at ratios ?!
Gregor> I "lose" class here and that is not what I
Gregor> want. Perhaps I should stick with list instead of
Gregor> data.frame.
Yes, I probably would, at least for the time being.
OTOH, it's interesting that some methods to "stick some S4
objects into a data frame do work fine , at least for the
following case (R-script below) -- and I wonder if we (R developers)
shouldn't think about more explicitly supporting this,
e.g., by stating something like
>> If an S4 object simply *contains* an atomic class that can be
>> used as data.frame column, then that S4 object can also be used
>> as data.frame column
and trying to fix all cases where the above is not fulfilled.
setClass("Real", contains="numeric")
(r <- new("Real", pi * 1:3))
try( dd <- data.frame(x = 1:3, R = r) ) ## fails
## Error in as.data.frame.default(x[[i]], optional = TRUE) :
## cannot coerce class "Real" into a data.frame
dd <- data.frame(x = 1:3)
dd[,"R"] <- r ## works fine .. didn't I say just yesterday how much
## I recommend [, <name>] indexing for data frames ?
dd
str(dd)
dd[1:2,]
## but
str(dd[1:2,]) # has lost the class -- of course since r[1:2] loses it
## -> you need to define a correct subset method for your class
## e.g.,
setMethod("[", signature(x = "Real", i = "ANY"),
function(x, i,j,drop, ...) new("Real", callNextMethod()))
r[1:2] # now correct
str(dd[1:2,]) # correct too
Martin Maechler, ETH Zurich
>> Gregor Gorjanc wrote:
>>
>>> Hello!
>>>
>>> I am developing a composition class, which represents a
>>> composition of mixture of levels, say soil has three
>>> components and each component accounts for 1/3 of the
>>> unit. I have tried with S4 class system and I would
>>> appreciate any help here. I was hoping that I would be
>>> able to include instance of my class into a
>>> data.frame. However, I encounter problems.
>>>
>>> Simple definition of class could be
>>>
>>> setClass(Class="composition",
>>> representation=representation(ratios="matrix"))
>>>
>>> n <- 2 k <- 3
>>>
>>> x <- new(Class="composition",
>>> ratios=matrix(data=rep(x=1/3, times=n*k), nrow=n,
>>> ncol=k))
>>>
>>> x An object of class "composition" Slot "ratios": [,1]
>>> [,2] [,3] [1,] 0.3333333 0.3333333 0.3333333 [2,]
>>> 0.3333333 0.3333333 0.3333333
>>>
>>> tmp <- data.frame(id=1:2) tmp$comp <- x Error: object is
>>> not subsettable
>>>
>>> As I understand this, my problem is that x is of length
>>> 1 as the following works
>>>
>>> tmp$comp <- c(x, x)
>>>
>>> although I am not able to print tmp now
>>>
>>> tmp Error in unlist(x, recursive, use.names) : argument
>>> not a list
>>>
>>> but this is expected as I (probably) need show/print
>>> method for this. How can I put my class into data.frame
>>> or how can I make my class behave as a vector?
>>>
>>> Thanks!
Gregor> -- Lep pozdrav / With regards, Gregor Gorjanc
Gregor> ----------------------------------------------------------------------
Gregor> University of Ljubljana PhD student Biotechnical
Gregor> Faculty Zootechnical Department URI:
Gregor> http://www.bfro.uni-lj.si/MR/ggorjan Groblje 3 mail:
Gregor> gregor.gorjanc <at> bfro.uni-lj.si
Gregor> SI-1230 Domzale tel: +386 (0)1 72 17 861 Slovenia,
Gregor> Europe fax: +386 (0)1 72 17 888
"Gregor" == Gregor Gorjanc <gregor.gorjanc at bfro.uni-lj.si>
on Sat, 04 Nov 2006 02:09:13 +0100 writes:
Gregor> Ferdinand Alimadhi wrote:
>> tmp$comp <- x at ratios ?!
Gregor> I "lose" class here and that is not what I
Gregor> want. Perhaps I should stick with list instead of
Gregor> data.frame.
Yes, I probably would, at least for the time being.
OK. Why do you say "at least for the time being"? Are there any plans to
generalize putting S4 classes that are not atomic into data.frame?
OTOH, it's interesting that some methods to "stick some S4
objects into a data frame do work fine , at least for the
following case (R-script below) -- and I wonder if we (R developers)
shouldn't think about more explicitly supporting this,
e.g., by stating something like
>> If an S4 object simply *contains* an atomic class that can be
>> used as data.frame column, then that S4 object can also be used
>> as data.frame column
OTOH, it's interesting that some methods to "stick some S4
objects into a data frame do work fine , at least for the
following case (R-script below) -- and I wonder if we (R developers)
shouldn't think about more explicitly supporting this,
e.g., by stating something like
>> If an S4 object simply *contains* an atomic class that can be
>> used as data.frame column, then that S4 object can also be used
>> as data.frame column
and trying to fix all cases where the above is not fulfilled.
There are also many cases where using a list as a data.frame column
will cause errors, depending on the contents of the list.
Hadley
Designing a "better data frame" is something many people have likely
thought about; I certainly have.
But data frames are so widely used and so central to models and other
software that a major change needs to be done by the user community, or
at least with maximum feedback, IMO.
Also, my prior feeling would be that it's better to think of an S4 class
to play the role of data.frame, rather than tinkering with the S3 class
to allow S4 columns. Having formal classes (particularly using class
unions to abstract notions about variables in the data frame) lets one
create a more precise and reliable definition.
It's true, though, that one then has to work out the details of
interfacing the S4 data frame class to current software that works with
the S3 data.frame class. AFAICS that is not too hard, but of course the
details would be important.
I've played around with some of these ideas, more as educational aids in
discussing classes and methods than as a serious proposal. Last time I
looked, the writeup was not at a level I would feel happy circulating
:-} But perhaps a group of interested people could exchange some ideas.
As far as I see this (at the risk of uterly simplifying the issue) new
data.frame (perhaps dataFrame) could just be a list? of classes that
have the same length i.e. length() should have the same value.
Gregor