web-dev-qa-db-de.com

Formel mit dynamischer Anzahl von Variablen

Angenommen, es gibt einige data.frame foo_data_frame und man möchte die Regression der Zielspalte Y durch einige andere Spalten finden. Zu diesem Zweck werden normalerweise einige Formeln und Modelle verwendet. Beispielsweise:

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

Das funktioniert gut, wenn die Formel statisch codiert ist. Wenn es gewünscht wird, mehrere Modelle mit der konstanten Anzahl abhängiger Variablen (z. B. 2) zu verwurzeln, kann dies folgendermaßen behandelt werden:

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...
  }
}

Meine Frage ist, wie man den gleichen Effekt macht, wenn sich die Anzahl der Variablen während des Programmablaufs dynamisch ändert?

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?)
   }
}
67
Max

Sehen ?as.formula, z.B.:

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

dabei ist factors ein Zeichenvektor, der die Namen der Faktoren enthält, die Sie im Modell verwenden möchten. Dies können Sie in ein lm Modell einfügen, z.

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
86
Joris Meys

Eine häufig vergessene Funktion ist reformulate. Von ?reformulate:

reformulate erstellt eine Formel aus einem Zeichenvektor.


Ein einfaches Beispiel:

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

ergibt diese Formel:

y ~ factor1 + factor2


Obwohl nicht explizit dokumentiert, können Sie auch Interaktionsbegriffe hinzufügen:

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

wird ergeben:

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

53
mnel

Eine andere Möglichkeit könnte darin bestehen, eine Matrix in der Formel zu verwenden:

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

lm(Y ~ foo[,factors])
10
Sacha Epskamp

Du brauchst eigentlich keine Formel. Das funktioniert:

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

wie geht das:

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

Im Allgemeinen löse ich das, indem ich den Namen meiner Antwortspalte ändere. Es ist einfacher, dynamisch und möglicherweise sauberer zu machen.

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, ...)
0
bibzzzz