2013-08-22 31 views
8

Tôi đang cố viết một thuật toán hình vuông nhỏ nhất được lặp lại trong R. Tôi muốn chuyển một hàm làm đối số để tính trọng số, nhưng tiếc là R phàn nàn rằng hàm không thể được tìm thấy. Bất kỳ ý tưởng những gì tôi đang làm sai? Cảm ơn trước!R: chức năng được truyền dưới dạng đối số không được tìm thấy

Đây là mã của tôi:

irls <- function(imodel, wfunc, tol) { 

    repeat { 
     b0 <- imodel$coef 
     imodel <- lm(formula(imodel), weights=wfunc(imodel), data=imodel$model) 
     b1 <- imodel$coef 
     if(abs((b1-b0)/b0)<=tol) break 
    } 

    imodel 
} 

và một ví dụ ngớ ngẩn để chứng minh vấn đề

x <- 1:100 
y <- x + rnorm(100) 
mlm <- lm(y~x-1) 
irls(mlm, function(x){rep(1,length(x$fit))},0.001) # error: wfunc not found 
+1

Lạ. Có vẻ như vấn đề nằm trong 'lm'. Khi nó cố tìm hàm trong dòng sau: 'mf <- eval (mf, parent.frame())' – nograpes

+0

Nó có thể giúp: http://stackoverflow.com/questions/7027288/error-could-not- find-function-in-r – Fernando

+1

Tôi nghĩ rằng bạn nên tắt chức năng của mình trước tiên. 'wfunc <-function (x) {rep (1, length (x $ fit))}' theo sau với 'irls (mlm, wfunc, 0.001)' –

Trả lời

8

Vấn đề đi kèm với cách lm tìm kiếm dữ liệu. Nếu bạn thay đổi các chức năng này có vẻ như để làm việc

irls <- function(imodel, wfunc, tol) { 

    repeat { 
     b0 <- imodel$coef 
     dat <- imodel$model 
     dat$wts <- wfunc(imodel) 
     imodel <- lm(formula(imodel), weights=wts, data=dat) 
     b1 <- imodel$coef 
     if(abs((b1-b0)/b0)<=tol) break 
    } 

    imodel 
} 
+1

Đùa bạn ninja đã làm tôi! –

+0

Cảm ơn bạn rất nhiều :) – linuxfever

5

Các formula chứa các môi trường của lm gọi ban đầu (.GlobalEnv, trong trường hợp này), trong đó wfunc là không có sẵn. Để giải quyết sự cố này, bạn có thể thay thế bằng môi trường hiện tại.

irls <- function(imodel, wfunc, tol) { 
    f <- formula(imodel) 
    environment(f) <- environment() 
    repeat { 
    b0 <- imodel$coef 
    imodel <- lm(f, weights=wfunc(imodel), data=imodel$model) 
    b1 <- imodel$coef 
    if(abs((b1-b0)/b0)<=tol) break 
    } 
    imodel 
} 
irls(mlm, function(x){rep(1,length(x$fit))},0.001) 
+0

Bạn chỉ cần làm điều đó một lần - không phải mọi lần. – hadley

+0

@hadley: điểm tốt. Tôi đã di chuyển công thức ra ngoài vòng lặp. –

-1

Vấn đề này phát sinh vì model.frame.default được gọi là bên lm, mà đánh giá tất cả mọi thứ trong môi trường của công thức:

model.frame.default 
#function (formula, data = NULL, subset = NULL, na.action = na.fail, 
# drop.unused.levels = FALSE, xlev = NULL, ...) 
#{ 
#... 
# env <- environment(formula) 
#... 
# extras <- eval(extras, data, env) <-- this is where you run into a problem 
#... 

Vì vậy, giống như những người khác đã gợi ý, đánh giá chức năng bên ngoài của lm.

+0

và lý do cho downvote là ... – eddi

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