r - 对 df 中的每个预测变量使用 purrr 映射进行多个线性回归

标签 r regression tidyverse purrr broom

我正在尝试使用一个 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

这与我要找的很接近,但不完全是!我希望变量名称位于此处的“术语”列中,我不希望为每个模型粘贴截距。我正在寻找的结果更像:

# 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:“手动”构建和计算表达式

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

关于r - 对 df 中的每个预测变量使用 purrr 映射进行多个线性回归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61793547/

相关文章:

r - R 中包含不相等的数字和文本混合的单独列

r - 在向 tibble 添加新列时使用动态命名

r - 在 R 中使用 ggplot 绘制意大利面条图?

r - 检测 R 中字符串的一部分(不完全匹配)

regression - 使用 GLM 进行逻辑回归

python - 高斯过程 scikit-learn - 异常

python - 如何在 scikit learn 中绘制多元回归的最佳拟合平面?

r - 匹配两个向量并在字符串中替换

Flexdashboard OCR 中的 R Shiny 繁忙旋转器

r - 如何使用管道来使用对象的一部分