将数据框转换为深度嵌套列表

Converting data frame into deeply nested list

我正在尝试创建 whisker 包所期望的数据结构,但我似乎无法弄清楚如何 从我的数据框中创建该结构。假设我有以下数据框:

library(dplyr)  

existing_format <- 
  mtcars %>% 
    select(carb, gear, cyl) %>% 
    arrange(carb, gear, cyl) %>% 
    distinct() 

...我想从 existing_format 转到以下所需格式(仅显示 desired_format 列表的前两个元素):

desired_format <- list(
  list( 
    carb = "1",
    gear = list(
      list(gear = "3", cyl = list(list(cyl = "4"), list(cyl = "6"))),
      list(gear = "4", cyl = list(list(cyl = "4")))
    )
  ),
  list( 
    carb = "2",
    gear = list(
      list(gear = "3", cyl = list(list(cyl = "8"))),
      list(gear = "4", cyl = list(list(cyl = "4"))),
      list(gear = "5", cyl = list(list(cyl = "4")))
    )
  )
)

我试过按 carbgear 分组,然后使用 tidyr::nest() 创建嵌套 df,但没有任何效果。有些东西告诉我 whisker::iteratelist()whisker::rowSplit() 是前进的方向,但我想不通。

谢谢, 克里斯

在这种情况下可能比需要的更灵活,但您可以进行递归拆分

rsplit<-function(dd) {
  col <- names(dd)[1]
  dat <- dd[[1]]
  xx <- lapply(unique(dat), function(x) {
    z <- setNames(list(x), col)
    if(ncol(dd)>1) {
      z[[names(dd)[2]]] <- rsplit(dd[dat==x,-1, drop=FALSE])
    }
    z
  })
  xx
}

rsplit(existing_format)

这将拆分所有列并使用列 headers 中的名称。

这里有一个方法,不是通用的 n 列,但它适用于 3。

library(purrr)
library(magrittr)
library(dplyr)

output <- existing_format                           %>%
    map_df(as.character)                            %>%
    group_by(carb,gear)                             %>%
    summarize_at("cyl",~lst(map(.,~lst(cyl = .x)))) %>%
    mutate(gear = map2(.x = gear,.y = cyl,~lst(gear = .x,cyl = .y))) %>%
    group_by(carb)                                  %>%
    summarize_at("gear",~lst(gear=.))               %$%
    map2(.x = carb,.y = gear,~lst(carb = .x,gear = .y))

identical(output[1:2],desired_format) #TRUE