在 R 中为数据集中的特定列循环线性回归
Posted
技术标签:
【中文标题】在 R 中为数据集中的特定列循环线性回归【英文标题】:Looping linear regression in R for specific columns in dataset 【发布时间】:2022-01-22 14:58:53 【问题描述】:我有以下数据集:
df <- data.frame(row_id = c(100, 101, 102, 103, 104, 105, 106, 107, 108, 109),
level = c(1000,2000,3000,4000,5000,6000,7000,8000,9000,10000),
col1 = c(1,0,1,1,1,0,0,1,1,0),
col2 = c(1,1,1,0,0,1,1,1,0,0),
col3 = c(0,0,1,0,0,1,1,1,1,0),
col4 = c(1,1,1,0,0,1,0,1,1,1),
col5 = c(1,1,1,0,1,0,1,0,0,1))
我想对变量level
与前缀为col
的其他每一列进行线性回归。我想使用 for 循环函数来执行此操作,而不是执行以下操作:
lm1<-lm(level~col1, data=df)
lm2<-lm(level~col2, data=df)
lm3<-lm(level~col3, data=df)
lm4<-lm(level~col4, data=df)
lm5<-lm(level~col5, data=df)
任何帮助将不胜感激,谢谢!
【问题讨论】:
这能回答你的问题吗? How to Loop/Repeat a Linear Regression in R 【参考方案1】:df <-
data.frame(
row_id = c(100, 101, 102, 103, 104, 105, 106, 107, 108, 109),
level = c(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000),
col1 = c(1, 0, 1, 1, 1, 0, 0, 1, 1, 0),
col2 = c(1, 1, 1, 0, 0, 1, 1, 1, 0, 0),
col3 = c(0, 0, 1, 0, 0, 1, 1, 1, 1, 0),
col4 = c(1, 1, 1, 0, 0, 1, 0, 1, 1, 1),
col5 = c(1, 1, 1, 0, 1, 0, 1, 0, 0, 1)
)
library(tidyverse)
VARS <- grep("^col", names(df), value = TRUE) %>%
set_names()
map(VARS, ~lm(reformulate(.x, "level"), data = df)) %>%
map(summary)
#> $col1
#>
#> Call:
#> lm(formula = reformulate(.x, "level"), data = df)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -4250 -1750 -125 2438 4000
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 6250 1569 3.984 0.00404 **
#> col1 -1250 2025 -0.617 0.55425
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 3137 on 8 degrees of freedom
#> Multiple R-squared: 0.04545, Adjusted R-squared: -0.07386
#> F-statistic: 0.381 on 1 and 8 DF, p-value: 0.5543
#>
#>
#> $col2
#>
#> Call:
#> lm(formula = reformulate(.x, "level"), data = df)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -3500 -2375 0 2375 3500
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 7000 1452 4.820 0.00132 **
#> col2 -2500 1875 -1.333 0.21914
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 2905 on 8 degrees of freedom
#> Multiple R-squared: 0.1818, Adjusted R-squared: 0.07955
#> F-statistic: 1.778 on 1 and 8 DF, p-value: 0.2191
#>
#> ...
由reprex package (v2.0.1) 于 2021 年 12 月 21 日创建
【讨论】:
【参考方案2】:如果您只对系数感兴趣,您可以通过重塑数据来做到这一点。您不需要 for 循环。标准误差估计会有一些限制。系数将是正确的:
lm(level~ind/values-1,cbind(df[1:2], stack(df, -(1:2))))
Call:
lm(formula = level ~ ind/values - 1, data = cbind(df[1:2], stack(df,
-(1:2))))
Coefficients:
indcol1 indcol2 indcol3 indcol4
6250.0 7000.0 4400.0 5333.3
indcol5 indcol1:values indcol2:values indcol3:values
6750.0 -1250.0 -2500.0 2200.0
indcol4:values indcol5:values
238.1 -2083.3
fhe 系数如下:Indcol1 是 col1 的截距,而 indcol1:values 是系数。
将此与您的结果进行比较
你也可以这样做:
lapply(df[-(1:2)], function(x)lm(df$level~x))
这样做的问题是你不知道变量名。
另一种方式:
lapply(names(df)[-(1:2)], function(x)lm(reformulate(x, 'level'), df))
【讨论】:
【参考方案3】:首先,我们需要一种方法来根据我们选择的变量创建一个公式。一种方法:
as.formula(paste0("level ~", var))
其中var
是类似"col1"
的变量。
现在我们只需要为每个模型创建循环。如果你想使用for
循环来做到这一点,你可以这样做:
models = list()
# Create a vector of the explanatory variables
variables = setdiff(names(df), c("row_id", "level"))
for (var in variables)
models[[var]] = lm(
as.formula(paste0("level ~ ", var)),
data = df
)
models
是一个包含每个模型的列表 - 例如,您可以通过 models$col3
使用 col3
访问模型:
> summary(models$col3)
Call:
lm(formula = as.formula(paste0("level ~ ", var)), data = df)
Residuals:
Min 1Q Median 3Q Max
-3600 -1950 0 1200 5600
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 4400 1327 3.317 0.0106 *
col3 2200 1876 1.173 0.2747
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 2966 on 8 degrees of freedom
Multiple R-squared: 0.1467, Adjusted R-squared: 0.04
F-statistic: 1.375 on 1 and 8 DF, p-value: 0.2747
随着需求变得越来越复杂,您可以对这种方法进行很多改进,但这是一个好的开始。
【讨论】:
以上是关于在 R 中为数据集中的特定列循环线性回归的主要内容,如果未能解决你的问题,请参考以下文章