具有动态变量数的公式


82

假设有一些data.frame foo_data_frame,有人想通过其他一些列来查找目标列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
谢谢!您的中间示例使我意识到,我不需要解决您的问题,可以做一些简单的事情!
Mark Adamson

Answers:


103

参见?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变量包含空格怎么办?说“ factor 1”,“ factor 2”等
公理


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, ...)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.