[R] S4 method dispatch: coercion of arguments with setAs defined

Renaud Gaujoux getoxxx at gmail.com
Thu Aug 6 17:09:27 CEST 2009


Thanks Martin, it's clearer now.

Indeed things get a bit dirty with replace methods. I'm wondering if 
it's a bug, a normal behaviour or if there is nothing to do about it?
I think it's because the replace method of A into B is not called after 
replacing an object's slot. I imagine this would be done in method 
'slot<-', wouldn't it?
See messages with the following code:

setIs("B", "A",
      test=function(object){ message("Test if B is A"); TRUE},
      coerce=function(object){ message("Coerce B into A"); slot(object, 
"obj")},
      replace=function(object, value) {
          message("Replace slot A in B")
          slot(object, "obj") <- value
          object
      })

setGeneric("number<-", function(object, value) standardGeneric("number<-"))
setReplaceMethod("number", "A", function(object, value) {
    message("Replace number in A")
    slot(object, "number") <- value
    object
})

objB <- new('B', obj=new('A', number=10))
number(objB) <- 20

Martin Morgan wrote:
> 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.
>>     
>
>




More information about the R-help mailing list