在R中为包创建公式(语法)

时间:2013-09-15 13:46:07

标签: r

我有一个似然函数作为参数输入maxLik包的maxLik函数。例如:

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,但我不确定它是否是我应该寻找的那个。任何有关这方面的建议都将受到高度赞赏。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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(...))