Doug Fir
Doug Fir

Reputation: 21242

While using map function how can I get the name of the variable being iterated on?

m1 <- lm(price ~ carat, data = diamonds)
m2 <- lm(price ~ carat + cut, data = diamonds)
m3 <- lm(price ~ carat + cut + depth, data = diamonds)

eval_mods <- list(m1, m2, m3) %>% 
  imap_dfr(broom::glance)

Returns a data frame:

# A tibble: 3 x 11
  r.squared adj.r.squared sigma statistic p.value    df   logLik     AIC     BIC      deviance df.residual
      <dbl>         <dbl> <dbl>     <dbl>   <dbl> <int>    <dbl>   <dbl>   <dbl>         <dbl>       <int>
1     0.849         0.849 1549.   304051.       0     2 -472730. 945467. 945493. 129345695398.       53938
2     0.856         0.856 1511.    64369.       0     6 -471420. 942854. 942916. 123212493961.       53934
3     0.857         0.857 1510.    53766.       0     7 -471366. 942748. 942819. 122965858561.       53933

I'd like to prepend a field with the name of the model, m1, m2, m3.

eval_mods <- list(m1, m2, m3) %>% 
  imap_dfr(broom::glance) %>% 
  mutate(model_name = c("m1", "m2", "m3"))

This gives me the output I want except I will likely have a fluctuating number of models as I work through my analysis and would prefer an automated way.

Tried:

eval_mods <- list(m1, m2, m3) %>% 
  imap_dfr(broom::glance) %>% 
  mutate(model = .y)

I was unclear what '.y' is but from readings the documentation I thought it might be the name of the iteration being worked through. I was hoping to get the same results as above but without have to pass a manually created vector model_name = c("m1", "m2", "m3"). Can I use .y in this way? If so, how? If not, is there another solution?

Upvotes: 0

Views: 55

Answers (1)

IceCreamToucan
IceCreamToucan

Reputation: 28695

You are correct about what .y is, it is the name of the current element. There are two issues with the attempt above:

  1. Your list has no names. In that case .y defaults to the index of the current element instead of the name
  2. You can only use .y inside imap.

A slightly modified version which works is below

list(m1 = m1, m2 = m2, m3 = m3) %>% 
  imap_dfr( ~ broom::glance(.x) %>% 
                mutate(model_nm = .y))

see comment below for easier built-in way to add an id to each row of output

Upvotes: 2

Related Questions