«Многоступенчатая» регрессия с метлой и dplyr в R

#r #dplyr #regression #tidyr #broom

#r #dplyr #регрессия #тидир #метла

Вопрос:

Я ищу способ выполнить «многоступенчатую» регрессию с помощью broom и dplyr в R. Я использую «многоступенчатую» в качестве заполнителя для регрессионного анализа, в котором вы интегрируете в окончательную регрессионную модель элементы предыдущих регрессионных моделей, такие как подгонка или остатки. Примером такой «многоступенчатой» регрессии может служить подход 2SLS для регрессии инструментальной переменной (IV).

Мои (сгруппированные) данные выглядят следующим образом:

 df lt;- 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) )  

где id и group являются идентификаторами, y зависимой переменной, в то время x z1 как и z2 являются предикторами. В условиях внутривенного введения x это было бы эндогенным предиктором.

Вот пример «многоступенчатой» регрессии:

 library(tidyverse) library(broom)  # Nest the data frame df_nested lt;- df %gt;%   group_by(group) %gt;%   nest()  # Run first stage regression and retrieve residuals df_fit lt;- df_nested %gt;%   mutate(  fit1 = map(data, ~ lm(x ~ z1   z2, data = .x)),  resids = map(fit1, residuals)   )  # Run second stage with residuals as control variable df_fit %gt;%   mutate(  fit2 = map2(data, resids, ~ tidy(lm(y ~ x   z2   .y["resids"], data = .x)))  ) %gt;%   unnest(fit2)  

Это приводит к ошибке, которая указывает на то, что .x и .y имеют разную длину. Каково решение для интеграции остатков, в этой попытке .y[«проживает»], во вторую регрессию в качестве контрольной переменной?

Ответ №1:

Одним из вариантов достижения желаемого результата было бы добавить остатки в виде нового столбца в ваш фрейм данных после регрессии первого этапа:

 library(tidyverse) library(broom)  # Nest the data frame df_nested lt;- df %gt;%   group_by(group) %gt;%   nest()  # Run first stage regression and retrieve residuals df_fit lt;- df_nested %gt;%   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 %gt;%   mutate(  fit2 = map(data, ~ tidy(lm(y ~ x   z2   resids, data = .x)))  ) %gt;%   unnest(fit2) #gt; # A tibble: 16 × 9 #gt; # Groups: group [4] #gt; group data fit1 resids term estimate std.error statistic p.value #gt; lt;dblgt; lt;listgt; lt;listgt; lt;listgt; lt;chrgt; lt;dblgt; lt;dblgt; lt;dblgt; lt;dblgt; #gt; 1 1 lt;tibble [2… lt;lmgt; lt;dbl [… (Inter… 0.402 0.524 0.767 0.451  #gt; 2 1 lt;tibble [2… lt;lmgt; lt;dbl [… x 0.0836 0.912 0.0917 0.928  #gt; 3 1 lt;tibble [2… lt;lmgt; lt;dbl [… z2 0.161 0.250 0.644 0.527  #gt; 4 1 lt;tibble [2… lt;lmgt; lt;dbl [… resids -0.0536 0.942 -0.0569 0.955  #gt; 5 2 lt;tibble [2… lt;lmgt; lt;dbl [… (Inter… 0.977 0.273 3.58 0.00175 #gt; 6 2 lt;tibble [2… lt;lmgt; lt;dbl [… x -0.561 0.459 -1.22 0.235  #gt; 7 2 lt;tibble [2… lt;lmgt; lt;dbl [… z2 -0.351 0.192 -1.82 0.0826  #gt; 8 2 lt;tibble [2… lt;lmgt; lt;dbl [… resids 0.721 0.507 1.42 0.170  #gt; 9 3 lt;tibble [2… lt;lmgt; lt;dbl [… (Inter… -0.710 1.19 -0.598 0.556  #gt; 10 3 lt;tibble [2… lt;lmgt; lt;dbl [… x 3.61 3.80 0.951 0.352  #gt; 11 3 lt;tibble [2… lt;lmgt; lt;dbl [… z2 -1.21 1.19 -1.01 0.323  #gt; 12 3 lt;tibble [2… lt;lmgt; lt;dbl [… resids -3.67 3.80 -0.964 0.346  #gt; 13 4 lt;tibble [2… lt;lmgt; lt;dbl [… (Inter… 59.6 40.1 1.49 0.152  #gt; 14 4 lt;tibble [2… lt;lmgt; lt;dbl [… x -83.4 56.5 -1.48 0.155  #gt; 15 4 lt;tibble [2… lt;lmgt; lt;dbl [… z2 -18.7 12.8 -1.45 0.160  #gt; 16 4 lt;tibble [2… lt;lmgt; lt;dbl [… resids 83.4 56.5 1.48 0.155