te time
te time

Reputation: 495

row bind list columns using dplyr

I would like to find a better way to bind together the results of any number of regressions after adding an identifier for each model. The code below is my current solution but is too manual for a large number of regressions. This is part of a larger tidy workflow so a solution inside of the tidyverse is preferred but whatever works is fine. Thanks

library(tidyverse)
library(broom)

model_dat=mtcars %>% 
do(lm_1 = tidy(lm(disp~ wt*vs, data = .),conf.int=T),
   lm_2=tidy(lm(cyl ~ wt*vs, data = .),conf.int=T ),
   lm_3=tidy(lm(mpg ~ wt*vs, data = .),conf.int=T ))
df=model_dat %>%
    select(lm_1) %>%
    unnest(c(lm_1)) %>%
    mutate(model="one") %>% 
    select(model,term,estimate,p.value:conf.high) %>%
    bind_rows(
        model_dat %>% 
            select(lm_2) %>% 
            unnest(c(lm_2)) %>% 
            mutate(model="two") %>% 
            select(model,term,estimate,p.value:conf.high)) %>%
    bind_rows(
        model_dat %>% 
            select(lm_3) %>% 
            unnest(c(lm_3)) %>% 
            mutate(model="three") %>% 
            select(model,term,estimate,p.value:conf.high))

Upvotes: 1

Views: 239

Answers (1)

akrun
akrun

Reputation: 887951

It may be easier with map2 i.e. loop across the columns and the corresponding english word for the sequence of columns, pluck the list element, create the 'model' column with second argument i.e. engish words (.y), select the columns of interest, and create a single dataset by specifying _dfr in map

library(purrr)
library(english)
library(dplyr)
library(broom)
map2_dfr(model_dat, as.character(english(seq_along(model_dat))), 
      ~ .x  %>% 
           pluck(1) %>%
           mutate(model = .y) %>% 
           select(model, term, estimate, p.value:conf.high) )

-output

# A tibble: 12 x 6
#   model term        estimate  p.value conf.low conf.high
#   <chr> <chr>          <dbl>    <dbl>    <dbl>     <dbl>
# 1 one   (Intercept) -70.0    1.55e- 1 -168.       28.2  
# 2 one   wt          102.     8.20e- 9   76.4     128.   
# 3 one   vs           31.2    6.54e- 1 -110.      172.   
# 4 one   wt:vs       -36.7    1.10e- 1  -82.2       8.82 
# 5 two   (Intercept)   4.31   1.28e- 5    2.64      5.99 
# 6 two   wt            0.849  4.90e- 4    0.408     1.29 
# 7 two   vs           -2.19   7.28e- 2   -4.59      0.216
# 8 two   wt:vs         0.0869 8.20e- 1   -0.689     0.862
# 9 three (Intercept)  29.5    6.55e-12   24.2      34.9  
#10 three wt           -3.50   2.33e- 5   -4.92     -2.08 
#11 three vs           11.8    4.10e- 3    4.06     19.5  
#12 three wt:vs        -2.91   2.36e- 2   -5.40     -0.419

Or use summarise with across, unclass and then bind with bind_rows

model_dat %>% 
       summarise(across(everything(), ~ {
         # // get the column name
         nm1 <- cur_column()
         # // extract the list element (.[[1]])
         list(.[[1]] %>% 
            # // create new column by extracting the numeric part
            mutate(model = english(readr::parse_number(nm1))) %>%
            # // select the subset of columns, wrap in a list
            select(model, term, estimate, p.value:conf.high))
         }
         )) %>%
        # // unclass to list
        unclass %>%
        # // bind the list elements
        bind_rows

-output

# A tibble: 12 x 6
#   model     term        estimate  p.value conf.low conf.high
#   <english> <chr>          <dbl>    <dbl>    <dbl>     <dbl>
# 1 one       (Intercept) -70.0    1.55e- 1 -168.       28.2  
# 2 one       wt          102.     8.20e- 9   76.4     128.   
# 3 one       vs           31.2    6.54e- 1 -110.      172.   
# 4 one       wt:vs       -36.7    1.10e- 1  -82.2       8.82 
# 5 two       (Intercept)   4.31   1.28e- 5    2.64      5.99 
# 6 two       wt            0.849  4.90e- 4    0.408     1.29 
# 7 two       vs           -2.19   7.28e- 2   -4.59      0.216
# 8 two       wt:vs         0.0869 8.20e- 1   -0.689     0.862
# 9 three     (Intercept)  29.5    6.55e-12   24.2      34.9  
#10 three     wt           -3.50   2.33e- 5   -4.92     -2.08 
#11 three     vs           11.8    4.10e- 3    4.06     19.5  
#12 three     wt:vs        -2.91   2.36e- 2   -5.40     -0.419

Upvotes: 4

Related Questions