2014-09-04 72 views
1

与R工作组,这是一个真正的跆拳道:为什么as.formula只能在()内部的lm()内工作?

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()调用之内?我明白了,这是关于哪些事情环境评估中的一个问题,因为这个工程:

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

,但我有真正的麻烦缠绕我的头周围为什么一个作品,另一个没有。

> 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有:因为您要建立与全球环境的公式

+1

您可能希望清理代码并使其完全可重现。然而,看着'as.formula'的代码我也不明白。我认为'as.formula(f_string,env = basenev())'或'as.formula(f_string,env = parent.frame())'应该可以工作(我期望前者),但只有当'env'是'missing'它的工作原理。 (我希望你知道你不应该在这里使用''''lm'和朋友有一个'data'参数是有原因的) – Roland 2014-09-04 07:52:19

+0

@Roland哎呀,不小心在那里留下了一些东西...... – naught101 2014-09-04 08:03:21

+0

@Roland :关于'data ='的争论也是完全正确的。它让'lm()'把字符串变好,所以我可以避免整个问题。尽管如此,它很有趣,作为一个compsci初学者:) – naught101 2014-09-04 08:12:01

回答

2

你失败的例子失败。如果在全球环境中创建合适的对象,你可以让它工作:

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

但是,这是完全无视iris数据。欢迎来到令人讨厌的R行为的世界。

其他示例都是在iris数据框中计算公式对象作为环境。如果调试lm并看看什么formula是在你的工作情况之一:

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

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

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

使用'environment()'是一个稍微漂亮的(在我看来)的方式来得到一个对象被分配的环境相比'attr(x,“。Environment” )'。所以你可以像'ls(envir = environment(f_formula))'那样做。我很难将这种行为称为“烦人”,因为这意味着可以通过'lm()'的'data ='参数轻松处理。不正确地使用它们时不要生气。正如@Roland首先所说的,使用'lm(f_formula,iris)'而不是'with(iris,lm(f_formula))'。 – MrFlick 2014-09-04 14:03:50

+1

我使用了这种符号,因为这是'str(f)'显示它的方式。大多数R对象(函数,数据框)不会将其环境存储在属性中。我不知道为什么公式。 'print.formula'很有趣。令人烦恼的是,对于一种功能性语言来说,纯粹的功能主义者会忽略的一些评估事项正在发生。 – Spacedman 2014-09-04 15:05:47

相关问题