Renaud Gaujoux
2009-Aug-05 09:10 UTC
[R] S4 method dispatch: coercion of arguments with setAs defined
Hi list, I've got a class B that contains a slot obj of class A. I'd like to be able to call all the methods of class A directly on objects of class B as if I had called the method on slot obj. This without overloading all methods of class A to work on class B. I don't define B as an extension of A, because I want class B to also work with objects of classes that inherit from class A and that I don't know the names. So I tried to dispatch the methods of class A to slot obj using function setAs as follows: setClass('A', representation(number='numeric')) setGeneric('getNumber', function(object) standardGeneric('getNumber')) setMethod('getNumber', 'A', function(object) object at number) setClass('B', representation(obj='A', extra='list')) setAs('B', 'A', def= function(from) from at obj ) objB <- new('B', obj=new('A', number=10)) getNumber(objB) But get the error: Error in function (classes, fdef, mtable) : unable to find an inherited method for function "getNumber", for signature "B" I thought the dispatch procedure in S4 would try to find a way to coerce objects of class 'B' into the closest class usable with the given method (in that case into an object of class 'A'). I expected it to internally do: getNumber(as(objB, 'A')) Am I thinking wrong or do I need to do another thing to make it work? Thanks
Martin Morgan
2009-Aug-06 12:42 UTC
[R] S4 method dispatch: coercion of arguments with setAs defined
Hi Renaud -- Renaud Gaujoux <renaud at mancala.cbio.uct.ac.za> writes:> Hi list, > > I've got a class B that contains a slot obj of class A. I'd like to be > able to call all the methods of class A directly on objects of class B > as if I had called the method on slot obj. This without overloading > all methods of class A to work on class B. > I don't define B as an extension of A, because I want class B to also > work with objects of classes that inherit from class A and that I > don't know the names. > > So I tried to dispatch the methods of class A to slot obj using > function setAs as follows: > > setClass('A', representation(number='numeric')) > setGeneric('getNumber', function(object) standardGeneric('getNumber')) > setMethod('getNumber', 'A', function(object) object at number) > > setClass('B', representation(obj='A', extra='list')) > setAs('B', 'A', def= function(from) from at obj ) > > objB <- new('B', obj=new('A', number=10)) > getNumber(objB) > > But get the error: > > Error in function (classes, fdef, mtable) : > unable to find an inherited method for function "getNumber", for > signature "B" > > I thought the dispatch procedure in S4 would try to find a way to > coerce objects of class 'B' into the closest class usable with the > given method (in that case into an object of class 'A'). I expected it > to internally do: > > getNumber(as(objB, 'A')) > > Am I thinking wrong or do I need to do another thing to make it work?setAs defines a method for coercing from one object to another, without defining an inheritance. You can use 'setIs' setClass('A', representation(number='numeric')) setGeneric('number', function(object) standardGeneric('number')) setMethod('number', 'A', function(object) object at number) setClass('B', representation(obj='A', extra='list')) setIs("B", "A", test=function(object) TRUE, coerce=function(object) slot(object, "obj"), replace=function(object, value) { slot(object, "obj") <- value object }) to define an inheritance relationship:> objB <- new('B', obj=new('A', number=10)) > number(objB)[1] 10 This is not something I usually do (are all A methods appropriate for B's slot 'obj'?) and at least in my hands there seem to be some rough edges setGeneric("number<-", function(object, value) standardGeneric("number<-")) setReplaceMethod("number", "A", function(object, value) { slot(object, "number") <- value object })> number(objB) <- 20 > is(objB, "B")[1] FALSE Martin> Thanks > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.-- Martin Morgan Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793