如何运行 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)
})
我的数据框为:
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)
})