R中有多个x变量和一个y的简单线性回归.只写一个模型,而不是每个x和y的组合?



我想对一个y变量(1个变量)分析许多x变量(400个变量)。但是我不想为每个x变量都写一个新的模型。是否有可能编写一个模型,而不是在R-Studio中检查所有x变量?

这是一种方法,我们使用一个函数将数据帧中的所有变量回归到作为参数传递给函数的同一数据帧中的因变量上。

我们使用lapply()来驱动lm(),因为它将返回结果模型对象作为一个列表,并且我们能够轻松地命名结果列表,以便我们可以通过自变量名称提取模型。

regList <- function(dataframe,depVar) {
indepVars <- names(dataframe)[!(names(dataframe) %in% depVar)]

modelList <- lapply(indepVars,function(x){
lm(dataframe[[depVar]] ~ dataframe[[x]],data=dataframe)
})
# name list elements based on independent variable names 
names(modelList) <- indepVars
modelList
}

我们用mtcars数据帧来演示函数,指定mpg列作为因变量。

modelList <- regList(mtcars,"mpg")

此时,modelList对象包含10个模型,每个模型对应mtcars数据帧中的变量,mpg除外。我们可以通过独立变量名或索引访问单个模型。

# print the model where cyl is independent variable 
summary(modelList[["cyl"]])

…输出:

> summary(modelList[["cyl"]])
Call:
lm(formula = dataframe[[depVar]] ~ dataframe[[x]], data = dataframe)
Residuals:
Min      1Q  Median      3Q     Max 
-4.9814 -2.1185  0.2217  1.0717  7.5186 
Coefficients:
Estimate Std. Error t value Pr(>|t|)    
(Intercept)     37.8846     2.0738   18.27  < 2e-16 ***
dataframe[[x]]  -2.8758     0.3224   -8.92 6.11e-10 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 3.206 on 30 degrees of freedom
Multiple R-squared:  0.7262,    Adjusted R-squared:  0.7171 
F-statistic: 79.56 on 1 and 30 DF,  p-value: 6.113e-10

提取内容

将输出保存在list()中使我们能够在不使用vgrep的情况下找到具有最高R^2的模型。

首先,我们从每个模型摘要中提取r.squared值,并将结果保存到一个向量中。

r.squareds <- unlist(lapply(modelList,function(x) summary(x)$r.squared)) 

因为我们使用names()来命名原始列表中的元素,R自动将变量名保存为vector的元素名。当我们按R^2的降序对向量进行排序并输出结果向量的第一个元素时,这就派上用场了。

r.squareds[order(r.squareds,decreasing=TRUE)][1]

…毫无疑问,获胜者是wt

> r.squareds[order(r.squareds,decreasing=TRUE)][1]
wt 
0.7528328 

如果你的数据帧是DF,

regs <- list()
for (v in setdiff(names(DF), "y")) {
fm <- eval(parse(text = sprintf("y ~ %s", v)))
regs[[v]] <- lm(fm, data=DF)
}

现在你在regs列表中有了所有简单的回归结果。

的例子:

## Generate data
n <- 1000
set.seed(1)
DF <- data.frame(y = rnorm(n))
for (j in seq(400)) DF[[paste0('x',j)]] <- rnorm(n)
## Now data ready
dim(DF)
# [1] 1000 401
head(names(DF))
# [1] "y"  "x1" "x2" "x3" "x4" "x5"
tail(names(DF))
# [1] "x395" "x396" "x397" "x398" "x399" "x400"
regs <- list()
for (v in setdiff(names(DF), "y")) {
fm <- eval(parse(text = sprintf("y ~ %s", v)))
regs[[v]] <- lm(fm, data=DF)
}
head(names(regs))
# [1] "x1" "x2" "x3" "x4" "x5" "x6"
r2s <- sapply(regs, function(x) summary(x)$r.squared)
head(r2s, 3)
#           x1           x2           x3 
# 0.0000409755 0.0024376111 0.0005509134 

如果您想将它们分别包含在模型中,您可以只遍历x变量并在每次迭代中将它们添加到模型中。例如:

x_variables = list("x_var1", "x_var2", "x_var3", "x_var4", ...)
for(x in x_variables){
model <- lm(y_variable ~ x, data = df)
summary(model)
}

可以用所有其他x变量填充上面代码中的省略号。为了您的缘故,我希望您可以利用某种命名约定来使用dplyr谓词(如starts_withcontains)选择变量!

如果您希望在同一模型中包含所有x变量,只需像往常一样将它们添加进去。例如(假设您想使用OLS,但同样的前提也适用于其他类型):

model <- lm(y_variable ~ 
x_var1, x_var2, x_var3, x_var4, ..., data = df)
summary(model)

最新更新