【问题标题】:How to unnest a tibble list column with both list and character entries ("cannot combine list and character")?如何取消包含列表和字符条目的小标题列表列(“无法组合列表和字符”)?
【发布时间】:2022-01-17 12:18:49
【问题描述】:

我有一个嵌套的 tibble,我想取消嵌套。两个列表列(street_address 和 status)包含字符向量和列表,一个列表列(国家)仅包含字符向量。取消嵌套 tibble 时,会产生错误,这显然是由于这两种类型的条目的两列中同时存在字符向量和列表。

df <- tibble::tribble(
                          ~id,         ~country,                                                                                                                       ~street_address,                                                                   ~status,
          "2008-002231-32-GB", c("United Kingdom", "Netherlands"),                                                                                                                       list(c(NA, NA)),                                                           list(c(NA, NA)),
         "2020-001060-28-SE",  c("Denmark", "Denmark", "Denmark", "Denmark"), c("Palle Juul Jensens Blvrd 67", "Palle Juul Jensens Boulevard 99", "Palle Juul Jensens Blvrd 67", "Palle Juul Jensens Boulevard 99"), c("Non-Commercial", "Non-Commercial", "Non-Commercial", "Non-Commercial")
          )

df
# A tibble: 2 × 4
  id                country   street_address status    
  <chr>             <list>    <list>         <list>    
1 2008-002231-32-GB <chr [2]> <list [1]>     <list [1]>
2 2020-001060-28-SE <chr [4]> <chr [4]>      <chr [4]> 

df %>%
unnest(cols = c(country, street_address, status))
# >Error: Can't combine `..1$street_address` <list> and `..2$street_address` <character>.

reprex package (v2.0.1) 于 2021 年 12 月 14 日创建

似乎是列中存在列表条目是问题(全部采用 list(c(NA, NA)) 的格式)。一种选择可能是将这些观察结果更改为字符向量(或将它们设为 NA,因为它们似乎都是 NA),但我无法弄清楚如何做到这一点或这是否能解决问题。任何帮助将不胜感激。

请注意,这是一个更新的问题,因为我随问题提交的第一个数据是我使用 dpasta() 生成的,并不能很好地代表我的实际数据。

想要的结果应该是这样的:

# A tibble: 8 × 4
  id                country        street_address                  status        
  <chr>             <chr>          <chr>                           <chr>         
1 2020-001060-28-SE Denmark        Palle Juul Jensens Blvrd 67     Non-Commercial
2 2020-001060-28-SE Denmark        Palle Juul Jensens Boulevard 99 Non-Commercial
3 2020-001060-28-SE Denmark        Palle Juul Jensens Blvrd 67     Non-Commercial
4 2020-001060-28-SE Denmark        Palle Juul Jensens Boulevard 99 Non-Commercial
5 2008-002231-32-GB United Kingdom NA                              NA                       
6 2008-002231-32-GB Netherlands    NA                              NA                        
> 
``

【问题讨论】:

    标签: r list tibble unnest


    【解决方案1】:
    library(tidyverse)
    df <- tibble::tribble(
      ~ id,
      ~ country,
      ~ street_address,
      ~ status,
      "2008-002231-32-GB",
      c("United Kingdom", "Netherlands"),
      list(c(NA, NA)),
      list(c(NA, NA)),
      "2020-001060-28-SE",
      c("Denmark", "Denmark", "Denmark", "Denmark"),
      c(
        "Palle Juul Jensens Blvrd 67",
        "Palle Juul Jensens Boulevard 99",
        "Palle Juul Jensens Blvrd 67",
        "Palle Juul Jensens Boulevard 99"
      ),
      c(
        "Non-Commercial",
        "Non-Commercial",
        "Non-Commercial",
        "Non-Commercial"
      )
    )
    
    
    df %>% mutate(res = map_chr(street_address, class)) %>% 
      group_split(res) %>% 
      map(~unnest(data = ., c(country, street_address, status))) %>% 
      map_df(~unnest(data = ., c(country, street_address, status))) %>% 
      select(-res)
    #> # A tibble: 8 x 4
    #>   id                country        street_address                  status       
    #>   <chr>             <chr>          <chr>                           <chr>        
    #> 1 2020-001060-28-SE Denmark        Palle Juul Jensens Blvrd 67     Non-Commerci~
    #> 2 2020-001060-28-SE Denmark        Palle Juul Jensens Boulevard 99 Non-Commerci~
    #> 3 2020-001060-28-SE Denmark        Palle Juul Jensens Blvrd 67     Non-Commerci~
    #> 4 2020-001060-28-SE Denmark        Palle Juul Jensens Boulevard 99 Non-Commerci~
    #> 5 2008-002231-32-GB United Kingdom <NA>                            <NA>         
    #> 6 2008-002231-32-GB United Kingdom <NA>                            <NA>         
    #> 7 2008-002231-32-GB Netherlands    <NA>                            <NA>         
    #> 8 2008-002231-32-GB Netherlands    <NA>                            <NA>
    

    reprex package (v2.0.1) 于 2021 年 12 月 14 日创建

    【讨论】:

    • 谢谢!我已经用一个可以更好地反映我的实际数据的小标题更新了这个问题。我希望你会考虑再看一遍。
    • 更新了解决方案。这是想要的结果吗?
    • 我希望对于 2008-002231-32-GB id,只会产生两行,因为该 id 的所有列中只有两个元素。我已经在上面的问题中添加了我期望的结果应该看起来不错,但是我无法通过修改您的代码来生成它。
    • 为什么不删除 2020-001060-28-SE 的重复项?
    • 手动删除重复项并不是一个真正的选项,因为完整的数据集有 24565 个 id。如果可以仅针对具有此类条目(list(c(NA,NA)))的那些ID做到这一点,那么也许这将是一种解决方法,但我看不出如何。
    【解决方案2】:

    您可以使用tidyr 中的unnest 函数取消嵌套数据。代码如下所示:

    library(tidyr)
    
    df %>%
      mutate(r = map(street_address, ~data.frame(t(.))), s = map(status, ~data.frame(t(.)))) %>%
      unnest(r, s) %>%
      select(-street_address, -status)
    

    输出如下所示:

    # A tibble: 6 x 12
      id     country  t...   X1     X2     X3     X4    t...1 X11   X21   X31   X41  
      <chr>  <chr>    <list> <chr>  <chr>  <chr>  <chr> <lis> <chr> <chr> <chr> <chr>
    1 2008-~ United ~ <lgl ~ NA     NA     NA     NA    <lgl~ NA    NA    NA    NA   
    2 2008-~ Netherl~ <lgl ~ NA     NA     NA     NA    <lgl~ NA    NA    NA    NA   
    3 2020-~ Denmark  <NULL> Palle~ Palle~ Palle~ Pall~ <NUL~ Non-~ Non-~ Non-~ Non-~
    4 2020-~ Denmark  <NULL> Palle~ Palle~ Palle~ Pall~ <NUL~ Non-~ Non-~ Non-~ Non-~
    5 2020-~ Denmark  <NULL> Palle~ Palle~ Palle~ Pall~ <NUL~ Non-~ Non-~ Non-~ Non-~
    6 2020-~ Denmark  <NULL> Palle~ Palle~ Palle~ Pall~ <NUL~ Non-~ Non-~ Non-~ Non-~
    

    【讨论】:

    • 谢谢!请注意,我已经更新了问题中的 tibble,如果您想再次查看它。
    猜你喜欢
    • 2021-02-27
    • 2018-12-21
    • 1970-01-01
    • 2017-10-10
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    相关资源
    最近更新 更多