2013-09-15 5 views
4

У меня есть функция правдоподобия, которая входит в качестве аргумента в функцию maxLik функции пакета maxLik. Например:Создание формулы (синтаксиса) в R для пакета

library(maxLik) 

likFun <- function(param, x, y, h) { 

    dep <- as.matrix(x[,y]) 
    indep <- as.matrix(x[,h]) 
    indep <- as.matrix(cbind(cons=1, indep)) 
    k  <- dim(indep)[2] 
    beta <- as.matrix(param[1:k]) 
    xbeta <- crossprod(t(indep), beta) 
    sig <- param[k+1] 
    res <- (dep-xbeta)/sig 
    sum( (-(1/2)*log(2*pi)) - ((1/2)*log((sig)^2)) - ((res^2)/2) ) 

} 
model <- maxLik(likFun, start=c(0,0,0,1), grad=NULL, hess=NULL, x=mtcars, 
       y="mpg", h=c("cyl", "hp")) 
summary(model) 

В принципе, вышеуказанная функция правдоподобия использует максимальную вероятность для модели с множественной регрессией. Мой вопрос заключается в том, как создать formula в R (для пакета), например, в lm, чтобы пользователь мог ввести зависимую переменную и независимые переменные и данные. Я проверил model.matrix, но я не уверен, является ли он тем, кого я должен искать. Любое предложение в этом отношении будет высоко оценено.

+0

Не ясно мне. Ваша функция, по-видимому, принимает в качестве аргументов независимые и зависимые переменные. Где нужна «формула»? –

+0

@ Carl: Я пытаюсь развить это (не совсем это) в виде пакета. Поэтому я не могу использовать эту версию. – Metrics

+1

Вы хотите использовать что-то вроде 'mpg ~ cyl + hp' вместо' y = "mpg", h = c ("cyl", "hp") 'в аргументах? –

ответ

3

Для вы можете вызвать свою функцию, используя что-то вроде mpg ~ cyl + hp вместо y="mpg", h=c("cyl", "hp") в аргументах, вы можете использовать объект формулы. По умолчанию они не оценены, поэтому вам не нужны substitute или match.call.

Если вам нужно что-то более сложное, чем просто удалять символы в каждой части формулы, вам придется написать собственный парсер. В противном случае, используйте функцию all.vars:

f <- function(data, formula){ 
    print("Right hand side:") 
    print(head(data[,all.vars(formula[[3]]), drop=FALSE])) 
    print("Left hand side:") 
    print(head(data[,all.vars(formula[[2]]), drop=FALSE])) 
} 

Результат:

> f(mtcars, mpg ~ cyl + hp) 
[1] "Right hand side:" 
        cyl hp 
Mazda RX4   6 110 
Mazda RX4 Wag  6 110 
Datsun 710   4 93 
Hornet 4 Drive  6 110 
Hornet Sportabout 8 175 
Valiant    6 105 
[1] "Left hand side:" 
        mpg 
Mazda RX4   21.0 
Mazda RX4 Wag  21.0 
Datsun 710  22.8 
Hornet 4 Drive 21.4 
Hornet Sportabout 18.7 
Valiant   18.1 
+0

Спасибо за это. – Metrics

+1

Да; мой ответ на такие вопросы, грубо говоря, «Прочитайте исходный код для ссылочного пункта». В этом случае для 'lm' –

2

Грубо, вы используете eval внутри функции. Однако сначала вам нужно получить аргументы функции в необоснованном контексте (чтобы вы могли подставить переменные в формулу). Для этого вам понадобится match.call. Вот очень простой пример:

f <- function (.FUN, ...) { 
    args <- match.call(expand.dots = FALSE) 
    eval(args$.FUN, args$...) 
} 

Это будет фиксировать формулу в .FUN и фактические аргументы в ..., которые могут быть доступны (в виде списка) с помощью args$....

Теперь вы можете вызвать эту функцию, аналогичную lm:

> f(x + y, x = 1, y = 2) 
3 

В качестве альтернативы match.call, вы можете также использовать substitute получить аргумент функции в качестве невычисленного контексте:

f <- function (.FUN, ...) 
    eval(substitute(.FUN), list(...)) 
Смежные вопросы