[Rd] as(object,"list") as(object,"matrix") differences?
John Chambers
jmc at research.bell-labs.com
Thu Sep 9 17:41:33 CEST 2004
If the only issue is whether as(x, "list") preserves the names
attribute, this is certainly an easy change to implement, if the R
community decides that's the better solution.
With the release of 2.0 only a few weeks away, there's not much chance
of resolving the question for that version. Although the change is
simple, there may be some implications that will not arise until a good
deal of testing is done. So a more likely target is to resolve the
question for version 2.1.
By the way, one argument in your favor is that S-Plus retains the names
in as(x, "list") (but not in as(x, "numeric"), even if x had names in
that case). So a closer approximation to compatibility with the
behavior of S-Plus would retain names. (I'm not quite convinced this is
what the discussion in the green book would imply, but it's what
happens!)
If others have opinions, it would be good to hear them.
Meanwhile, a candidate for the simplest workaround: Have new classes
extend the class "listNamed" defined below, rather than "list" directly,
and as(x, "list") should retain names, I think.
---------------------------------------------
setClass("listNamed", "list")
setAs("listNamed", "list", function(from) {
if(strict) class(from) <- "list"
from
})
---------------------------------------------
Although not necessary for correctness, it's probably good to add the
following method for "show". (With the default method, names are not
printed, even though they are there--users are likely to be confused.)
---------------------------------------------
setMethod("show", "listNamed",
function(object) {
cat("An object of class ", class(object), "\n", sep="")
show(as(object, "list"))
})
---------------------------------------------
(By the way, the workaround depends on the bug fix to setAs committed
recently to r-devel, so if you try this you should use the latest
version.)
Wolski wrote:
>
> Hi!
>
> First of all thanks a lot to John Chambers. I think S4 makes some tasks really easier.
> This mail tries to summarise the mail exchange concerning contains="list" in S4.
> I do not know all the R "internals" so instead of talking I try to use and to play around with S4. People like I learn by example. But I would like to use all features of S4. I dont say that anything is good or bad. I just ask on which parts and features can I rely on? About which parts of methods I be sure that there are not going to change in the nearest future? And making a search on several hundred packages in the lib directory, and finding that setAs is used only in the file methods/R-ex/as.R its not reassuring.
>
> I like to use S4 and i like to use lists.
>
> I like to use lists like maps or multimaps with key value pairs. I believe that I am not the only one who uses lists to store different types of objects and to access them using mylist[["key"]]. So in my opinion list had have and should have names. (I am not a phyton user yet but I know that phyton has also a data structure to store key value pairs and it is a quite important one.)
>
> R provides a lot of powerfull functions which are operating on "lists" like sapply, lapply, mapply, [[]] [] etc....
> And all the list methods lapply, [], etc preserve the list names. So if they "return a type" are "list" then list have names. But as I said i understand examples and so probably nothing new to what you have already said. And I think that my examples will show that even in S4 except for the function as(object,"list") old style "list" have names attribute.
>
> If I write a new class, and this class is a mainly a container class, I would like rather inherit from a list (contains="list") with names rather then include it (include means representation(list="list") like e.g. class Biobase:container does). I like to inherit because I would not like to wrap every possible list function which is available for lists. Its just because I even not know all of them. And if I have inheritance as a tool this is not neceassary. Any function working on lists can be used on a class inheriting from list.
>
> The following code summarizes, by example, how names are treated when "list" is "contained" by a class.
> I show 3 versions how to inherit from "list" showing the problems with the 'naive' inheritance.
> And I think that the example shows also that in S4 the old styl "list" class are with "names"!
> There are also some inconsistencies, bugs which I am going to show on occasion?
>
> #NAIVE inheritance from list.
> #define cass
> setClass("ListWithNames","list")
> setClass("Mlist"
> ,representation(info="character") #uniq names have to be unique?
> ,contains="ListWithNames"
> ,prototype(uniq=FALSE)
> )
>
> tmp <- as.list(1:4)
> names(tmp) <- letters[1:4]
> mylist<-new("Mlist" , tmp , info="numeric" )
>
> #Example of manipulating the list part of the object.
> as(mylist,"list")<-lapply(mylist,"+",3)
> as(mylist,"list") <- mylist[2:4]
>
> as(mylist,"list") <- as(mylist,"ListWithNames")[2:4]
>
> #what does not work is assigning shorter lists without names. Seems like a bug. Or is there an explanation.
> as(mylist,"list")<-as.list(1:5)
> as(mylist,"list")<-as.list(1:4)
>
> class(Mlist)
> #I have not defined in class Representation
> # a names attribute but there is the name attribute anyway inherited by from list.
>
> mylist at names
>
> # But this does not work. Of course.
> mylist at names <- letters[5:9]
>
> #Slots are implemented using attributes?
>
> attributes(mylist at .Data)$names #this is what is expected.
> attributes(mylist)$names #But whats this?
> attributes(mylist)$names <- letters[2:11]
> attributes(mylist at .Data)$names #are they the same? synchronized?
>
> # So if @names are there why not make it official ?
> # I make it official with a new class definition.
> # REFINED version of "list" inheritance.
>
> setClass("MlistN"
> ,representation(info="character",names="character") #uniq names have to be unique?
> ,contains="ListWithNames"
> )
>
> mylistNam<-new("MlistN" , tmp , info="numeric")
> mylistNam at names<-letters[4:7]
> mylistNam["d"]
> mylistNam[["d"]]
>
> as(mylistNam,"list")<-tmp[1:3]
>
> as(mylistNam,"list")<-as.list(1:4)
> as(mylistNam,"list")<-as.list(1:3) #<- the same error as before.
> as(mylistNam,"list")<-list(a=1,b=2,c=3,d=4)
>
> #to get it more complicated
> as(mylistNam,"ListWithNames") # Is without names??
>
> ## MORE REFINED version of list inheritance.
> setClass("MlistN"
> ,representation(info="character",names="character") #uniq names have to be unique?
> ,contains="list"
> )
>
> # I dont like the as(o,"list")
> # My Solution. Now it does not mether wheter the list has or has not names is longer or shorter.
>
> setAs("MlistN","list"
> ,def=function(from){
> print("test")
> to<-from at .Data
> names(to)<-from at names
> to
> }
> ,replace=function(from,value)
> {
> from at .Data<-value
> from at names<-names(value)
> from
> }
> )
>
> bublegum <- list(b=1, u=3, b=4, l=4, e=2, g=1, u=4, m=2)
> mylistNam <- bublegum
> bubl<-bublegum[1:4]
> names(bubl)<-NULL
> as(mylistNam,"list") <- bubl
>
> I have just one question: Can I rely that this is not going to change in further versions of R?
>
> /E
--
John M. Chambers jmc at bell-labs.com
Bell Labs, Lucent Technologies office: (908)582-2681
700 Mountain Avenue, Room 2C-282 fax: (908)582-3340
Murray Hill, NJ 07974 web: http://www.cs.bell-labs.com/~jmc
More information about the R-devel
mailing list