How to tidy() on map() model results



If I run tidy() on my map() results:

map(.x = levels(Orange$Tree), .f = function(z){lm(formula = age ~ 1 + circumference, subset = Tree == z, data = Orange)}) %>% 

I get an error:
"Error in names(object) <- nm :
'names' attribute [1] must be the same length as the vector [0]
In addition: Warning message:
In : applied to non-(list or vector) of type 'NULL'"

Which confirms that I don't know what I'm doing. :slight_smile:

Does anyone have a suggestion?


Would you be able to make this into a minimal reproducible example (aka a reprex)?

In addition to the reprex section of the tidyverse site (linked to above), there's a quick, helpful overview of the package and how to use it (Jenny starts ~10:40) in the video below.

You can also see the slides from that video here:


The problem you're encountering (I think) is that map() returns a list of lm objects (one for each level of Tree as per your call). And tidy() doesn't know how to operate on a list of lm objects, just on a single lm object.

So you need to iterate over your list, tidy()ing each element. Luckily you already know how to do that (with map())! I got the the following code to work (indentation/formatting not really that important):

    .x = levels(Orange$Tree), 
    .f = function(z) {
        lm(formula = age ~ 1 + circumference, subset = Tree == z, data = Orange)
    ) %>% 


Thanks Jim! You nailed it.


You could also do it like this:

Orange %>%
  group_by(Tree) %>%
  nest() %>%
  mutate(model = map(data, ~ lm(age ~ 1 + circumference, data = .x)),
        tidy_model = map(model, broom::tidy)) %>%

This will give you a data frame with all of the different models in the same data frame rather than in a list of data frames.

More similar to your accepted answer, you could change the map(tidy) portion to map_df(tidy) and you would get the same thing. The nice thing about the first approach is that you can do a lot more than just tidy the models, i.e., augment or glance, all in the same mutate call and then just unnest which ever you are interested in.


You'll need to drop the parentheses on broom::tidy() to get this to run, but in the long big picture this is a much more useful idiom.


Oops, you are correct! I have corrected my response. I overlooked that since I was typing directly into the browser