Merging list-column data frames

Viewed 45

I have a data frame / tibble with several list-columns that I want to merge / join with each other, but I'm struggling to find an elegant way to do so using the mutate(map()) workflow.

Suppose I have a data frame with the following structure:

library(gapminder)

# Setup
gap_1 <- gapminder %>% 
    select(-pop, -gdpPercap) %>% 
    group_by(country, continent) %>% 
    nest() %>% 
    rename(lifeExp = data) 

gap_2 <- gapminder %>% 
    select(-lifeExp, -gdpPercap) %>% 
    group_by(country, continent) %>% 
    nest() %>% 
    rename(pop = data)  

gap_3 <- gapminder %>% 
    select(-lifeExp, -pop) %>% 
    group_by(country, continent) %>% 
    nest() %>% 
    rename(gdpPercap = data)

# What my data looks like 
gap_main <- reduce(list(gap_1, gap_2, gap_3), left_join, by = c("country", "continent")) %>% ungroup()  

What I'm hoping to do is to merge the list-columns lifeExp, pop, and gdpPercap by year (There are more than three such columns in my data). But I'm not sure how one would go about this using mutate and pmap / map2.

My attempts so far have been to use pmap with bind_cols like so: (this is assuming rows correspond)

gap_main %>% 
     mutate(all = pmap(list(lifeExp, pop, gdpPercap), ~ bind_cols(...))) 

or repeatedly use map2 with left_join. Is there a more elegant way of doing this perhaps using reduce?

1 Answers

I am not sure how your desired output should look like, would the approach below work for you? It uses {dplyr}'s rowwise notation and then basically purrr::reduce to join all three columns in one call.

library(tidyverse)
library(gapminder)

gap_main %>% 
  rowwise %>% 
  mutate(data = list(reduce(list(lifeExp, pop, gdpPercap), left_join, by = "year")))

#> # A tibble: 142 x 6
#> # Rowwise: 
#>    country    continent lifeExp        pop           gdpPercap      data        
#>    <fct>      <fct>     <list>         <list>        <list>         <list>      
#>  1 Afghanist… Asia      <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  2 Albania    Europe    <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  3 Algeria    Africa    <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  4 Angola     Africa    <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  5 Argentina  Americas  <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  6 Australia  Oceania   <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  7 Austria    Europe    <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  8 Bahrain    Asia      <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  9 Bangladesh Asia      <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#> 10 Belgium    Europe    <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#> # … with 132 more rows

Alternatively you could use pmap instead of rowwise in the following way:

gap_main %>% 
  mutate(all = pmap(list(lifeExp, pop, gdpPercap),
                    ~ reduce(list(..1, ..2, ..3), left_join, by = "year"))) 

#> # A tibble: 142 x 6
#>    country    continent lifeExp        pop           gdpPercap      all         
#>    <fct>      <fct>     <list>         <list>        <list>         <list>      
#>  1 Afghanist… Asia      <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  2 Albania    Europe    <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  3 Algeria    Africa    <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  4 Angola     Africa    <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  5 Argentina  Americas  <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  6 Australia  Oceania   <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  7 Austria    Europe    <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  8 Bahrain    Asia      <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#>  9 Bangladesh Asia      <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#> 10 Belgium    Europe    <tibble [12 ×… <tibble [12 … <tibble [12 ×… <tibble [12…
#> # … with 132 more rows
Related