4

I want to override the default predict.lm function due to a bug:

library(datasets)
# Just a regular linear regression
fit <- lm(mpg~disp+hp+wt+drat, data=mtcars)
termplot(fit, terms=2, se=T)

Gives this error:

Error in predict.lm(model, type = "terms", se.fit = se, terms = terms) : 
  subscript out of bounds

I know where the bug is and I've sent an email that awaits approval by the core mailing list but in the meantime I would like to test my own predict.lm function to fix this. I've understood that I need to redefine the S3 function for predict but when running this code:

setMethod("predict", "lm", predict.lm2)
getMethod("predict", "lm")

The getMethod returns my new function as expected but the termplot still runs the old function. The methods("predict") shows also that the old predict.lm is still there and I think it might be the call-order or something that I need to adjust. Anyone familiar with how to do this?

Argalatyr
  • 4,639
  • 3
  • 36
  • 62
Max Gordon
  • 5,367
  • 2
  • 44
  • 70
  • You could try setting the class of your model. `class(fit) <- c("lm2","lm")` – James Feb 14 '12 at 10:44
  • It complains then about lacking a definition for the lm2 class – Max Gordon Feb 14 '12 at 10:55
  • You're not working with S3 but with S4 when you use setMethod. That can give trouble. – Joris Meys Feb 14 '12 at 12:42
  • @JorisMeys: hmm... it works now but should I be using setOldClass() instead of setClass() - what advantage does that give me? – Max Gordon Feb 14 '12 at 13:20
  • I'm just saying that because predict uses S3 inheritance (it is not an S4 generic), which means that any S3 inheritance has priority over S4 inheritance. Meaning that if you have an S4 method predict for lm and an S3 method predict.lm, R will always use the latter one. See the section _Methods for S3 Generic Functions_ in `?Methods`. – Joris Meys Feb 14 '12 at 14:12

1 Answers1

4

@James's comment suggests to define your own lm2 class, that extends lm, and to implement predict.lm2.

class(fit) <- c("lm2", class(fit))
predict.lm2 <- function(...) { 
  # The function with your bugfix
  cat("Inside predict.lm2\n")
  predict.lm(...) 
}
termplot(fit, terms=2, se=T)
Vincent Zoonekynd
  • 31,893
  • 5
  • 69
  • 78
  • Thanks, this almost solves the problem although my bug-fixed predict.lm2 function causes a minor error: could not find function "qr.lm" - I guess this is due to some internal function of the lm class. How do I get access to the internal functions of lm? I've pasted my predict.lm2 function [here on pastebin](http://pastebin.com/FARH1gC0) – Max Gordon Feb 14 '12 at 11:42
  • 2
    Since the function is not exported, you have to explicitly specify the namespace: `stats:::qr.lm`, every time it appears. – Vincent Zoonekynd Feb 14 '12 at 12:07