7

我想遍历一个长向量的潜在解释变量,依次回归每个响应变量。我没有将模型公式粘贴在一起,而是考虑使用reformulate()如此处所示

下面的功能fun()似乎可以完成这项工作,适合所需的模型。但是请注意,它在其调用元素中记录了构造公式对象的名称,而不是其

## (1) Function using programmatically constructed formula
fun <- function(XX) {
    ff <- reformulate(response="mpg", termlabels=XX)
    lm(ff, data=mtcars)
}
fun(XX=c("cyl", "disp"))
# 
# Call:
# lm(formula = ff, data = mtcars)                 <<<--- Note recorded call
# 
# Coefficients:
# (Intercept)          cyl         disp  
#    34.66099     -1.58728     -0.02058  

## (2) Result of directly specified formula (just for purposes of comparison)
lm(mpg ~ cyl + disp, data=mtcars)
# 
# Call:
# lm(formula = mpg ~ cyl + disp, data = mtcars)   <<<--- Note recorded call
# 
# Coefficients:
# (Intercept)          cyl         disp  
#    34.66099     -1.58728     -0.02058  

我的问题:这有什么危险吗?例如,如果我想稍后将 或其他函数应用于模型拟合对象(可能来自其他环境),这会成为一个问题updatepredict

然而,一个稍微尴尬的替代方法是使用eval(substitute()). 这在某种程度上是一个更安全的结构吗?

fun2 <- function(XX) {
    ff <- reformulate(response="mpg", termlabels=XX)
    eval(substitute(lm(FF, data=mtcars), list(FF=ff)))
}
fun2(XX=c("cyl", "disp"))$call
## lm(formula = mpg ~ cyl + disp, data = mtcars)
4

1 回答 1

2

我总是犹豫是否声称没有涉及 R 环境和范围界定的东西可能会咬人的情况,但是......经过更多的探索,我上面的第一次使用看起来确实很安全

事实证明,打印出来的电话有点红鲱鱼。

其他函数实际使用的公式(以及由formula()and提取的公式as.formula())是存储在termsfit 对象的元素中的公式,正确地获取了实际公式。(该terms元素包含一个 class 对象"terms",它只是一个"formula"带有一堆附加属性的对象。)

要查看我的问题中的所有提案和相关评论都存储了相同的"formula"对象(直到相关的环境),请运行以下命令。

## First the three approaches in my post
formula(fun(XX=c("cyl", "disp")))
# mpg ~ cyl + disp
# <environment: 0x026d2b7c>

formula(lm(mpg ~ cyl + disp, data=mtcars))
# mpg ~ cyl + disp

formula(fun2(XX=c("cyl", "disp"))$call)
# mpg ~ cyl + disp
# <environment: 0x02c4ce2c>

## Then Gabor Grothendieck's idea
XX = c("cyl", "disp")
ff <- reformulate(response="mpg", termlabels=XX)
formula(do.call("lm", list(ff, quote(mtcars))))  
## mpg ~ cyl + disp

要确认formula()确实是从 fit 对象的元素派生其输出,terms请查看stats:::formula.lmand stats:::formula.terms

于 2013-07-03T21:50:01.873 回答