为什么as.formula仅在with()内部的lm()内部工作? [英] Why does as.formula only work inside lm() inside with()?

查看:173
本文介绍了为什么as.formula仅在with()内部的lm()内部工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用R,这是一个真正的WTF:

Working with R, this is a real WTF:

R> f_string <- 'Sepal.Length ~ Sepal.Width'
R> l <- with(iris, lm(as.formula(f_string))) # works fine

R> f_formula <- as.formula(f_string)
R> l <- with(iris, lm(f_formula))
Error in eval(expr, envir, enclos) : object 'Sepal.Length' not found

为什么as.formula必须位于lm()调用中?我知道这是一个关于在什么环境中评估事物的问题,因为这可行:

Why does as.formula have to be inside the lm() call? I get it that this is a question about which environment things are evaluated in, because this works:

R> f_formula <- with(iris, as.formula(f_string))
R> lm(f_formula)

但是我很难理解为什么一个有效而另一个无效的原因.

but I'm having real trouble wrapping my head around why one works and the other one doesn't.

推荐答案

您失败的示例失败,因为您正在使用全局环境创建公式:

Your failing example fails because you are creating the formula with the global environment:

> f_formula <- as.formula(f_string)
> l <- with(iris, lm(f_formula))
Error in eval(expr, envir, enclos) : object 'Sepal.Length' not found
> str(f_formula)
Class 'formula' length 3 Sepal.Length ~ Sepal.Width
  ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 

那里没有Sepal.Length.如果您在全局环境中创建适当的对象,则可以使其起作用:

and there's no Sepal.Length there. If you create the appropriate objects in the global environment you can make it work:

> Sepal.Length=1:10
> Sepal.Width=runif(10)
> l <- with(iris, lm(f_formula)) # "works" (ie doesn't error)

但这完全是忽略了 iris数据.欢迎来到令人讨厌的R行为世界.

But that is completely ignoring the iris data. Welcome to the world of annoying R behaviour.

其他示例都将iris数据框中的公式对象作为环境进行计算.如果您调试lm并查看其中一种工作情况下的formula是什么:

The other examples are all computing the formula object within the iris data frame as an environment. If you debug lm and take a look at what formula is in one of your working cases:

Browse[2]> str(formula)
Class 'formula' length 3 Sepal.Length ~ Sepal.Width
  ..- attr(*, ".Environment")=<environment: 0x9d590b4> 

您将看到环境不再是全球环境.如果要查看该环境中的内容,请从公式的属性和列表中获取它:

you'll see the environment is no longer the global one. If you want to see what's in that environment, get it from the formula's attributes and list:

Browse[2]> e = attr(formula,".Environment")
Browse[2]> with(e,ls())
[1] "Petal.Length" "Petal.Width"  "Sepal.Length" "Sepal.Width"  "Species"     

这篇关于为什么as.formula仅在with()内部的lm()内部工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆