R 中具有多个 x 变量和一个 y 变量的简单线性回归。只写一个模型而不是每个 x 和 y 组合?
Simple linear regression in R with many x varibales and one y. Only write one model and not for each x and y combination?
我想针对一个 y 变量(1 个变量)分析许多 x 变量(400 个变量)。但是我不想为每个 x 变量编写一个新模型。是否可以编写一个模型,而不是在 R-Studio 中用 y 检查所有 x 变量?
如果您想将它们分别包含在模型中,您可以循环遍历 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 变量填充上面代码中的省略号。为了您的利益,我希望有某种命名约定,您可以使用 starts_with
或 contains
!
等 dplyr 动词来利用 select 变量
如果您希望在同一个模型中包含所有 x 变量,您只需像往常一样添加它们。例如(假设您想使用 OLS,但同样的前提也适用于其他类型):
model <- lm(y_variable ~
x_var1, x_var2, x_var3, x_var4, ..., data = df)
summary(model)
这是一种方法,我们使用一个函数对数据框中的所有变量进行回归,该因变量来自作为参数传递给函数的同一数据框。
我们使用lapply()
来驱动lm()
,因为它将return生成的模型对象作为一个列表,我们可以很容易地命名生成的列表,这样我们就可以提取模型按自变量名称。
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()
中使我们能够执行类似查找具有最高 R^2 的模型的操作,而无需使用 vgrep.
首先,我们从每个模型摘要中提取 r.squared
值并将结果保存到向量中。
r.squareds <- unlist(lapply(modelList,function(x) summary(x)$r.squared))
因为我们使用names()
来命名原始列表中的元素,R 会自动将变量名称保存到向量的元素名称中。当我们按 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
我想针对一个 y 变量(1 个变量)分析许多 x 变量(400 个变量)。但是我不想为每个 x 变量编写一个新模型。是否可以编写一个模型,而不是在 R-Studio 中用 y 检查所有 x 变量?
如果您想将它们分别包含在模型中,您可以循环遍历 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 变量填充上面代码中的省略号。为了您的利益,我希望有某种命名约定,您可以使用 starts_with
或 contains
!
如果您希望在同一个模型中包含所有 x 变量,您只需像往常一样添加它们。例如(假设您想使用 OLS,但同样的前提也适用于其他类型):
model <- lm(y_variable ~
x_var1, x_var2, x_var3, x_var4, ..., data = df)
summary(model)
这是一种方法,我们使用一个函数对数据框中的所有变量进行回归,该因变量来自作为参数传递给函数的同一数据框。
我们使用lapply()
来驱动lm()
,因为它将return生成的模型对象作为一个列表,我们可以很容易地命名生成的列表,这样我们就可以提取模型按自变量名称。
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()
中使我们能够执行类似查找具有最高 R^2 的模型的操作,而无需使用 vgrep.
首先,我们从每个模型摘要中提取 r.squared
值并将结果保存到向量中。
r.squareds <- unlist(lapply(modelList,function(x) summary(x)$r.squared))
因为我们使用names()
来命名原始列表中的元素,R 会自动将变量名称保存到向量的元素名称中。当我们按 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