2012-02-22 28 views
6

考慮下述R代碼:R:暫時重寫功能和範圍/命名空間

local({ 
    lm <- function(x) x^2 
    lm(10) 
}) 

這暫時覆蓋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. 
}) 

confint函數使用vcov函數來獲得標準誤差爲係數,這種想法是使用一個強大的VAR- cov矩陣臨時覆蓋vcov,而不是「手動」或改變功能。

vcov和confint都是通用函數,我不知道這是不是按預期工作的原因。這不是我感興趣的具體例子;而不是概念上的教訓。這是一個命名空間還是範圍「問題」?

回答

4

我們展示瞭如何做到這一點使用代理對象(見本document的代理部分),先用proto package然後無:

1)原。由於confint.lm正在呼叫vcov,因此我們需要確保(a)vcov的新替代版本位於修訂版confint.lm的環境中,並且(b)修訂版confint.lm仍然可以從其原始版本訪問對象。 (例如,confint.lm在統計調用隱藏功能format.perc所以,如果我們沒有第二點安排是真實的,隱藏的功能無法訪問。)

要執行上面我們做一個新confint.lm這是除了它有一個新的環境(代理環境),其中包含我們的替代品vcov,並且其父代又是原始的confint.lm環境。在下面,代理環境被實現爲原始對象,其中這裏要知道的關鍵項目是:(a)原始對象是環境並且(b)以所示的方式將功能放置在原始對象中,從而將其環境改變爲原始對象。同樣爲了避免S3派遣confintconfint.lm的任何問題,我們直接調用confint.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) 

另一個例子,見例2 here

2)環境。該代碼是更加繁重沒有原位(實際上它大致加倍的代碼大小),但在這裏它是:

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))) 

編輯:清晰度的各種改進

+0

這很棒,我不熟悉proto軟件包,但它似乎相當有用。我繼續閱讀小插曲,這是一個很好的閱讀。感謝您付出的努力! – Stefan 2012-02-23 07:45:21

2

這是因爲函數confintvcov都在命名空間「stats」中。你在這裏調用的confint()有效地得到了stats :: vcov,很大程度上是因爲這是命名空間的用途 - 你可以編寫自己的版本,但不會損害其他預期的行爲。

在你的第一個例子中,你仍然可以安全地調用依賴於stats :: lm的其他函數,並且不會因你的本地修改而感到不適。

+0

好了,除了 類(模型)< - c(「lmr」,class(model)); vcov.lmr < - function(x)hccm(x); confint(model); 有沒有技巧指向所需的功能? (對不起,內嵌評論) – Stefan 2012-02-22 09:01:01