Передавать строки из фрейма данных в качестве аргументов в пользовательскую функцию регрессии, используя dplyr / purrr - PullRequest
1 голос
/ 22 июня 2019

Я пишу регрессионную функцию, которая может принимать несколько аргументов (я привожу здесь только 3 аргумента для простоты, но их будет десятки).В конечном итоге я хочу передать все возможные комбинации аргументов в функцию регрессии и собрать оценки из моделей.Поэтому я сначала создам полный набор комбинаций, используя cross_df, а затем перебираю каждую строку результирующего кадра данных, где каждая строка содержит набор аргументов для передачи в пользовательскую функцию регрессии (один аргумент на столбец).Затем в кадре данных я хочу создать два новых столбца: один с оценочным коэффициентом для независимой переменной и один со связанным значением p.

Вот что я пробовал:

rm(list = ls())
library(DeclareDesign)
library(tidyverse)

set.seed(12345)

df <- fabricate(N = 100,
                oneDV = rnorm(N),
                anotherDV = draw_binary(prob = 0.5, N),
                X = draw_binary(prob = 0.5, N),
                M = rnorm(N))


myreg <- function(DV = NULL,
                  control = FALSE,
                  subset = FALSE) {

  dat <- df

  # declare dv
    dv <- DV

 if(subset) {
  dat %>% filter(M < median(M))} else {
  dat <- dat
  }  

  # controls
    if(control) {
      cntr <- "+ M"} else {
      cntr <- ""
      }

  # decalare formula
    frm <- paste0(dv, "~ X", cntr)
    out <- lm_robust(as.formula(frm), data = df)
    out$coef <- as.vector(out$coefficients[2])
    out$pval <- as.vector(out$p.value[2])

    return(out)
}

args <- list(
  DV = c("oneDV", "anotherDV"),
  control = c(T,F),
  double = c(T,F))

args %>% 
  purrr::cross_df() %>% 
  mutate(coef = myreg(DV, control, subset)$coef,
         pval = myreg(DV, control, subset)$pval)

Как вы можете видеть, это не зацикливается на каждой строке, как я хочу - один и тот же результат показан для каждой строки, даже если каждая строка должна представлять отдельную модель (8 различных вэтот пример).Что я делаю не так?

1 Ответ

1 голос
/ 22 июня 2019

Использование map2_dbl:

library(tidyverse)

args %>% 
    purrr::cross_df() %>% 
    mutate(coef = map2_dbl(DV, control, ~myreg(.x, .y)$coef), 
           pval = map2_dbl(DV, control, ~myreg(.x, .y)$pval))

#> # A tibble: 4 x 4
#>   DV        control   coef  pval
#>   <chr>     <lgl>    <dbl> <dbl>
#> 1 oneDV     TRUE    0.120  0.569
#> 2 anotherDV TRUE    0.0957 0.354
#> 3 oneDV     FALSE   0.163  0.437
#> 4 anotherDV FALSE   0.0833 0.408

Создано в 2019-06-21 пакетом Представления (v0.3.0)

Использование pmap с более чем 2 аргументами:

args %>% 
    purrr::cross_df() %>% 
    mutate(mod = pmap(., myreg), 
           coef = map_dbl(mod, ~.x$coef), 
           pval = map_dbl(mod, ~.x$pval))

#> # A tibble: 8 x 6
#>   DV        control subset mod           coef  pval
#>   <chr>     <lgl>   <lgl>  <list>       <dbl> <dbl>
#> 1 oneDV     TRUE    TRUE   <lm_robst> -0.0917 0.678
#> 2 anotherDV TRUE    TRUE   <lm_robst> -0.0404 0.693
#> 3 oneDV     FALSE   TRUE   <lm_robst> -0.0825 0.706
#> 4 anotherDV FALSE   TRUE   <lm_robst> -0.0369 0.717
#> 5 oneDV     TRUE    FALSE  <lm_robst> -0.0917 0.678
#> 6 anotherDV TRUE    FALSE  <lm_robst> -0.0404 0.693
#> 7 oneDV     FALSE   FALSE  <lm_robst> -0.0825 0.706
#> 8 anotherDV FALSE   FALSE  <lm_robst> -0.0369 0.717

Создано в 2019-06-22 пакетом Представление (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...