kray
kray

Reputation: 377

Plotting from two data lists on one figure from a nested tibble

I have a nested list with multiple data lists. I can plot each data source on its own figure, but I am stuck trying to get a smoothing line from each data source on top of each other in a single figure. Here is a code example using the mtcars dataset.

library(dplyr)
library(tidyr)
library(purrr)
library(ggplot2)
by_cyl <- mtcars %>%  
  group_by(cyl, gear) %>%  
  nest() %>%  
  rename(cyl_data = data)

by_gear <- mtcars %>% 
  group_by(gear) %>%  
  nest() %>%  
  rename(gear_data = data

mtcars_nest <- left_join(by_cyl, by_gear, by = "gear")

mtcars_nest <- mtcars_nest %>% 
  mutate(
    map(cyl_data, ~ ggplot(., aes(x = wt, y = mpg)) + 
                             geom_point() +
                             geom_smooth(se = TRUE, color = 'blue')
    )
  ) %>% 
  rename(plot_cyl = `map(...)`)

mtcars_nest <- mtcars_nest %>% 
  mutate(
    map(gear_data, ~ ggplot(., aes(x = wt, y = mpg)) + 
          geom_point() +
          geom_smooth(se = TRUE, color = 'red')
    )
  ) %>% 
  rename(plot_gear = `map(...)`)

mtcars_nest$plot_cyl[1]
mtcars_nest$plot_gear[1]

#How to get these two plots on one figure?

Any thoughts on how to get mtcars$plot_cyl and mtcars$plot_gear on a single figure? What I really need is to add another gg list to the mtcars_nest tibble, so that I end up with a structure like cyl, gear, cyl_data, gear_data, plot_cyl, plot_gear, and plot_cyl_gear in mtcars_nest.

> mtcars_nest
# A tibble: 8 x 6
    cyl  gear cyl_data          gear_data          plot_cyl plot_gear
  <dbl> <dbl> <list>            <list>             <list>   <list>   
1     6     4 <tibble [4 × 9]>  <tibble [12 × 10]> <S3: gg> <S3: gg> 
2     4     4 <tibble [8 × 9]>  <tibble [12 × 10]> <S3: gg> <S3: gg> 
3     6     3 <tibble [2 × 9]>  <tibble [15 × 10]> <S3: gg> <S3: gg> 
4     8     3 <tibble [12 × 9]> <tibble [15 × 10]> <S3: gg> <S3: gg> 
5     4     3 <tibble [1 × 9]>  <tibble [15 × 10]> <S3: gg> <S3: gg> 
6     4     5 <tibble [2 × 9]>  <tibble [5 × 10]>  <S3: gg> <S3: gg> 
7     8     5 <tibble [2 × 9]>  <tibble [5 × 10]>  <S3: gg> <S3: gg> 
8     6     5 <tibble [1 × 9]>  <tibble [5 × 10]>  <S3: gg> <S3: gg> 

I have tried adding:

mtcars_nest <- mtcars_nest %>% 
  mutate(
    map(cyl_data, ~ ggplot(., aes(x = wt, y = mpg)) + 
          # geom_point() +
          geom_smooth(se = TRUE, color = 'blue'),
        gear_data, ~ ggplot(., aes(x = wt, y = mpg)) + 
          # geom_point() +
          geom_smooth(se = TRUE, color = 'red')
    )
  ) %>% 
  rename(plot_cyl_gear = `map(...)`)

But it seems to plot only the cyl_data in blue (the first data source in the map function.

Upvotes: 1

Views: 973

Answers (1)

aosmith
aosmith

Reputation: 36084

Looping through the two different datasets simultaneously is something that you can do with map2(). This function is still used within mutate(). (In fact, you could make all three sets of plots in one mutate() call if you wanted to, since you can name the new columns as you go.)

The first dataset is .x when creating the plot within map2() with the formula interface, and the second is .y. In this case I defined one of the datasets in the global ggplot() and the other in the second geom_smooth() call to plot two separate smooths from different datasets on the same plot.

mtcars_nest = mtcars_nest %>% 
    mutate( 
        plot_cyl_gear = map2(cyl_data, gear_data,
                                 ~ ggplot(.x, aes(x = wt, y = mpg)) +
                                     geom_smooth(se = TRUE, color = 'blue') +
                                     geom_smooth(data = .y, se = TRUE, color = 'red')
        ) )

mtcars_nest$plot_cyl_gear[1]

enter image description here

Upvotes: 1

Related Questions