[Rd] as(object,"list") as(object,"matrix") differences?
Wolski
wolski at molgen.mpg.de
Thu Sep 9 15:57:36 CEST 2004
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
More information about the R-devel
mailing list