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

4

我有一个似然函数,作为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)

基本上,上述似然函数是为多元回归模型使用最大似然估计。我的问题是如何在R中创建一个类似于lmformula(用于该软件包),以便用户能够输入因变量、自变量和数据。我已经检查了model.matrix,但不确定它是否是我应该寻找的东西。任何关于此方面的建议将不胜感激。


我不太清楚。您的函数似乎将自变量和因变量作为其参数。那么formula的需要在哪里发生呢? - Carl Witthoft
@卡尔:我正在尝试以包的形式开发这个(不完全是这个),所以我不能使用这个版本。 - Metrics
1
你想在参数中使用类似于 mpg ~ cyl + hp 这样的东西,而不是 y="mpg", h=c("cyl", "hp") 吗? - Ferdinand.kraft
确切地说,那就是我想要的。 - Metrics
2个回答

3
为了能够使用类似于 mpg ~ cyl + hp 而不是在参数中使用 y="mpg", h=c("cyl", "hp") 来调用您的函数,您可以使用公式对象。它们默认情况下未求值,因此您不需要使用 substitutematch.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
是的,对于这类问题,我的首选答案大致是“阅读所引用项目的源代码”。在这种情况下,指的是lm的源代码。 - Carl Witthoft

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接