【问题标题】:R dataframe to nested listR数据框到嵌套列表
【发布时间】:2021-05-24 18:17:11
【问题描述】:

我想将这种格式的数据框 (tbl) 转换为以下嵌套列表 (tbllst):

library(tidyr)

tbl <- tribble(
  ~Col1, ~Col2, ~Col3,
  "Var1", "Var1_1", "Var1_1_1", 
  "Var1", "Var1_1", "Var1_1_2", 
  "Var1", "Var1_2", "Var1_2_1", 
  "Var1", "Var1_2", "Var1_2_2", 
)

tbllst <- list(
  Col1 = list(
    "Var1" = list(
      Col2 = list(
        "Var1_1" = list(
          Col3 = c(
            "Var1_1_1", 
            "Var1_1_2"
          )
        ),
        "Var1_2" = list(
          Col3 = c(
            "Var1_2_1", 
            "Var1_2_2"
          )
        )
      )
    )
  )
)

有没有一种自动化的方式来实现这一点?

【问题讨论】:

    标签: r list dataframe nested nested-lists


    【解决方案1】:

    rrapply-package 中的函数rrapply() 有一个选项how = "unmelt",它将熔化的data.frame 转换为嵌套列表,其中data.frame 中的每一行都成为嵌套列表中的节点路径。

    要应用此功能,我们首先需要将tbldata.frame 转换为rrapply() 所需的输入格式:

    library(purrr)
    library(dplyr)
    library(rrapply)
    
    ## put data.frame in format for rrapply-function
    tbl1 <- imap_dfc(tbl, ~bind_cols(.y, .x)) %>%
      group_by(across(num_range(prefix = "...", range = 1:5))) %>%
      summarize(`...6` = list(c(`...6`)))
    
    tbl1
    #> # A tibble: 2 x 6
    #> # Groups:   ...1, ...2, ...3, ...4 [2]
    #>   ...1  ...2  ...3  ...4   ...5  ...6     
    #>   <chr> <chr> <chr> <chr>  <chr> <list>   
    #> 1 Col1  Var1  Col2  Var1_1 Col3  <chr [2]>
    #> 2 Col1  Var1  Col2  Var1_2 Col3  <chr [2]>
    
    ## unmelt to nested list
    ls_tbl <- rrapply(tbl1, how = "unmelt")
    
    str(ls_tbl)
    #> List of 1
    #>  $ Col1:List of 1
    #>   ..$ Var1:List of 1
    #>   .. ..$ Col2:List of 2
    #>   .. .. ..$ Var1_1:List of 1
    #>   .. .. .. ..$ Col3: chr [1:2] "Var1_1_1" "Var1_1_2"
    #>   .. .. ..$ Var1_2:List of 1
    #>   .. .. .. ..$ Col3: chr [1:2] "Var1_2_1" "Var1_2_2"
    

    注意group_by()summarize()操作的目的只是为了在一个Col3节点下获得多个var1_%_%。以下是相当容易的(但不会产生完全相同的结果):

    ls_tbl <- rrapply(imap_dfc(tbl, ~bind_cols(.y, .x)), how = "unmelt")
    
    str(ls_tbl)
    #> List of 1
    #>  $ Col1:List of 1
    #>   ..$ Var1:List of 1
    #>   .. ..$ Col2:List of 2
    #>   .. .. ..$ Var1_1:List of 2
    #>   .. .. .. ..$ Col3: chr "Var1_1_1"
    #>   .. .. .. ..$ Col3: chr "Var1_1_2"
    #>   .. .. ..$ Var1_2:List of 2
    #>   .. .. .. ..$ Col3: chr "Var1_2_1"
    #>   .. .. .. ..$ Col3: chr "Var1_2_2"
    

    【讨论】:

      【解决方案2】:

      这是另一个使用data.table + rrapply的选项

      library(data.table)
      library(rrapply)
      
      dt <- setDT(tbl)[, Map(function(...) list2DF(.(...)), names(.SD), .SD)]
      rrapply(dt[, lapply(.SD, list), c(head(names(dt), -1))], how = "unmelt")
      

      给了

      $Col1
      $Col1$Var1
      $Col1$Var1$Col2
      $Col1$Var1$Col2$Var1_1
      $Col1$Var1$Col2$Var1_1$Col3
      [1] "Var1_1_1" "Var1_1_2"
      
      
      $Col1$Var1$Col2$Var1_2
      $Col1$Var1$Col2$Var1_2$Col3
      [1] "Var1_2_1" "Var1_2_1"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-01
        • 2018-03-06
        • 2020-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-03
        • 1970-01-01
        相关资源
        最近更新 更多