【问题标题】:Modify, extract, and concatenate list sub-elements into a data.frame in R with tidyverse使用 tidyverse 修改、提取和连接列表子元素到 R 中的 data.frame
【发布时间】:2018-08-15 16:21:08
【问题描述】:

我正在尝试找到一种优雅的方式来处理 R 中的列表结构。特别是,在这种情况下,我想从列表中提取子元素,根据列表中的关联数据修改它们,并将它们连接成一个数据框。举个例子可能更容易:

mystruct <- structure(list(dataset1 = structure(list(data1 = structure(list(
    a = c(1, 2, 3), b = c(4, 5, 6)), .Names = c("a", "b"), row.names = c(NA, 
-3L), class = "data.frame"), data2 = c("a", "b", "c", "d", "e"
)), .Names = c("data1", "data2")), dataset2 = structure(list(
    data1 = structure(list(a = c(7, 8, 9), b = c(10, 11, 12)), .Names = c("a", 
    "b"), row.names = c(NA, -3L), class = "data.frame"), data2 = c("f", 
    "g", "h", "i", "j")), .Names = c("data1", "data2"))), .Names = c("dataset1", 
"dataset2"))

我可以像这样连接 data1 元素:

> mystruct %>% map_dfr(~.x$data1)
  a  b
1 1  4
2 2  5
3 3  6
4 7 10
5 8 11
6 9 12

但我想添加一个“数据集”列,该列由获取数据的列表元素的名称填充:

  dataset    a  b
1 dataset1   1  4
2 dataset1   2  5
3 dataset1   3  6
4 dataset2   7 10
5 dataset2   8 11
6 dataset2   9 12

有没有办法用 tidyverse 很好地做到这一点?我也愿意接受 data.table 解决方案。

谢谢, 艾莉

【问题讨论】:

    标签: r data.table tidyverse purrr


    【解决方案1】:

    map_df 提供一个.id 参数,这将创建一个给出列表名称的列:

    map_df(mystruct, 'data1', .id='dataset')
    
    #   dataset a  b
    #1 dataset1 1  4
    #2 dataset1 2  5
    #3 dataset1 3  6
    #4 dataset2 7 10
    #5 dataset2 8 11
    #6 dataset2 9 12
    

    或者map_dfr 应该也可以:

    map_dfr(mystruct, 'data1', .id='dataset')
    

    【讨论】:

      【解决方案2】:

      map_dfr 有一个 .id 参数:

      mystruct %>% map_dfr(~ .x$data1, .id = "id")
      

      给予:

              id a  b
      1 dataset1 1  4
      2 dataset1 2  5
      3 dataset1 3  6
      4 dataset2 7 10
      5 dataset2 8 11
      6 dataset2 9 12
      

      【讨论】:

        【解决方案3】:

        重组为带有列表列的“整洁”表...

        library(data.table)
        tabstruct = rbindlist(lapply(mystruct, lapply, list), id = TRUE)
        #         .id        data1     data2
        # 1: dataset1 <data.frame> a,b,c,d,e
        # 2: dataset2 <data.frame> f,g,h,i,j
        

        然后“unnest”数据1:

        tabstruct[, rbindlist(setNames(data1, .id), id=TRUE)]
        
        #         .id a  b
        # 1: dataset1 1  4
        # 2: dataset1 2  5
        # 3: dataset1 3  6
        # 4: dataset2 7 10
        # 5: dataset2 8 11
        # 6: dataset2 9 12
        

        或未嵌套数据2:

        tabstruct[, .(val = unlist(data2)), by=.id]
        #          .id val
        #  1: dataset1   a
        #  2: dataset1   b
        #  3: dataset1   c
        #  4: dataset1   d
        #  5: dataset1   e
        #  6: dataset2   f
        #  7: dataset2   g
        #  8: dataset2   h
        #  9: dataset2   i
        # 10: dataset2   j
        

        【讨论】:

          【解决方案4】:

          这是在list 中的多个数据集上执行此操作的选项

          map(c('data1', 'data2'), ~  
                   map2_df(mystruct, .x, ~ .x[[.y]], .id = 'id'))
          #[[1]]
          #        id a  b
          #1 dataset1 1  4
          #2 dataset1 2  5
          #3 dataset1 3  6
          #4 dataset2 7 10
          #5 dataset2 8 11
          #6 dataset2 9 12
          
          #[[2]]
          # A tibble: 5 x 3
          #  id    dataset1 dataset2
          #  <chr> <chr>    <chr>   
          #1 1     a        f       
          #2 1     b        g       
          #3 1     c        h       
          #4 1     d        i       
          #5 1     e        j     
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-10-29
            • 1970-01-01
            • 2014-04-18
            • 1970-01-01
            • 1970-01-01
            • 2019-01-07
            • 2018-08-16
            • 2021-04-24
            相关资源
            最近更新 更多