1

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)

しかし、なぜ一方が機能し、もう一方が機能しないのか、頭を悩ませています。

4

1 に答える 1

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データ フレーム内の数式オブジェクトを環境として計算しています。デバッグして、作業ケースの 1 つにある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"     
于 2014-09-04T08:53:37.660 に答える