Ste*_*fan 6 scope namespaces r
考虑以下R代码:
local({
lm <- function(x) x^2
lm(10)
})
Run Code Online (Sandbox Code Playgroud)
这会暂时覆盖该lm功能,但一旦local执行,它将"恢复正常".我想知道为什么同样的方法似乎在下一个简单的例子中不起作用:
require(car)
model <- lm(len ~ dose, data=ToothGrowth)
local({
vcov <- function(x) hccm(x) #robust var-cov matrix
confint(model) # confint will call vcov, but not the above one.
})
Run Code Online (Sandbox Code Playgroud)
该confint函数使用该vcov函数来获得系数的标准误差,并且想法是通过暂时覆盖使用鲁棒的var-cov矩阵vcov,而不用"手动"或改变函数.
vcov和confint都是通用函数,我不知道这是不是它按预期工作的原因.这不是我感兴趣的具体例子; 而是概念课.这是命名空间还是范围"问题"?
我们展示如何使用代理对象来执行此操作(请参阅本文档的代理部分),首先使用proto 包,然后不使用:
1)原型。由于confint.lm正在调用,vcov我们需要确保(a)我们的新替代品vcov位于修订版的confint.lm环境中,并且(b)修订版confint.lm仍然可以访问其原始对象。(例如,confint.lm调用 stats 中的隐藏函数format.perc,因此如果我们没有安排第二点为 true,则无法访问隐藏函数。)
为了执行上述操作,我们创建一个新环境,除了它有一个新环境(代理环境confint.lm)之外,它是相同的,其中包含我们的替换环境,而其父环境又是原始环境。下面,代理环境被实现为原始对象,其中需要了解的关键项目是:(a) 原始对象是环境,以及 (b) 以所示方式将函数放置在原始对象中,将其环境更改为该原始对象。另外,为了避免 S3 调度出现任何问题,我们直接调用该方法。vcovconfint.lmconfintconfint.lmconfint.lm
尽管hccm这里似乎没有任何不同的结果,但我们可以通过注意以下输出来验证它是否已运行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)
Run Code Online (Sandbox Code Playgroud)
有关另一个示例,请参阅此处的示例 2 。
2)环境。没有 proto 的代码有点繁重(实际上它大约使代码大小增加了一倍),但这里是:
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)))
Run Code Online (Sandbox Code Playgroud)
编辑:清晰度的各种改进