如何简洁地从数据框中编写包含许多变量的公式?

时间:2011-03-09 20:05:24

标签: r dataframe glm lm

假设我有一个响应变量和一个包含三个协变量的数据(作为玩具示例):

y = c(1,4,6)
d = data.frame(x1 = c(4,-1,3), x2 = c(3,9,8), x3 = c(4,-4,-2))

我想对数据进行线性回归:

fit = lm(y ~ d$x1 + d$x2 + d$y2)

有没有办法编写公式,这样我就不必写出每个协变量?例如,像

fit = lm(y ~ d)

(我希望数据框中的每个变量都是一个协变量。)我问,因为我的数据框中实际上有50个变量,所以我想避免写出x1 + x2 + x3 + etc

6 个答案:

答案 0 :(得分:173)

有一个特殊的标识符可以在公式中用来表示所有变量,它是.标识符。

y <- c(1,4,6)
d <- data.frame(y = y, x1 = c(4,-1,3), x2 = c(3,9,8), x3 = c(4,-4,-2))
mod <- lm(y ~ ., data = d)

你也可以做这样的事情,使用所有变量吧:

mod <- lm(y ~ . - x3, data = d)

从技术上讲,.表示公式中已提及的所有变量。例如

lm(y ~ x1 * x2 + ., data = d)

其中.仅引用x3 x1,而x2已在公式中。

答案 1 :(得分:57)

稍微不同的方法是从字符串创建公式。在formula帮助页面中,您将找到以下示例:

## Create a formula for a model with a large number of variables:
xnam <- paste("x", 1:25, sep="")
fmla <- as.formula(paste("y ~ ", paste(xnam, collapse= "+")))

然后,如果你看一下生成的公式,你会得到:

R> fmla
y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + 
    x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + 
    x22 + x23 + x24 + x25

答案 2 :(得分:7)

是的,当然,只需将回复y添加为数据框中的第一列,然后在其上调用lm()

d2<-data.frame(y,d)
> d2
  y x1 x2 x3
1 1  4  3  4
2 4 -1  9 -4
3 6  3  8 -2
> lm(d2)

Call:
lm(formula = d2)

Coefficients:
(Intercept)           x1           x2           x3  
    -5.6316       0.7895       1.1579           NA  

此外,我的有关R的信息指出,<-的作业建议超过=

答案 3 :(得分:3)

juba方法的扩展是使用reformulate,这是一个为此类任务明确设计的函数。

## Create a formula for a model with a large number of variables:
xnam <- paste("x", 1:25, sep="")

reformulate(xnam, "y")
y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + 
    x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + 
    x22 + x23 + x24 + x25

对于OP中的示例,此处最简单的解决方案是

# add y variable to data.frame d
d <- cbind(y, d)
reformulate(names(d)[-1], names(d[1]))
y ~ x1 + x2 + x3

mod <- lm(reformulate(names(d)[-1], names(d[1])), data=d)

请注意,将因变量添加到d <- cbind(y, d)中的data.frame是首选,不仅因为它允许使用reformulate,还因为它允许将来使用{{1}像lm这样的函数中的对象。

答案 4 :(得分:1)

我构建了这个解决方案,reformulate并不注意变量名是否有空格。

add_backticks = function(x) {
    paste0("`", x, "`")
}

x_lm_formula = function(x) {
    paste(add_backticks(x), collapse = " + ")
}

build_lm_formula = function(x, y){
    if (length(y)>1){
        stop("y needs to be just one variable")
    }
    as.formula(        
        paste0("`",y,"`", " ~ ", x_lm_formula(x))
    )
}

# Example
df <- data.frame(
    y = c(1,4,6), 
    x1 = c(4,-1,3), 
    x2 = c(3,9,8), 
    x3 = c(4,-4,-2)
    )

# Model Specification
columns = colnames(df)
y_cols = columns[1]
x_cols = columns[2:length(columns)]
formula = build_lm_formula(x_cols, y_cols)
formula
# output
# "`y` ~ `x1` + `x2` + `x3`"

# Run Model
lm(formula = formula, data = df)
# output
Call:
    lm(formula = formula, data = df)

Coefficients:
    (Intercept)           x1           x2           x3  
        -5.6316       0.7895       1.1579           NA  

```

答案 5 :(得分:0)

您可以查看包leaps,特别是功能regsubsets() 模型选择功能。如文档中所述:

通过穷举搜索,前进或后退逐步或顺序替换进行模型选择