【问题标题】:List into tibble using list names as values in one column使用列表名称作为一列中的值列出到 tibble
【发布时间】:2018-03-01 12:24:57
【问题描述】:

我想像这样转换一个列表:

l <- list(x = c(1, 2), y = c(3, 4, 5))

变成这样的小标题:

 Name  Value 
 x      1
 x      2
 y      3
 y      4
 y      5

【问题讨论】:

    标签: r list tidyverse purrr tibble


    【解决方案1】:

    我认为没有什么比使用 base R 中的 stack-function 更容易的了:

    df <- stack(l)
    

    返回一个数据框:

    > df
      values ind
    1      1   x
    2      2   x
    3      3   y
    4      4   y
    5      5   y
    

    因为您要求tibble 作为输出,您可以通过as_tibble(df)(来自tibble-package)来获得它。

    或者更直接:df &lt;- as_tibble(stack(l))


    另一种纯基R方法:

    df <- data.frame(ind = rep(names(l), lengths(l)), value = unlist(l), row.names = NULL)
    

    给出了类似的结果:

    > df
      ind value
    1   x     1
    2   x     2
    3   y     3
    4   y     4
    5   y     5
    

    row.names = NULL 不一定是必需的,但将行号作为行名。

    【讨论】:

      【解决方案2】:

      更新

      我找到了更好的解决方案。

      这适用于我之前发布的简单和复杂列表(如下)

      l %>% map_dfr(~ .x %>% as_tibble(), .id = "name")
      

      给我们

      # A tibble: 5 x 2
        name  value
        <chr> <dbl>
      1 x        1.
      2 x        2.
      3 y        3.
      4 y        4.
      5 y        5.
      

      ================================================

      原答案

      来自 tidyverse

      l %>% 
        map(~ as_tibble(.x)) %>% 
        map2(names(.), ~ add_column(.x, Name = rep(.y, nrow(.x)))) %>% 
        bind_rows()
      

      给我们

      # A tibble: 5 × 2
        value  Name
        <dbl> <chr>
      1     1     x
      2     2     x
      3     3     y
      4     4     y
      5     5     y
      

      R 中的堆栈函数非常适合 Jaap 所示的简单列表。

      但是,对于更复杂的列表,例如:

      l <- list(
        a = list(num = 1:3, let_a = letters[1:3]),
        b = list(num = 101:103, let_b = letters[4:6]),
        c = list()
      )
      

      我们得到

      stack(l)
      
      values ind
      1       1   a
      2       2   a
      3       3   b
      4       a   b
      5       b   a
      6       c   a
      7     101   b
      8     102   b
      9     103   a
      10      d   a
      11      e   b
      12      f   b
      

      这是错误的。

      上面显示的 tidyverse 解决方案工作正常,将嵌套列表中不同元素的数据分开:

      # A tibble: 6 × 4
          num   let  Name  lett
        <int> <chr> <chr> <chr>
      1     1     a     a  <NA>
      2     2     b     a  <NA>
      3     3     c     a  <NA>
      4   101  <NA>     b     d
      5   102  <NA>     b     e
      6   103  <NA>     b     f
      

      【讨论】:

      • 您更新的解决方案确实非常有用,它在手头的不同情况下对我有用,dist 对象列表的结果通过 broom::tidy 变成了一个小玩意。
      • 更短的:l %&gt;% map_dfr(as_tibble, .id = "name")(或map_dfr(l, as_tibble, .id = "name")
      【解决方案3】:

      我们可以从reshape2使用melt

      library(reshape2)
      melt(l)
      #   value L1
      #1     1  x
      #2     2  x
      #3     3  y
      #4     4  y
      #5     5  y
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-19
        • 2020-12-16
        • 1970-01-01
        • 2014-04-09
        • 1970-01-01
        • 1970-01-01
        • 2022-08-02
        • 1970-01-01
        相关资源
        最近更新 更多