2012-04-16 7 views
5

Tôi nhận ra một hành vi lạ hôm nay với mã R của tôi. Tôi đã thử một gói {boot.StepAIC} bao gồm một hàm bootstrap cho kết quả hồi quy từng bước với AIC. Tuy nhiên tôi không nghĩ rằng nền thống kê là ở đây vấn đề (tôi hy vọng như vậy).
Tôi có thể sử dụng chức năng ở cấp cao nhất của R. Đây là mã ví dụ của tôi.chức năng hoạt động (boot.stepAIC) nhưng ném một lỗi bên trong một vấn đề môi trường chức năng khác?

require(MASS) 
require(boot.StepAIC) 

n<-100 
x<-rnorm(n); y<-rnorm(n,sd=2); z<-rnorm(n,sd=3); res<-x+y+z+rnorm(n,sd=0.1) 
dat.test<-as.data.frame(cbind(x,y,z,res)) 
form.1<-as.formula(res~x+y+z) 
boot.stepAIC(lm(form.1, dat.test),dat.test) # should be OK - works at me 

Tuy nhiên, tôi muốn kết hợp với chức năng riêng. Tôi chuyển dữ liệu và công thức đến hàm đó. Nhưng tôi nhận được một lỗi trong vòng boot.stepAIC() nói:

mô hình phù hợp thất bại trong 100 mẫu bootstrap Lỗi trong strsplit (nam.vars, ":"): đối số phi vật

# custom function 
fun.boot.lm.stepAIC<-function(dat,form) { 
    if(!inherits(form, "formula")) stop("No formula given") 
    fit.lm<-lm(formula=form,data=dat) 
    return(boot.stepAIC(object=fit.lm,data=dat)) 
} 
fun.boot.lm.stepAIC(dat=dat.test,form=form.1) 
# results in an error 

Vậy đâu là sai lầm? Tôi cho rằng nó phải có một cái gì đó để làm với môi trường địa phương và toàn cầu, phải không?

+0

Tôi chưa sử dụng 'boot.stepAIC' trước đây nhưng nghi ngờ nó cũng có thể liên quan đến cách thức công thức được chuyển vào hàm (cũng liên quan đến các vấn đề môi trường). Xem http://stackoverflow.com/q/6877534, http://stackoverflow.com/q/7666807 để biết một số ý tưởng. Cụ thể, gọi 'lm' hoặc' boot.stepAIC' qua 'do.call' có thể giúp khi các đối số được đánh giá trước khi được truyền vào. Bạn cũng có thể điều tra gợi ý' as.name' trong các chú thích. Những vấn đề này là khó khăn - may mắn! – Aaron

+0

http://stackoverflow.com/q/8998884/210673 cũng có vẻ là vấn đề tương tự. – Aaron

+0

yep. Tôi đã đọc hết rồi. Tôi cho rằng các vấn đề được kết nối. – Sebastian

Trả lời

4

Sử dụng do.call như trong anova test fails on lme fits created with pasted formula cung cấp câu trả lời.

không có quyền truy cập vào form khi chạy trong một hàm; có thể được tái tạo trong môi trường toàn cầu như thế này; chúng ta thấy rằng lm đang sử dụng form.1 làm công thức và xóa nó làm cho không thành công.

> form.1<-as.formula(res~x+y+z) 
> mm <- lm(form.1, dat.test) 
> mm$call 
lm(formula = form.1, data = dat.test) 
> rm(form.1) 
> boot.stepAIC(mm,dat.test) 
# same error as OP 

Sử dụng do.call không hoạt động. Ở đây tôi cũng sử dụng as.name; nếu không, đối tượng mm sẽ mang theo toàn bộ tập dữ liệu thay vì chỉ tên của nó.

> form.1<-as.formula(res~x+y+z) 
> mm <- do.call("lm", list(form.1, data=as.name("dat.test"))) 
> mm$call 
lm(formula = res ~ x + y + z, data = dat.test) 
> rm(form.1) 
> boot.stepAIC(mm,dat.test) 

Để áp dụng điều này cho vấn đề ban đầu, tôi muốn làm điều này:

fun.boot.lm.stepAIC<-function(dat,form) { 
    if(!inherits(form, "formula")) stop("No formula given") 
    mm <- do.call("lm", list(form, data=as.name(dat))) 
    do.call("boot.stepAIC", list(mm,data=as.name(dat))) 
}  
form.1<-as.formula(res~x+y+z) 
fun.boot.lm.stepAIC(dat="dat.test",form=form1) 

này hoạt động quá nhưng toàn bộ tập dữ liệu được bao gồm trong đối tượng đầu ra cuối cùng, và kết quả cuối cùng để an ủi , cũng.

fun.boot.lm.stepAIC<-function(dat,form) { 
    if(!inherits(form, "formula")) stop("No formula given") 
    mm <- do.call("lm", list(form, data=dat)) 
    boot.stepAIC(mm,data=dat) 
}  
form.1<-as.formula(res~x+y+z) 
fun.boot.lm.stepAIC(dat=dat.test,form=form.1) 
+0

Cảm ơn. Do giải thích toàn diện, tôi thấy quan điểm. Tôi cũng đọc hai bài viết liên quan. Thành thật mà nói, tôi vẫn còn đau đầu với những vấn đề này. "Trường hợp sử dụng" cho hành vi đó là gì? Tôi chuyển hai đối tượng đến hàm đó để nó được thực thi trong ngữ cảnh của hàm gọi. Tôi thấy không có điểm trong R hoặc boot.stepAIC (không biết ai để "đổ lỗi") để chuyển hướng đến môi trường toàn cầu.Vấn đề là làm thế nào tôi có thể chắc chắn trong đó bối cảnh một hàm đang tìm kiếm các đối tượng. Sự hiểu biết của tôi cho đến nay là, luôn sử dụng do.call() chứ không phải là hàm trực tiếp. Bất kỳ chiến lược nào về điều đó? – Sebastian

+0

Tôi đã chơi một chút với điều đó và tôi vẫn cố gắng hiểu ngữ cảnh. Trong ví dụ cuối cùng của bạn, về cơ bản bạn chuyển tên của biến toàn cục (hoặc cha mẹ) và truy cập ra khỏi hàm toàn cục dat.test. Nó là một cuộc gọi bằng cách tham khảo? Nó có thể được rằng các chức năng mô hình đôi khi sử dụng một cuộc gọi bằng chiến lược tham khảo ngay cả khi tôi giả định gọi hoàn toàn của nó theo giá trị? – Sebastian

+0

1) 'boot.stepAIC' sử dụng' update', chạy lại cuộc gọi của mô hình tuyến tính; nếu cuộc gọi có tên của đối tượng hàm (chẳng hạn như 'form') thì đối tượng đó phải có thể truy cập được. 2) Mỗi ​​chức năng có một môi trường (một trong đó nó được tạo ra trong, thường), và một chuỗi các môi trường cha mẹ, mà nó nhìn vào để tìm các đối tượng. Tuy nhiên, việc chạy một hàm trong một hàm khác không thay đổi chuỗi gốc này! Ở cuối chuỗi là môi trường toàn cầu, vì vậy khi 'form' nằm trong môi trường toàn cục, nó có thể tìm thấy nó. Nhưng khi 'form' nằm trong môi trường của hàm gọi, nó không thể. – Aaron