这个问题与R - 如何将公式传递给函数内的 with(df, glm(y ~ x)) 构造高度相关,但提出了更广泛的问题。
为什么这些表达式有效?
text_obj <- "mpg ~ cyl"
form_obj <- as.formula(text_obj)
with(mtcars, lm(mpg ~ cyl))
with(mtcars, lm(as.formula(text_obj)))
lm(form_obj, data = mtcars)
Run Code Online (Sandbox Code Playgroud)
但不是这个吗?
with(mtcars, lm(form_obj))
Error in eval(predvars, data, env) : object 'mpg' not found
Run Code Online (Sandbox Code Playgroud)
我通常会使用该data参数,但这在mice包中是不可能的。IE。
library(mice)
mtcars[5, 5] <- NA # introduce a missing value to be imputed
mtcars.imp = mice(mtcars, m = 5)
Run Code Online (Sandbox Code Playgroud)
这些不起作用
lm(form_obj, data = mtcars.imp)
with(mtcars.imp, lm(form.obj))
Run Code Online (Sandbox Code Playgroud)
但这确实
with(mtcars.imp, lm(as.formula(text_obj)))
Run Code Online (Sandbox Code Playgroud)
因此,是否总是as.formula在函数内部使用参数,而不是先构造它然后将其传入?
公式的一个重要的“隐藏”方面是它们的相关环境。
创建时form_obj,其环境设置为form_obj创建时的位置:
environment(form_obj)
# <environment: R_GlobalEnv>
Run Code Online (Sandbox Code Playgroud)
对于每个其他版本,公式的环境是从内部创建的with(),并设置为该临时环境。as.formula通过将其分为几个步骤,最容易看到这一点:
with(mtcars, {
f = as.formula(text_obj)
print(environment(f))
lm(f)
})
# <environment: 0x7fbb68b08588>
Run Code Online (Sandbox Code Playgroud)
我们可以form_obj通过在调用之前编辑其环境来使该方法起作用lm:
with(mtcars, {
# set form_obj's environment to the current one
environment(form_obj) = environment()
lm(form_obj)
})
Run Code Online (Sandbox Code Playgroud)
帮助页面?formula有点长,但有一个关于环境的部分:
环境
公式对象具有关联的环境,并且该环境(而不是父环境)用于
model.frame计算在提供的数据参数中找不到的变量。使用运算符创建的公式
~使用创建它们的环境。使用 创建的公式as.formula将使用env其环境的参数。
结果是,制作一个公式,将~环境部分“隐藏起来”——在更一般的设置中,使用它更安全,as.formula这使您可以更全面地控制公式适用的环境。
您还可以查看 Hadley 有关环境的章节:
http://adv-r.had.co.nz/Environments.html
| 归档时间: |
|
| 查看次数: |
730 次 |
| 最近记录: |