R - 如何将公式传递给 with(data, lm(y ~ x)) 结构

问题描述 投票:0回答:2

这个问题与 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)

但不是这个?

with(mtcars, lm(form_obj))
Error in eval(predvars, data, env) : object 'mpg' not found

我通常会使用

data
参数,但这在
mice
包中是不可能的。 IE。

library(mice)
mtcars[5, 5] <- NA # introduce a missing value to be imputed
mtcars.imp = mice(mtcars, m = 5)

这些不起作用

lm(form_obj, data = mtcars.imp)
with(mtcars.imp, lm(form.obj))

但这确实

with(mtcars.imp, lm(as.formula(text_obj)))

因此,在函数内部始终使用

as.formula
参数,而不是先构造它然后将其传入,是不是更好?

r lm r-mice
2个回答
5
投票

公式的一个重要的“隐藏”方面是它们的相关环境。

创建

form_obj
时,其环境设置为创建
form_obj
的位置:

environment(form_obj)
# <environment: R_GlobalEnv>

对于每个其他版本,公式的环境是从

with()
内部创建的,并设置为该临时环境。使用
as.formula
方法最容易看到这一点,将其分为几个步骤:

with(mtcars, {
  f = as.formula(text_obj)
  print(environment(f))
  lm(f)
})
# <environment: 0x7fbb68b08588>

我们可以通过在调用

form_obj
之前编辑其环境来使
lm
方法发挥作用:

with(mtcars, {
  # set form_obj's environment to the current one
  environment(form_obj) = environment()
  lm(form_obj)
})

?formula
的帮助页面有点长,但是有一个关于环境的部分:

环境

公式对象具有关联的环境,

model.frame
使用此环境(而不是父环境)来计算在提供的数据参数中找不到的变量。

使用

~
运算符创建的公式使用创建它们的环境。使用
as.formula
创建的公式将为其环境使用
env
参数。

结果是,使用

~
制作公式会将环境部分“隐藏起来”——在更一般的设置中,使用
as.formula
更安全,它可以让您更全面地控制公式适用的环境。

您还可以查看 Hadley 关于环境的章节:

http://adv-r.had.co.nz/Environments.html


0
投票

我需要补充一项

 environment(form_obj) = environment()

form_obj 可能指定一个存在于创建公式的环境中的变量。为了解决这种情况,可以添加公式作为父级的环境,例如

ev <- environment()
parent.env(ev) <- environment(form_obj)
environment(form_obj) <- ev
© www.soinside.com 2019 - 2024. All rights reserved.