将数据框转换为深度嵌套列表
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")))
)
)
)
我试过按 carb
和 gear
分组,然后使用 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
我正在尝试创建 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")))
)
)
)
我试过按 carb
和 gear
分组,然后使用 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