Skip to content

setAs vs setIs

4 messages · Charilaos Skiadas, Christophe Genolini, Martin Maechler

#
Hi the list

I am fighting with the twins setAs and setIs...

Here are some questions and comments (comments to myself but that migth 
be wrong, it is why I am posting them)
1. Very surprising : using setIs define 'is', 'as<-' but not 'as' ???
2. Using setAs define 'as', 'as<-' but not 'is'...
What surprise me is that as<- can be define by both. I would have thing 
that setis is for 'is', setAs is for 'as' and 'as<-'...
Since it is not the case, is there a possibility to set with only one 
function 'as', 'is' and 'as<-'

Last point, I get a warning using setAs. I did not manage to find the 
name of the variable it want me to use...

### Data
setClass("B",representation(b="numeric"))
setClass("C",representation(c="numeric"))
setClass("D",representation(d="numeric"))
b <- new("B",b=3)
c <- new("C",c=4)
d <- new("D",d=5)

### using setIs
setIs("C","B",
    test=function(object){return(object at c>0)},
    replace=function(from,values){
        from at c <- values at b^3
        return(from)
    }
)
is(c,"B")             #Ok
as(c,"B")             #not ok
as(c,"B") <- b        #ok (!)

### using setAs
setAs("D","B",
    function(from,to){to<-new("B",b=from at d);return(to)},
    replace=function(from,values){
        from at d<-values at b^2;
        return(from)
    }
)
is(d,"B")             # not ok
as(d,"B")             # ok
as(d,"B")<-b          # ok


Thanks

Christophe
#
On Mar 16, 2008, at 8:12 PM, Christophe Genolini wrote:

            
It seems to me your problem here is simply that you did not define a  
coerce cal in setIs, so it does not know how to turn a C object into  
a B object, which is what you ask it to do here. It knows how to test  
if C object is also a B object, because of the test function you  
provided, and it can do the replacement you ask it in as(c,"B") <-b  
because of the replace command you provided, but the third part is  
missing. Perhaps something like this:
setIs("C","B",
	test=function(object){return(object at c>0)},
	replace=function(from,values){
		from at c <- values at b^3
		return(from)
	},
	coerce=function(from) {
		new("B",b=from at c^(1/3))
	}
)
Haris Skiadas
Department of Mathematics and Computer Science
Hanover College
#
I works, great !
So using your code, we can define 'as','as<-' and 'is' with setIt. Is 
there still any interest using setAs ?

Christophe
#
CG> I works, great !
    CG> So using your code, we can define 'as','as<-' and 'is' with setIt. Is 
    CG> there still any interest using setAs ?

Well, ?setIs  contains 

  >>  This function establishes an inheritance relation
  >>  between two classes, by some means other than having one
  >>  class contain the other.  It should _not_ be used for
  >>  ordinary relationships: either include the second class in
  >>  the 'contains=' argument to 'setClass' if the class is
  >>  contained in the usual way, or consider 'setClassUnion' to
  >>  define a virtual class that is extended by several ordinary
  >>  classes.  A call to 'setIs' makes sense, for example, if one
  >>  class ought to be automatically convertible into a second
  >>  class, but they have different representations, so that the
  >>  conversion must be done by an explicit computation, not just
  >>  be inheriting slots, for example.  In this case, you will
  >>  typically need to provide both a 'coerce=' and 'replace='
  >>  argument to 'setIs'.

which for me has been entailing that you should use
setIs() only rarely but rather

use  setClass(..., contains = ....)
and  setAs(.....)

much more frequently.  That may well depend on the kind of your
classes of course.
For the 'Matrix' package at least, our experience and use
testing has resulted in almost no use of setIs()
but rather hierarchical class definitions, i.e., the above 
setClass( ..., contains=), and many setAs(...).

Martin Maechler, ETH Zurich