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

时间:2017-12-13 21:42:14

标签: r purrr r-whisker

我正在尝试创建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()是前进的方向,但我无法理解。

谢谢, 克里斯

2 个答案:

答案 0 :(得分:6)

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

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)

这将拆分所有列,并使用列标题中的名称。

答案 1 :(得分:1)

这是一种方法,对于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