[R] passing an extra argument to an S3 generic

ilai keren at math.montana.edu
Tue Feb 14 17:32:47 CET 2012


Hi Michael,
Try the attached. The only change to your script is in the first line
where I explicitly tell hatvalues to use methods (the "infmlm" class
stays). I also commented out all your TESTME at the end.

source('mlminfl-testHELP.R')

Now this should have worked for you too. Let me know. Sorry about that
"just remove the class". Had somewhat of a brain glitch when writing
the E-mail and wasn't clear.

Cheers






On Tue, Feb 14, 2012 at 8:05 AM, Michael Friendly <friendly at yorku.ca> wrote:
> On 2/11/2012 12:00 PM, ilai wrote:
>>
>> You are setting a new class ("inflmlm") at the end of mlm.influence.
>> Remove that second to last line and enjoy your new S3 method.
>
>
> Thanks for the suggestion, but it doesn't help -- I still get the same
> behavior whether mlm.influence returns a classed object or not.
> As well, I am defining print.inflmlm() and as.data.frame.inflmlm() methods
> for these objects, so I do need mlm.influence to return a classed object.
>
> My hatvalues.mlm is designed to be similar in structure to
> stats::hatvalues.lm where the S3 generic is defined.
>
>
> hatvalues.mlm <- function(model, m=1, infl, ...)
> {
>   if (missing(infl)) {
>     infl <- mlm.influence(model, m=m, do.coef=FALSE);
>   }
>    hat <- infl$H
>    m <- infl$m
>    names(hat) <- if(m==1) infl$subsets else apply(infl$subsets,1, paste,
> collapse=',')
>    hat
> }
>
>> hatvalues
> function (model, ...)
> UseMethod("hatvalues")
> <bytecode: 0x0326fd30>
> <environment: namespace:stats>
>> hatvalues.lm
>
> function (model, infl = lm.influence(model, do.coef = FALSE),
>    ...)
> {
>    hat <- infl$hat
>    names(hat) <- names(infl$wt.res)
>    hat
> }
> <bytecode: 0x0326de6c>
> <environment: namespace:stats>
>
> The idea is that the infl= argument specifies a call to the computational
> function, mlm.influence() in my case, just as lm.influence() does in the
> stats package.
>
> The logic of UseMethod is that it should dispatch on the class of the
> *first* argument to the function, which in my test case is c("mlm", "lm")
>
>
>> Rohwer.mod <- lm(cbind(SAT, PPVT, Raven) ~ n+s+ns+na+ss, data=Rohwer2)
>> class(Rohwer.mod)
> [1] "mlm" "lm"
>
>> trace(hatvalues)
>> hatvalues(Rohwer.mod, m=2)
> trace: hatvalues(Rohwer.mod, m = 2)
>
> Error in UseMethod("hatvalues") :
>  no applicable method for 'hatvalues' applied to an object of class
> "c('double', 'numeric')"
>> hatvalues(Rohwer.mod)
> trace: hatvalues(Rohwer.mod)
>
>         1          2          3          4          5          6     7
>    8
> 0.16700926 0.21845327 0.14173469 0.07314341 0.56821462 0.15432157 0.04530969
> 0.17661104
> ...
>
>
> I'm still stumped on why with the extra argument m=2, R sees this
> as an object of class c('double', 'numeric').  As well, I can't see
> any way to debug this.
>
>
>
>> I'm not sure, but I think it is just the new class "inflmlm" applied
>> to inf in the formals of hatvalues.mlm confused the dispatch
>> mechanism. You would think the error message will call the offending
>> class not "numeric" double" but that's above my pay grade...
>>
>> You could probably put back the inflmlm class assignment with an
>> explicit call to UseMethod in hatvalues.mlm ?
>>
>> Cheers
>>
>> On Fri, Feb 10, 2012 at 2:35 PM, Michael Friendly<friendly at yorku.ca>
>>  wrote:
>>>
>>> On 2/10/2012 4:09 PM, Henrik Bengtsson wrote:
>>>>
>>>>
>>>> So people may prefer to do the following:
>>>>
>>>> hatvalues.mlm<- function(model, m=1, infl, ...)
>>>> {
>>>>    if (missing(infl)) {
>>>>      infl<- mlm.influence(model, m=m, do.coef=FALSE);
>>>>    }
>>>>
>>>>    hat<- infl$H
>>>>    m<- infl$m
>>>>    names(hat)<- if(m==1) infl$subsets else apply(infl$subsets,1,
>>>> paste, collapse=',')
>>>>    hat
>>>> }
>>>
>>>
>>> Thanks;  I tried exactly that, but I still can't pass m=2 to the mlm
>>> method
>>> through the generic
>>>
>>>> hatvalues(Rohwer.mod)
>>>
>>>         1          2          3          4          5          6
>>>  7
>>>          8
>>> 0.16700926 0.21845327 0.14173469 0.07314341 0.56821462 0.15432157
>>> 0.04530969
>>> 0.17661104
>>>         9         10         11         12         13         14
>>> 15
>>>         16
>>> 0.05131298 0.45161152 0.14542776 0.17050399 0.10374592 0.12649927
>>> 0.33246744
>>> 0.33183461
>>>        17         18         19         20         21         22
>>> 23
>>>         24
>>> 0.17320579 0.26353864 0.29835817 0.07880597 0.14023750 0.19380286
>>> 0.04455330
>>> 0.20641708
>>>        25         26         27         28         29         30
>>> 31
>>>         32
>>> 0.15712604 0.15333879 0.36726467 0.11189754 0.30426999 0.08655434
>>> 0.08921878
>>> 0.07320950
>>>
>>>> hatvalues(Rohwer.mod, m=2)
>>>
>>> Error in UseMethod("hatvalues") :
>>>  no applicable method for 'hatvalues' applied to an object of class
>>> "c('double', 'numeric')"
>>>
>>> ## This works:
>>>>
>>>> hatvalues.mlm(Rohwer.mod, m=2)
>>>
>>>   ... output snipped
>>>
>>>> hatvalues
>>>
>>>
>>> function (model, ...)
>>> UseMethod("hatvalues")
>>> <bytecode: 0x021339e4>
>>> <environment: namespace:stats>
>>>
>>>>
>>>
>>> -Michael
>>>
>>>
>>> --
>>> Michael Friendly     Email: friendly AT yorku DOT ca
>>> Professor, Psychology Dept.
>>> York University      Voice: 416 736-5115 x66249 Fax: 416 736-5814
>>> 4700 Keele Street    Web:   http://www.datavis.ca
>>> Toronto, ONT  M3J 1P3 CANADA
>>>
>>>
>>
>
>
> --
> Michael Friendly     Email: friendly AT yorku DOT ca
> Professor, Psychology Dept.
> York University      Voice: 416 736-5115 x66249 Fax: 416 736-5814
> 4700 Keele Street    Web:   http://www.datavis.ca
> Toronto, ONT  M3J 1P3 CANADA
>


More information about the R-help mailing list