passing an extra argument to an S3 generic
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