在 R 中使用 broom 和 dplyr 进行“多步”回归

Posted

技术标签:

【中文标题】在 R 中使用 broom 和 dplyr 进行“多步”回归【英文标题】:"Multi-step" regression with broom and dplyr in R 【发布时间】:2022-01-14 02:53:21 【问题描述】:

我正在寻找一种在 R 中使用 broom 和 dplyr 执行“多步”回归的方法。我使用“多步”作为回归分析的占位符,您可以在其中集成先前回归的最终回归模型元素模型,例如拟合或残差。这种“多步”回归的一个例子是用于工具变量 (IV) 回归的 2SLS 方法。

我的(分组的)数据如下所示:

df <- data.frame(
  id = sort(rep(seq(1, 20, 1), 5)),
  group = rep(seq(1, 4, 1), 25),
  y = runif(100),
  x = runif(100),
  z1 = runif(100),
  z2 = runif(100)
)

其中idgroup 是标识符,y 是因变量,而xz1z2 是预测变量。在 IV 设置中,x 将是一个内生预测因子。

以下是“多步”回归的示例:

library(tidyverse)
library(broom)

# Nest the data frame
df_nested <- df %>% 
  group_by(group) %>% 
  nest()

# Run first stage regression and retrieve residuals
df_fit <- df_nested %>% 
  mutate(
    fit1 = map(data, ~ lm(x ~ z1 + z2, data = .x)),
    resids = map(fit1, residuals) 
  )

# Run second stage with residuals as control variable
df_fit %>% 
  mutate(
    fit2 = map2(data, resids, ~ tidy(lm(y ~ x + z2 + .y["resids"], data = .x)))
        ) %>% 
  unnest(fit2)

这会产生一个错误,表明 .x 和 .y 的长度不同。将残差(在此尝试中将 .y["resids"] 整合到第二个回归中作为控制变量的解决方案是什么?

【问题讨论】:

【参考方案1】:

实现所需结果的一个选项是在第一阶段回归后将残差作为新列添加到数据框中:

library(tidyverse)
library(broom)

# Nest the data frame
df_nested <- df %>% 
  group_by(group) %>% 
  nest()

# Run first stage regression and retrieve residuals
df_fit <- df_nested %>% 
  mutate(
    fit1 = map(data, ~ lm(x ~ z1 + z2, data = .x)),
    resids = map(fit1, residuals),
    data = map2(data, resids, ~ bind_cols(.x, resids = .y))
  )

# Run second stage with residuals as control variable
df_fit %>% 
  mutate(
    fit2 = map(data, ~ tidy(lm(y ~ x + z2 + resids, data = .x)))
  ) %>% 
  unnest(fit2)
#> # A tibble: 16 × 9
#> # Groups:   group [4]
#>    group data        fit1   resids  term    estimate std.error statistic p.value
#>    <dbl> <list>      <list> <list>  <chr>      <dbl>     <dbl>     <dbl>   <dbl>
#>  1     1 <tibble [2… <lm>   <dbl [… (Inter…   0.402      0.524    0.767  0.451  
#>  2     1 <tibble [2… <lm>   <dbl [… x         0.0836     0.912    0.0917 0.928  
#>  3     1 <tibble [2… <lm>   <dbl [… z2        0.161      0.250    0.644  0.527  
#>  4     1 <tibble [2… <lm>   <dbl [… resids   -0.0536     0.942   -0.0569 0.955  
#>  5     2 <tibble [2… <lm>   <dbl [… (Inter…   0.977      0.273    3.58   0.00175
#>  6     2 <tibble [2… <lm>   <dbl [… x        -0.561      0.459   -1.22   0.235  
#>  7     2 <tibble [2… <lm>   <dbl [… z2       -0.351      0.192   -1.82   0.0826 
#>  8     2 <tibble [2… <lm>   <dbl [… resids    0.721      0.507    1.42   0.170  
#>  9     3 <tibble [2… <lm>   <dbl [… (Inter…  -0.710      1.19    -0.598  0.556  
#> 10     3 <tibble [2… <lm>   <dbl [… x         3.61       3.80     0.951  0.352  
#> 11     3 <tibble [2… <lm>   <dbl [… z2       -1.21       1.19    -1.01   0.323  
#> 12     3 <tibble [2… <lm>   <dbl [… resids   -3.67       3.80    -0.964  0.346  
#> 13     4 <tibble [2… <lm>   <dbl [… (Inter…  59.6       40.1      1.49   0.152  
#> 14     4 <tibble [2… <lm>   <dbl [… x       -83.4       56.5     -1.48   0.155  
#> 15     4 <tibble [2… <lm>   <dbl [… z2      -18.7       12.8     -1.45   0.160  
#> 16     4 <tibble [2… <lm>   <dbl [… resids   83.4       56.5      1.48   0.155

【讨论】:

以上是关于在 R 中使用 broom 和 dplyr 进行“多步”回归的主要内容,如果未能解决你的问题,请参考以下文章

使用扫帚(增强)和dplyr与黄土适合时出错

使用 R 从预先指定的回归模型中获取残差

R语言broom包整洁化模型

R语言使用broom包将回归模型(线性回归逻辑回归比例风险回归)的结果整理成dataframe并导出到excel等文件中:基于mtcars和colon数据集

R与数据可视化系列如何使用dplyr进行数据清洗和变换

在 R 中使用 dplyr 进行过滤时,为啥过滤掉的变量级别会保留在过滤后的数据中? [复制]