2012-07-21 3 views
6

y ~ a*bという形の多くの数式(クラスformulaまたはFormula)があります。abが要因です。数式内の拡大因子の相互作用

このような数式を取り、相互作用の用語がすべて「スペルアウト」された数式を返す関数を記述する必要があります。ここでの例である:

BigFormula戻り formula(x ~ a + b + c + d + a:c + a:d + b:c + b:d)
fac1 <- factor(c('a', 'a', 'b', 'b')) 
fac2 <- factor(c('c', 'd', 'c', 'd')) 
BigFormula(formula(x ~ fac1*fac2)) 

これを行う簡単な方法はありますか?

(コンテキスト:私はmod1mod2巣の形anova(mod1, mod2)、多くのコマンドを実行している、とどこ両モデルの右辺はfac1*fac2などの用語が含まれていますこれらのコマンドのポイントは、F-統計を計算することです。問題は、anovaは通常3つ以上の変数を表すにもかかわらず、fac1*fac2を3つの変数として扱います(上記のコードでは、fac1*fac2は8つの変数を表します)。結果として、anovaは入れ子にされた制限の数を過小評価します私の自由度を過大評価しています)。

答えて

2

次の解決方法はどうですか?私は複雑な相互作用のより極端な例を使用します。

f = formula(y ~ a * b * c * d * e)

相互作用項を綴るために、我々は条件によって返された値から用語を抽出。式():

> terms 
[1] "a"   "b"   "c"   "d"   "e"   "a:b"  "a:c"  
[8] "b:c"  "a:d"  "b:d"  "c:d"  "a:e"  "b:e"  "c:e"  
[15] "d:e"  "a:b:c"  "a:b:d"  "a:c:d"  "b:c:d"  "a:b:e"  "a:c:e"  
[22] "b:c:e"  "a:d:e"  "b:d:e"  "c:d:e"  "a:b:c:d" "a:b:c:e" "a:b:d:e" 
[29] "a:c:d:e" "b:c:d:e" "a:b:c:d:e" 

をそして、我々は、式に戻って、それを変換することができます:

terms = attr(terms.formula(f), "term.labels")

f = as.formula(sprintf("y ~ %s", paste(terms, collapse="+")))

> f 
y ~ a + b + c + d + e + a:b + a:c + b:c + a:d + b:d + c:d + a:e + 
    b:e + c:e + d:e + a:b:c + a:b:d + a:c:d + b:c:d + a:b:e + 
    a:c:e + b:c:e + a:d:e + b:d:e + c:d:e + a:b:c:d + a:b:c:e + 
    a:b:d:e + a:c:d:e + b:c:d:e + a:b:c:d:e 
0

私たちは同様の問題を抱えていますが、数式には50の変数があり、非常に頻繁に変更する必要がありました。私たちの解決策は、Rスクリプト内にループ内でそれらを外部ファイルに送信し、実際の数式を作成した後、単純にそのtxtファイルを読んで貼り付けることでした。私が思う限り、入れ子になったループで行うことができますので、より多くの数式を作成してファイルを1行ずつ読み戻すことができます。 Rスクリプトとbashの両方を常に使うのは良いことです。

7

formulaのヘルプを見て、あなたに役立つ既存のものがあるかもしれません。

たとえば、式y ~ (a + b + c + d)^2はすべての主要効果とすべての2ウェイ相互作用を提供し、式y ~ (a + b) * (c + d)は上に示した拡張を与えます。 また、y ~ a*b*c - a:b:cに3ウェイインタラクションが含まれないように、タームを引き算することもできます。

3

は、私はまだ、式のすべてのトリックを学ぶためには至っていないが、私は明示的な式をしたい場合、私は貼り付けてsapply一緒に使用する傾向があるでしょう:

> f 
[1] "x ~ a + b + c + d + a:c + a:d + b:c + b:d" 
:私たちは、で終わる

# the factors 
fac1 <- factor(c('a', 'a', 'b', 'b')) 
fac2 <- factor(c('c', 'd', 'c', 'd')) 

# create all the interaction terms 
out <- sapply(levels(fac1), function(ii) { 
    sapply(levels(fac2), function(jj) { 
    paste0(ii,":",jj) 
    }) 
}) 
# along with the single terms 
terms <- c(levels(fac1), levels(fac2), as.vector(out)) 

# and create the rhs of the formula 
rhs <- paste0(terms, collapse=" + ") 

# finally add the lhs 
f <- paste0("x ~ ", rhs)