【问题标题】:Merging list-column data frames合并列表列数据框
【发布时间】:2021-02-20 10:06:40
【问题描述】:

我有一个包含多个列表列的数据框/tibble,我想将它们相互合并/连接,但我正在努力寻找一种使用mutate(map()) 工作流程的优雅方法。

假设我有一个具有以下结构的数据框:

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()  

我希望做的是按年合并列表列lifeExppopgdpPercap(我的数据中有三个以上这样的列)。但我不确定如何使用mutatepmap / map2 来解决这个问题。

到目前为止,我的尝试是将pmapbind_cols 一起使用,如下所示:(这是假设行对应)

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

或重复使用map2left_join。有没有更优雅的方法可以使用reduce?

【问题讨论】:

    标签: r tidyr purrr


    【解决方案1】:

    我不确定你想要的输出应该是什么样子,下面的方法对你有用吗?它使用 {dplyr} 的 rowwise 表示法,然后基本上是 purrr::reduce 在一次调用中加入所有三列。

    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
    

    或者,您可以通过以下方式使用pmap 而不是rowwise

    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
    

    【讨论】:

    • 我认为 OP 想要一个列表列而不是三个单独的列表列,这应该是合并年份列的结果。
    • 在第一种方法中,该列称为data,第二种方法称为all。这是一个包含三个连接数据框的列表列。我只是没有删除旧列。
    • 谢谢你!最后,我希望加入后做的是select(country, continent, all),然后是unnest(all),这样你就剩下看起来像原始的gapminder数据集了。将采用您的pmap 解决方案。
    • 如果您添加 ... %&gt;% select(country, continent, all) %&gt;% unnest(all) 这应该会产生您想要的结果。
    猜你喜欢
    • 2016-06-25
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2019-09-19
    • 2016-10-31
    • 1970-01-01
    相关资源
    最近更新 更多