We show how to do this using proxy objects (see Proxies section of this document), first using the proto package and then without:
1) proto. Since confint.lm
is calling vcov
we need to ensure that (a) our new replacement for vcov
is in the revised confint.lm
's environment and (b) the revised confint.lm
can still access the objects from its original. (For example, confint.lm
calls the hidden function format.perc
in stats so if we did not arrange for the second point to be true that hidden function could not be accessed.)
To perform the above we make a new confint.lm
which is the same except it has a new environment (the proxy environment) which contains our replacment vcov
and whose parent in turn is the original confint.lm
environment. Below, the proxy environment is implemented as a proto object where the key items to know here are: (a) proto objects are environments and (b) placing a function in a proto object in the way shown changes its environment to be that proto object. Also to avoid any problems from S3 dispatch of confint
to confint.lm
we call the confint.lm
method directly.
Although the hccm
does not seem to have any different result here we can verify that it was run by noticing the output of the trace
:
library(car)
library(proto)
trace(hccm)
model <- lm(len ~ dose, data=ToothGrowth)
proto(environment(stats:::confint.lm), # set parent
vcov = function(x) hccm(x), #robust var-cov matrix
confint.lm = stats:::confint.lm)[["confint.lm"]](model)
For another example, see example 2 here.
2) environments. The code is a bit more onerous without proto (in fact it roughly doubles the code size) but here it is:
library(car)
trace(hccm)
model <- lm(len ~ dose, data=ToothGrowth)
local({
vcov <- function(x) hccm(x) #robust var-cov matrix
confint.lm <- stats:::confint.lm
environment(confint.lm) <- environment()
confint.lm(model) # confint will call vcov, but not the above one.
}, envir = new.env(parent = environment(stats:::confint.lm)))
EDIT: various improvements in clarity