2012-02-22 38 views
6

xem xét mã R sau:R: tạm thời trọng chức năng và phạm vi/namespace

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

này tạm thời đè lm chức năng, nhưng một khi local đã được thực hiện nó sẽ "trở lại bình thường". Tôi tự hỏi tại sao các phương pháp tương tự dường như không làm việc trong ví dụ này đơn giản tiếp theo:

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

Chức năng confint sử dụng vcov chức năng để có được sai số chuẩn cho các hệ số, và ý tưởng là sử dụng một var- mạnh mẽ ma trận cov bằng cách ghi đè tạm thời vcov, mà không làm việc "thủ công" hoặc thay đổi chức năng.

Cả vcov và confint đều là các hàm chung, tôi không biết đây có phải là lý do không hoạt động như dự định hay không. Nó không phải là ví dụ cụ thể mà tôi quan tâm như vậy; thay vì bài học khái niệm. Đây có phải là không gian tên hoặc phạm vi "vấn đề" không?

Trả lời

4

Chúng tôi thấy làm thế nào để làm điều này sử dụng đối tượng proxy (Proxy thấy phần của document này), đầu tiên sử dụng proto package và sau đó không:

1) proto. Vì confint.lm đang gọi vcov, chúng tôi cần đảm bảo rằng (a) thay thế mới của chúng tôi cho vcov là trong môi trường sửa đổi confint.lm và (b) sửa đổi confint.lm vẫn có thể truy cập các đối tượng từ bản gốc. (Ví dụ: confint.lm gọi hàm ẩn format.perc trong số liệu thống kê, vì vậy nếu chúng tôi không sắp xếp điểm thứ hai là đúng thì không thể truy cập chức năng ẩn.)

Để thực hiện ở trên, chúng tôi thực hiện confint.lm mới là ngoại trừ nó có một môi trường mới (môi trường proxy ) có chứa thay thế của chúng tôi vcov và có cha mẹ lần lượt là môi trường gốc confint.lm. Dưới đây, môi trường proxy được thực hiện như một đối tượng proto nơi các mục quan trọng cần biết ở đây là: (a) đối tượng proto là môi trường và (b) đặt một hàm trong đối tượng proto theo cách hiển thị thay đổi môi trường của nó. . Ngoài ra, để tránh bất kỳ vấn đề nào từ việc gửi S3 của confint đến confint.lm, chúng tôi gọi trực tiếp phương thức confint.lm.

Mặc dù hccm dường như không có bất kỳ kết quả khác nhau ở đây chúng ta có thể xác minh rằng nó được điều hành bởi nhận thấy đầu ra của 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) 

Ví dụ khác, xem ví dụ 2 here.

2) môi trường.Mã này là lựa chọn hợp lý hơn một chút mà không proto (trên thực tế nó làm tăng gấp đôi kích thước code) nhưng ở đây nó là:

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: nhiều cải tiến rõ nét

+0

Thats rực rỡ, tôi không quen thuộc với gói proto nhưng nó có vẻ khá hữu ích. Tôi tiếp tục đọc các họa tiết, và nó là một đọc tốt. Cảm ơn bạn đã nỗ lực! – Stefan

2

Điều này là do các chức năng confintvcov đều nằm trong "số liệu thống kê" không gian tên. Các confint() bạn gọi ở đây có hiệu quả được thống kê :: vcov, khá nhiều bởi vì đó là những gì không gian tên cho - bạn được phép viết các phiên bản của riêng bạn nhưng không gây tổn hại đến hành vi mong đợi khác.

Trong ví dụ đầu tiên, bạn vẫn có thể gọi một cách an toàn các chức năng khác dựa trên số liệu thống kê :: lm và điều đó sẽ không bị khó chịu bởi sửa đổi cục bộ của bạn.

+0

OK, vì vậy trừ lớp (mô hình) <- c ("lmr", lớp (mô hình)); vcov.lmr <- chức năng (x) hccm (x); confint (model); không có thủ thuật nào để trỏ đến chức năng mong muốn? (xin lỗi vì bình luận nội tuyến) – Stefan

Các vấn đề liên quan