Как использовать purrr для перебора каждой комбинации ковариат и результатов в lm reg

#r #purrr #lm

Вопрос:

Общий для меня сценарий заключается в том, что мне нужно запустить в основном одну и ту же регрессионную модель, но с различными результатами, и для анализа чувствительности мне одновременно нужно повторять различные наборы ковариат.

Я все еще новичок в R, но, используя приведенное ниже с помощью purrr, я могу повторять результаты и ковариаты, но, конечно, он проходит параллельно через пары списков, когда мне нужно, чтобы он прошел через каждую комбинацию из каждого списка.

Каковы некоторые варианты того, как повторять все комбинации результатов и ковариат?

Кроме того, кто-нибудь знает, почему приведенный ниже код не будет работать с «map2»? Я получаю сообщение об ошибке «as_mapper(.f, …) : аргумент «.f» отсутствует, по умолчанию отсутствует»

 library(dplyr)
library(purrr)

dataset <- tibble(
    y1=rnorm(n=100),
    y2=rnorm(n=100),
    x1=rnorm(n=100),
    x2=rnorm(n=100))


outcomes <- dataset %>%
    select(y1,y2)

covars <- dataset %>%
    select(x1,x2)

paramlist <- list(covarL,outcomeL)

paramlist %>%
    pmap(~lm(.y ~ .x,data=dataset))
 

Комментарии:

1. dplyr::expand_grid ?

Ответ №1:

Есть много способов сделать это в более широкой области наведения порядка. Я являюсь поклонником dplyr::rowwise такого рода расчетов. Мы можем использовать colnames вместо фактических данных, а затем создать матрицу, подобную tibble tidyr::expand_grid той, которая содержит все комбинации результатов и коваров. Тогда мы можем использовать dplyr::rowwise и использовать lm inside list() вместе с reformulate которым принимает строки в качестве входных данных. Чтобы получить результат, мы можем использовать broom::tidy .

 library(dplyr)
library(purrr)
library(tidyr)

dataset <- tibble(
  y1=rnorm(n=100),
  y2=rnorm(n=100),
  x1=rnorm(n=100),
  x2=rnorm(n=100))

outcomes <- dataset %>%
  select(y1,y2) %>% colnames

covars <- dataset %>%
  select(x1,x2) %>% colnames

paramlist <- expand_grid(outcomes, covars)

paramlist %>%
  rowwise %>% 
  mutate(mod = list(lm(reformulate(outcomes, covars), data = dataset)),
         res = list(broom::tidy(mod)))

#> # A tibble: 4 x 4
#> # Rowwise: 
#>   outcomes covars mod    res             
#>   <chr>    <chr>  <list> <list>          
#> 1 y1       x1     <lm>   <tibble [2 x 5]>
#> 2 y1       x2     <lm>   <tibble [2 x 5]>
#> 3 y2       x1     <lm>   <tibble [2 x 5]>
#> 4 y2       x2     <lm>   <tibble [2 x 5]>
 

Создано 2021-09-06 пакетом reprex (v2.0.1)

Мы можем сделать то же самое с {мурррр} вместо dplyr::rowwise :

 paramlist %>% 
  mutate(mod = map2(outcomes, covars, ~ lm(reformulate(.y, .x), data = dataset)),
         res = map(mod, broom::tidy)) 

#> # A tibble: 4 x 4
#>   outcomes covars mod    res             
#>   <chr>    <chr>  <list> <list>          
#> 1 y1       x1     <lm>   <tibble [2 x 5]>
#> 2 y1       x2     <lm>   <tibble [2 x 5]>
#> 3 y2       x1     <lm>   <tibble [2 x 5]>
#> 4 y2       x2     <lm>   <tibble [2 x 5]>
 

Создано 2021-09-06 пакетом reprex (v2.0.1)

Другим чистым решением {purrr} является использование вложенного map вызова. Поскольку он вложен, нам нужны flatten результаты, прежде чем мы сможем map(summary) их использовать.

 # outcomes and covars are the same strings as above

outcomes %>% 
  map(~ map(covars, function(.y) lm(reformulate(.y, .x), data = dataset))) %>% 
  flatten %>% 
  map(summary)

#> [[1]]
#> 
#> Call:
#> lm(formula = reformulate(.y, .x), data = dataset)
#> 
#> Residuals:
#>      Min       1Q   Median       3Q      Max 
#> -2.20892 -0.56744 -0.08498  0.55445  2.10146 
#> 
#> Coefficients:
#>               Estimate Std. Error t value Pr(>|t|)
#> (Intercept) -0.0009328  0.0923062  -0.010    0.992
#> x1          -0.0809739  0.0932059  -0.869    0.387
#> 
#> Residual standard error: 0.9173 on 98 degrees of freedom
#> Multiple R-squared:  0.007643,   Adjusted R-squared:  -0.002483 
#> F-statistic: 0.7548 on 1 and 98 DF,  p-value: 0.3871
#> 
#> 
#> [[2]]
#> 
#> Call:
#> lm(formula = reformulate(.y, .x), data = dataset)
#> 
#> Residuals:
#>      Min       1Q   Median       3Q      Max 
#> -2.11442 -0.59186 -0.08153  0.61642  2.10575 
#> 
#> Coefficients:
#>             Estimate Std. Error t value Pr(>|t|)
#> (Intercept) -0.02048    0.09461  -0.216    0.829
#> x2          -0.05159    0.10805  -0.477    0.634
#> 
#> Residual standard error: 0.9197 on 98 degrees of freedom
#> Multiple R-squared:  0.002321,   Adjusted R-squared:  -0.007859 
#> F-statistic: 0.228 on 1 and 98 DF,  p-value: 0.6341
#> 
#> 
#> [[3]]
#> 
#> Call:
#> lm(formula = reformulate(.y, .x), data = dataset)
#> 
#> Residuals:
#>     Min      1Q  Median      3Q     Max 
#> -2.3535 -0.7389 -0.2023  0.6236  3.8627 
#> 
#> Coefficients:
#>             Estimate Std. Error t value Pr(>|t|)
#> (Intercept) -0.08178    0.10659  -0.767    0.445
#> x1          -0.08476    0.10763  -0.788    0.433
#> 
#> Residual standard error: 1.059 on 98 degrees of freedom
#> Multiple R-squared:  0.006289,   Adjusted R-squared:  -0.003851 
#> F-statistic: 0.6202 on 1 and 98 DF,  p-value: 0.4329
#> 
#> 
#> [[4]]
#> 
#> Call:
#> lm(formula = reformulate(.y, .x), data = dataset)
#> 
#> Residuals:
#>     Min      1Q  Median      3Q     Max 
#> -2.4867 -0.7020 -0.1935  0.5869  3.7574 
#> 
#> Coefficients:
#>             Estimate Std. Error t value Pr(>|t|)
#> (Intercept) -0.06575    0.10875  -0.605    0.547
#> x2           0.12388    0.12420   0.997    0.321
#> 
#> Residual standard error: 1.057 on 98 degrees of freedom
#> Multiple R-squared:  0.01005,    Adjusted R-squared:  -5.162e-05 
#> F-statistic: 0.9949 on 1 and 98 DF,  p-value: 0.321
 

Создано 2021-09-06 пакетом reprex (v2.0.1)