如何运行 lm regression for every column in R

how to run lm regression for every column in R

我的数据框为:

df=data.frame(x=rnorm(100),y1=rnorm(100),y2=rnorm(100),y3=...)

我想要运行一个循环,从第一列的第二列开始回归每一列:

for(i in names(df[,-1])){
    model = lm(i~x, data=df)
}

但是我失败了。关键是我想为每一列做一个回归循环,有些列名只是一个数字(例如 404.1)。我找不到使用上述命令为每一列 运行 循环的方法。

您的代码看起来不错,除非您在 lm 中调用 i,R 会将 i 读取为一个字符串,您无法对其进行回归。使用 get 将允许您拉取与 i.

对应的列
df=data.frame(x=rnorm(100),y1=rnorm(100),y2=rnorm(100),y3=rnorm(100))

storage <- list()
for(i in names(df)[-1]){
  storage[[i]] <- lm(get(i) ~ x, df)
}

我创建了一个空列表 storage,我将在循环的每次迭代中填充它。这只是个人喜好,但我也反对您如何编写当前循环:

 for(i in names(df[,-1])){
    model = lm(i~x, data=df)
}

您将覆盖 model,从而仅返回最后一次迭代结果。我建议你把它改成一个列表,或者一个可以迭代存储结果的矩阵。

希望对您有所帮助

另一个使用 broom 和 tidyverse 的解决方案:

library(tidyverse)
library(broom)
df <- data.frame(x=rnorm(100),y1=rnorm(100),y2=rnorm(100))

result <- df %>% 
  gather(measure, value, -x) %>%
  nest(-measure) %>%
  mutate(fit = map(data, ~ lm(value ~ x, data = .x)),
         tidied = map(fit, tidy)) %>%
  unnest(tidied)
library(tidyverse)
df <- data.frame(x=rnorm(100),y1=rnorm(100),y2=rnorm(100))

head(df) 你会看到

       x          y1          y2
1 -0.8955473  0.96571502 -0.16232461
2  0.5054406 -2.74246178 -0.18120499
3  0.1680144 -0.06316372 -0.53614623
4  0.2956123  0.94223922  0.38358329
5  1.1425223  0.43150919 -0.32185672
6 -0.3457060 -1.16637706 -0.06561134 
models <- df %>% 
  pivot_longer(
    cols = starts_with("y"),
    names_to = "y_name",
    values_to = "y_value"
  ) 

之后,head(models),你会得到

       x y_name y_value
   <dbl> <chr>    <dbl>
1 -0.896 y1      0.966 
2 -0.896 y2     -0.162 
3  0.505 y1     -2.74  
4  0.505 y2     -0.181 
5  0.168 y1     -0.0632
6  0.168 y2     -0.536 

split(.$y_name)会将所有数据按y_name的不同层级进行拆分,对于每一部分数据,它们都会做同样的功能split(map(~lm(y_value ~ x, data = .))

在此之后,head(models)你会得到

$y1

Call:
lm(formula = y_value ~ x, data = .)

Coefficients:
(Intercept)            x  
    0.14924      0.08237  


$y2

Call:
lm(formula = y_value ~ x, data = .)

Coefficients:
(Intercept)            x  
    0.11183      0.03141  

如果你想整理你的结果,你可以做以下事情:

  tibble(
    dvsub = names(.),
    untidied = .
    ) %>%
  mutate(tidy = map(untidied, broom::tidy)) %>%
  unnest(tidy) 

然后你会得到 View(models) 这样的:

  dvsub untidied     term        estimate std.error statistic p.value
  <chr> <named list> <chr>          <dbl>     <dbl>     <dbl>   <dbl>
1 y1    <lm>         (Intercept)   0.0367    0.0939     0.391   0.697
2 y1    <lm>         x             0.0399    0.0965     0.413   0.680
3 y2    <lm>         (Intercept)   0.0604    0.109      0.553   0.582
4 y2    <lm>         x            -0.0630    0.112     -0.561   0.576

所以整个代码如下:

models <- df %>% 
  pivot_longer(
    cols = starts_with("y"),
    names_to = "y_name",
    values_to = "y_value"
  ) %>%
  split(.$y_name) %>%
  map(~lm(y_value ~ x, data = .)) %>%
  tibble(
    dvsub = names(.),
    untidied = .
    ) %>%
  mutate(tidy = map(untidied, broom::tidy)) %>%
  unnest(tidy) 

通用 R 解决方案:

lapply(df[, -1], function(y) {
  lm(y ~ df$x)
})