9

How do I extract elements from a nested list only using the purrr package? In this case I want to get a vector of intercepts after splitting a data.frame. I have accomplished what I need using lapply(), but I would like to use only functions purrr package.

library(purrr)
mtcars %>% 
split(.$cyl) %>%
map(  ~lm(mpg ~ wt, data = .)) %>%        # shorthand  NOTE: ~ lm  
lapply(function(x) x[[1]] [1]) %>% # extract intercepts  <==is there a purrr function for this line?
as_vector()                               # convert to vector

I have tried map() and at_depth() but nothing seemed to work for me.

userJT
  • 11,486
  • 20
  • 77
  • 88
hackR
  • 1,459
  • 17
  • 26
  • How did you try `map`? If you delete the function name `lapply` and replace it with `map` - exact same arguments - it works just fine. – Gregor Thomas Jan 12 '16 at 19:07
  • 1
    I found the help page for `map` useful here. It looks like you can do some short-cut coding compared to `lapply`. Like `map_dbl(c(1, 1))` for indexing nested lists. – aosmith Jan 12 '16 at 19:19
  • @Gregor. Aaaargh! That's just too obvious. Thanks – hackR Jan 12 '16 at 19:41

2 Answers2

21

The map functions have some shorthand coding for indexing nested lists. A helpful snippet from the help page:

To index deeply into a nested list, use multiple values; c("x", "y") is equivalent to z[["x"]][["y"]].

So using code for nested indexes along with map_dbl, which reduces to a vector, you can simply do:

mtcars %>%
    split(.$cyl) %>%
    map(~lm(mpg ~ wt, data = .)) %>%
    map_dbl(c(1, 1))

       4        6        8 
39.57120 28.40884 23.86803 

I also found this blog post introducing purrr 0.1.0 useful, as it gave a few more example of the shorthand coding that I ended up using.

aosmith
  • 34,856
  • 9
  • 84
  • 118
  • Perfect. This is the best answer for me because it doesn't output those vectors with names as attributes. Cheers! – hackR Jan 12 '16 at 19:57
1

using tidy function from broom

library(purrr)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(tidyr)
library(broom)

cyl_group<-mtcars %>% group_by(cyl) %>% 
        nest()
        
cyl_lm<-cyl_group %>% mutate(
        mod=map(data,~lm(mpg ~ wt, data = .x))
) %>% mutate(coef=map(mod,~tidy(.x))) %>% unnest(coef)
cyl_lm
#> # A tibble: 6 x 8
#> # Groups:   cyl [3]
#>     cyl data             mod    term      estimate std.error statistic   p.value
#>   <dbl> <list>           <list> <chr>        <dbl>     <dbl>     <dbl>     <dbl>
#> 1     6 <tibble [7 x 10~ <lm>   (Interce~    28.4      4.18       6.79   1.05e-3
#> 2     6 <tibble [7 x 10~ <lm>   wt           -2.78     1.33      -2.08   9.18e-2
#> 3     4 <tibble [11 x 1~ <lm>   (Interce~    39.6      4.35       9.10   7.77e-6
#> 4     4 <tibble [11 x 1~ <lm>   wt           -5.65     1.85      -3.05   1.37e-2
#> 5     8 <tibble [14 x 1~ <lm>   (Interce~    23.9      3.01       7.94   4.05e-6
#> 6     8 <tibble [14 x 1~ <lm>   wt           -2.19     0.739     -2.97   1.18e-2

Created on 2020-08-19 by the reprex package (v0.3.0)

Nithin .M
  • 85
  • 5