对 df 中的每个预测变量使用 purrr 映射进行多个线性回归
Using purrr map for several linear regressions for each predictor in df
我正在尝试 运行 许多具有一个 Y 变量和许多 x 变量的单独线性回归。我的数据有 300 多个 x 变量。我一直在尝试用 purrr 和 broom 来做到这一点,但无法弄清楚如何获得我想要的输出。
示例:
iris <- iris %>%
select_if(is.numeric)
iris %>%
map(~lm(Sepal.Length ~ .x, data = iris)) %>%
map(summary) %>%
map_df(tidy)
这会产生以下输出:
# A tibble: 6 x 5
term estimate std.error statistic p.value
<chr> <dbl> <dbl> <dbl> <dbl>
1 (Intercept) 0 3.79e-17 0. 1.00e+ 0
2 .x 1 6.43e-18 1.56e17 0.
3 (Intercept) 6.53 4.79e- 1 1.36e 1 6.47e- 28
4 .x -0.223 1.55e- 1 -1.44e 0 1.52e- 1
5 (Intercept) 4.31 7.84e- 2 5.49e 1 2.43e-100
6 .x 0.409 1.89e- 2 2.16e 1 1.04e- 47
这与我要找的很接近,但不完全是!我希望变量名称位于此处的 'term' 列中,我不希望为每个模型粘贴截距。我正在寻找更像的结果:
# A tibble: 6 x 5
term estimate std.error statistic p.value
<chr> <dbl> <dbl> <dbl> <dbl>
1 Sepal.Width 0 3.79e-17 0. 1.00e+ 0
2 Petal.Width 1 6.43e-18 1.56e17 0.
3 Petal.Length 6.53 4.79e- 1 1.36e 1 6.47e- 28
对于达到这一点的任何帮助将不胜感激!!当然还要特别感谢对过程的解释(我正在学习)
干杯
lm()
遵循一组称为非标准求值的特殊规则,它在计算中使用部分表达式。这是一个显示差异的简单示例:
a <- "purrr"
print(a) # Standard evaluation - expression a is evaluated to its value
# [1] "purrr"
library(a) # Non-standard evaluation - expression a is used as-is
# Error in library(a) : there is no package called ‘a’
类似地,lm()
使用表达式 Sepal.Length ~ .x
的一部分,这就是为什么您在输出中看到 .x
,而不是 map()
放入 .x
。这里有几个选项可以解决这个问题。
选项 1:构造和计算表达式 "by hand"
colnames(iris) %>% # Start with all column names
setdiff( "Sepal.Length" ) %>% # ...that are not Sepal.Length
rlang::syms() %>% # Convert them to symbols
map( ~rlang::expr(lm(Sepal.Length ~ !!.x,
data=iris)) ) %>% # Create expressions
map( eval.parent ) %>% # Evaluate expressions
map( broom::tidy ) %>% # Tidy up the output
bind_rows() %>% # Combine into a single data frame
filter( term != "(Intercept)" ) # Drop all (Intercept) entries
在这里,!!.x
将用存储在其中的符号替换 .x
。此 map()
步骤的输出将是一组看起来与您想要的完全一样的表达式:
lm(Sepal.Length ~ Sepal.Width, data = iris)
lm(Sepal.Length ~ Petal.Length, data = iris)
lm(Sepal.Length ~ Petal.Width, data = iris)
选项 2:自己注释行
iris %>%
select( -Sepal.Length ) %>%
map( ~lm(Sepal.Length ~ .x, data=iris) ) %>% # As before
map( broom::tidy ) %>% # Tidy up the output
map( filter, term != "(Intercept)" ) %>% # Remove (Intercept) entries
map( select, -term ) %>% # Remove the default term column
bind_rows( .id="term" ) # Make your own from the list names
我正在尝试 运行 许多具有一个 Y 变量和许多 x 变量的单独线性回归。我的数据有 300 多个 x 变量。我一直在尝试用 purrr 和 broom 来做到这一点,但无法弄清楚如何获得我想要的输出。
示例:
iris <- iris %>%
select_if(is.numeric)
iris %>%
map(~lm(Sepal.Length ~ .x, data = iris)) %>%
map(summary) %>%
map_df(tidy)
这会产生以下输出:
# A tibble: 6 x 5
term estimate std.error statistic p.value
<chr> <dbl> <dbl> <dbl> <dbl>
1 (Intercept) 0 3.79e-17 0. 1.00e+ 0
2 .x 1 6.43e-18 1.56e17 0.
3 (Intercept) 6.53 4.79e- 1 1.36e 1 6.47e- 28
4 .x -0.223 1.55e- 1 -1.44e 0 1.52e- 1
5 (Intercept) 4.31 7.84e- 2 5.49e 1 2.43e-100
6 .x 0.409 1.89e- 2 2.16e 1 1.04e- 47
这与我要找的很接近,但不完全是!我希望变量名称位于此处的 'term' 列中,我不希望为每个模型粘贴截距。我正在寻找更像的结果:
# A tibble: 6 x 5
term estimate std.error statistic p.value
<chr> <dbl> <dbl> <dbl> <dbl>
1 Sepal.Width 0 3.79e-17 0. 1.00e+ 0
2 Petal.Width 1 6.43e-18 1.56e17 0.
3 Petal.Length 6.53 4.79e- 1 1.36e 1 6.47e- 28
对于达到这一点的任何帮助将不胜感激!!当然还要特别感谢对过程的解释(我正在学习)
干杯
lm()
遵循一组称为非标准求值的特殊规则,它在计算中使用部分表达式。这是一个显示差异的简单示例:
a <- "purrr"
print(a) # Standard evaluation - expression a is evaluated to its value
# [1] "purrr"
library(a) # Non-standard evaluation - expression a is used as-is
# Error in library(a) : there is no package called ‘a’
类似地,lm()
使用表达式 Sepal.Length ~ .x
的一部分,这就是为什么您在输出中看到 .x
,而不是 map()
放入 .x
。这里有几个选项可以解决这个问题。
选项 1:构造和计算表达式 "by hand"
colnames(iris) %>% # Start with all column names
setdiff( "Sepal.Length" ) %>% # ...that are not Sepal.Length
rlang::syms() %>% # Convert them to symbols
map( ~rlang::expr(lm(Sepal.Length ~ !!.x,
data=iris)) ) %>% # Create expressions
map( eval.parent ) %>% # Evaluate expressions
map( broom::tidy ) %>% # Tidy up the output
bind_rows() %>% # Combine into a single data frame
filter( term != "(Intercept)" ) # Drop all (Intercept) entries
在这里,!!.x
将用存储在其中的符号替换 .x
。此 map()
步骤的输出将是一组看起来与您想要的完全一样的表达式:
lm(Sepal.Length ~ Sepal.Width, data = iris)
lm(Sepal.Length ~ Petal.Length, data = iris)
lm(Sepal.Length ~ Petal.Width, data = iris)
选项 2:自己注释行
iris %>%
select( -Sepal.Length ) %>%
map( ~lm(Sepal.Length ~ .x, data=iris) ) %>% # As before
map( broom::tidy ) %>% # Tidy up the output
map( filter, term != "(Intercept)" ) %>% # Remove (Intercept) entries
map( select, -term ) %>% # Remove the default term column
bind_rows( .id="term" ) # Make your own from the list names