【问题标题】:Unnest one column list to many columns in tidyr将一列列表取消嵌套到 tidyr 中的多列
【发布时间】:2026-01-05 12:55:02
【问题描述】:

例如,我有一个这样的整洁数据框:

df <- tibble(id=1:2,
         ctn=list(list(a="x",b=1),
                  list(a="y",b=2)))
# A tibble: 2 x 2
     id        ctn
  <int>     <list>
1     1 <list [2]>
2     2 <list [2]>

我如何将ctn 列取消嵌套到右侧,以便数据框如下所示:

# A tibble: 2 x 3
     id     a     b
  <int> <chr> <dbl>
1     1     x     1
2     2     y     2

【问题讨论】:

    标签: r tidyr


    【解决方案1】:

    一个选项是

    library(data.table)
    setDT(df)[, unlist(ctn, recursive = FALSE), id]
    #   id a b
    #1:  1 x 1
    #2:  2 y 2
    

    或者tidyr

    library(tidyverse)
    df$ctn %>%
         setNames(., df$id) %>%
         bind_rows(., .id = 'id')
    # A tibble: 2 x 3
    #   id     a     b
    #  <chr> <chr> <dbl>
    #1     1     x     1
    #2     2     y     2
    

    【讨论】:

      【解决方案2】:

      使用dplyrpurrr

      df %>% 
        mutate(ctn = map(ctn, as_tibble)) %>%
        unnest()
      
      # A tibble: 2 x 3
           id     a     b
        <int> <chr> <dbl>
      1     1     x     1
      2     2     y     2
      

      【讨论】:

      • 如果您想避免警告(否则您可能希望将其包含为输出),请使用 as_tibble 而不是 as.data.frame。或添加stringsAsFactors=FALSE
      • @docendodiscimus 谢谢,进行了编辑。完全忘记了stringsAsFactors=FALSE,一开始就改成options()
      • 其他人注意:这适用于列表的列表列,但不适用于向量的列表列。有关列表解决方案的列表列,请参见 *.com/questions/49889246/how-to-unnest-column-list
      【解决方案3】:

      我们现在可以(dplyr 1.0.2 及更高版本)使用rowwise() 以简洁的方式执行此操作:

      df %>% rowwise() %>% mutate(as_tibble(ctn))
      
      # A tibble: 2 x 4
      # Rowwise: 
           id ctn              a         b
        <int> <list>           <chr> <dbl>
      1     1 <named list [2]> x         1
      2     2 <named list [2]> y         2
      

      并且坚持purrr,我们还可以:

      df %>% mutate(map_dfr(ctn, as_tibble))
      
      # A tibble: 2 x 4
           id ctn              a         b
        <int> <list>           <chr> <dbl>
      1     1 <named list [2]> x         1
      2     2 <named list [2]> y         2
      

      【讨论】:

        最近更新 更多