2013-06-30 1 views
7

私は、潜在的な説明変数であるベクトル を順番に回帰したいと考えています。 を一緒に貼り付けるのではなく、reformulate()as demonstrated hereと考えています。プログラムで構築された数式を使用するうえでの落とし穴はありますか?

以下の機能fun()は、希望のモデルに合った仕事をしているようです。しかし、 は、の値ではなく、という名前の構成式オブジェクト のという名前を呼び出し要素に記録することに注意してください。

## (1) Function using programatically contructed formula 
fun <- function(XX) { 
    ff <- reformulate(response="mpg", termlabels=XX) 
    lm(ff, data=mtcars) 
} 
fun(XX=c("cyl", "disp")) 
# 
# Call: 
# lm(formula = ff, data = mtcars)     <<<--- Note recorded call 
# 
# Coefficients: 
# (Intercept)   cyl   disp 
# 34.66099  -1.58728  -0.02058 

## (2) Result of directly specified formula (just for purposes of comparison) 
lm(mpg ~ cyl + disp, data=mtcars) 
# 
# Call: 
# lm(formula = mpg ~ cyl + disp, data = mtcars) <<<--- Note recorded call 
# 
# Coefficients: 
# (Intercept)   cyl   disp 
# 34.66099  -1.58728  -0.02058 

私の質問:はこの内の任意の危険性はありますか?たとえば、後でupdate、またはpredictまたは をモデルフィットオブジェクトに適用したい場合(おそらく他の環境から)、これは 問題になることがありますか?

それにもかかわらず、記録されている のコール権を取得するのは少し面倒な選択肢です。eval(substitute())を使用します。どのようにしてもこれは一般により安全な構造ですか?

fun2 <- function(XX) { 
    ff <- reformulate(response="mpg", termlabels=XX) 
    eval(substitute(lm(FF, data=mtcars), list(FF=ff))) 
} 
fun2(XX=c("cyl", "disp"))$call 
## lm(formula = mpg ~ cyl + disp, data = mtcars) 
+2

私はこの問題が 'update'を使って慎重になると思います。[http://stackoverflow.com/questions/13690184/update-inside-a-function-only-searches-the-global-environment]を参照してください。通常、これらの落とし穴は 'data.table'を使って調べることができます - [http://stackoverflow.com/questions/15096811/why-is-using-update-on-a-lm-inside-a- @ 15376891#15376891] – mnel

+3

これは動作します: 'do.call(" lm "、list(ff、quote(mtcars)))' –

+0

@G.Grothendieck - ありがとう。それは良いように見え、道路の下で何の問題も生じないはずです。 (また、興味深いリンクのためのmnelに感謝します。) –

答えて

2

は、私はいつもここで何かR環境とかむかもしれないスコープを含む状況が存在しないと主張することを躊躇んだけど、...もう少し探検した後、私の最初の使用は、上記安全に見えるん。

印刷された電話はちょっとした赤ちゃんです。

実際が他の機能(およびformula()as.formula()により抽出されたもの)によって使用されますが、フィットオブジェクトのterms要素に格納されているものであることを式、及びそれ実際式権を取得します。 (terms要素は、ちょうど付属属性の束と"formula"あるクラス"terms"のオブジェクトが含まれています。)

はまで(私の質問の提案と関連するコメントがすべて同じ"formula"オブジェクトを格納することを確認するには関連する環境)、以下を実行します。

## First the three approaches in my post 
formula(fun(XX=c("cyl", "disp"))) 
# mpg ~ cyl + disp 
# <environment: 0x026d2b7c> 

formula(lm(mpg ~ cyl + disp, data=mtcars)) 
# mpg ~ cyl + disp 

formula(fun2(XX=c("cyl", "disp"))$call) 
# mpg ~ cyl + disp 
# <environment: 0x02c4ce2c> 

## Then Gabor Grothendieck's idea 
XX = c("cyl", "disp") 
ff <- reformulate(response="mpg", termlabels=XX) 
formula(do.call("lm", list(ff, quote(mtcars)))) 
## mpg ~ cyl + disp 

formula()が本当にフィットオブジェクトのterms要素から、その出力を導出していることを確認するために、stats:::formula.lmstats:::formula.termsを見てみましょう。

+0

ニースの探検。私は前に 'do.call'メソッドを使用しましたが、これは同じ質問のいくつかのためです。これらの関数が格納されている式/呼び出しに依存していないことを知ってうれしいです。しかし、私は 'update'がそうだと信じています。だから、その使用法に注意してください。 – Aaron

+0

@Aaron - ありがとうございます。あなたは私の質問に続く最初のコメントでmnelと同じ問題を言いましたか?もしそうなら、その落とし穴が上記の呼び出しのどれにも等しく当てはまることを理解するのは間違いないでしょうか? ( 'do.call()'を使って 'lm()'の呼び出しを行っても、 'update()'のスコープの問題を避けることはできません) –

+1

さらに探検した後、 'update'のように見えます安全です。私はそれがなかったと確信していたが、多分私はこのすべての間違っていた。しかし、正しい関数に依存する関数、例えば 'anova.lme'があります。 http://stackoverflow.com/q/7666807/210673を参照してください。 – Aaron

関連する問題