使用R,这是一个真正的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()
电话中?我知道这是一个关于评估哪些环境的问题,因为这有效:
R> f_formula <- with(iris, as.formula(f_string))
R> lm(f_formula)
但是我很难绕过为什么一个人工作而另一个人不工作。
答案 0 :(得分:2)
您失败的示例失败,因为您正在使用全局环境创建公式:
> 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
。如果在全局环境中创建适当的对象,则可以使其工作:
> 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"