変数の動的な数を持つ式


83

仮定し、そこにいくつかのdata.frameのあるfoo_data_frameと1は、ターゲット列の回帰見つけたいYをいくつかの他の列で。その目的のために、通常、いくつかの式とモデルが使用されます。例えば:

linear_model <- lm(Y ~ FACTOR_NAME_1 + FACTOR_NAME_2, foo_data_frame)

式が静的にコーディングされている場合、これはうまく機能します。従属変数の数が一定(たとえば2)の複数のモデルをルート化する必要がある場合は、次のように扱うことができます。

for (i in seq_len(factor_number)) {
  for (j in seq(i + 1, factor_number)) {
    linear_model <- lm(Y ~ F1 + F2, list(Y=foo_data_frame$Y,
                                         F1=foo_data_frame[[i]],
                                         F2=foo_data_frame[[j]]))
    # linear_model further analyzing...
  }
}

私の質問は、プログラムの実行中に変数の数が動的に変化するときに同じ影響を与える方法です。

for (number_of_factors in seq_len(5)) {
   # Then root over subsets with #number_of_factors cardinality.
   for (factors_subset in all_subsets_with_fixed_cardinality) {
     # Here I want to fit model with factors from factors_subset.
     linear_model <- lm(Does R provide smth to write here?)
   }
}

2
ありがとう!あなたの真ん中の例は、私があなたの質問に対する解決策を必要とせず、もっと簡単なことをすることができることに気づきました!
マークアダムソン2016年

回答:


105

?as.formula例を参照してください。

factors <- c("factor1", "factor2")
as.formula(paste("y~", paste(factors, collapse="+")))
# y ~ factor1 + factor2

ここfactorsで、はモデルで使用する因子の名前を含む文字ベクトルです。これをlmモデルに貼り付けることができます。例:

set.seed(0)
y <- rnorm(100)
factor1 <- rep(1:2, each=50)
factor2 <- rep(3:4, 50)
lm(as.formula(paste("y~", paste(factors, collapse="+"))))

# Call:
# lm(formula = as.formula(paste("y~", paste(factors, collapse = "+"))))

# Coefficients:
# (Intercept)      factor1      factor2  
#    0.542471    -0.002525    -0.147433

66

忘れられがちな関数はreformulateです。差出人?reformulate

reformulate 文字ベクトルから数式を作成します。


簡単な例:

listoffactors <- c("factor1","factor2")
reformulate(termlabels = listoffactors, response = 'y')

次の式が得られます。

y ~ factor1 + factor2


明示的に文書化されていませんが、交互作用用語を追加することもできます。

listofintfactors <- c("(factor3","factor4)^2")
reformulate(termlabels = c(listoffactors, listofintfactors), 
    response = 'y')

生成されます:

y ~ factor1 + factor2 + (factor3 + factor4)^2


3
@JorisMeysそして、交互作用項を追加できるので、とても便利です!私は..年の同様のソリューションを探してきた
landroni

x変数にスペースが含まれている場合はどうなりますか?セイ「因子1」、「2倍」など。
公理

11

別のオプションは、式で行列を使用することです。

Y = rnorm(10)
foo = matrix(rnorm(100),10,10)
factors=c(1,5,8)

lm(Y ~ foo[,factors])

3
+1ですが、これでは交互作用効果を使用できないことに注意してください。そのためには、モデル行列を作成することもできます(を参照?model.matrix
Joris Meys 2011

4

実際には数式は必要ありません。これは機能します:

lm(data_frame[c("Y", "factor1", "factor2")])

これがするように:

v <- c("Y", "factor1", "factor2")
do.call("lm", list(bquote(data_frame[.(v)])))

+1非常に正しいですが、ここでも、model.matrixを使用して、交互作用効果のある行列を作成する必要があります。
Joris Meys 2011

0

私は通常、応答列の名前を変更することでこれを解決します。動的に行う方が簡単で、場合によってはよりクリーンになります。

model_response <- "response_field_name"
setnames(model_data_train, c(model_response), "response") #if using data.table
model_gbm <- gbm(response ~ ., data=model_data_train, ...)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.