我(再一次)被扁平的嵌套列表困住了。
我有一些列表列(源自JSON格式)的tibble。
library(tidyr)
library(dplyr)
df = tibble(id = c(1, 2, 3),
branch = list(NULL, list(colA = 'abc', colB = 'mno'),
list(list(colA = 'def', colB = 'uvw'),
list(colA = 'ghi', colB = 'xyz'))))我要unnest_wider栏‘分支’。它适用于第1行和第2行:
df %>%
slice(1:2) %>%
unnest_wider(branch)但是,第3行包含了一个列表,我必须首先对这些列表进行unnest_longer:
bind_rows(
df %>% slice(1,2),
df %>% slice(3) %>% unnest_longer(branch)) %>%
unnest_wider(branch)上面的代码提供了所需的输出,但我正在寻找一个通用解决方案,如下所示:
如果“分支”列的元素类型为“未命名列表”(指示有列表列表),则unnest_longer。之后,将unnest_wider应用于整个列“分支”
任何帮助都很感激!
发布于 2022-09-09 19:15:04
首先将叶子转换为数据帧,然后取消嵌套。
library(dplyr)
library(tidyr)
leaf2df <- function(x) {
if (length(names(x))) as.data.frame(x)
else if (is.list(x)) lapply(x, leaf2df)
}
df %>%
rowwise %>%
mutate(branch = list(bind_rows(leaf2df(branch)))) %>%
ungroup %>%
unnest(branch, keep_empty = TRUE)给予:
# A tibble: 4 × 3
id colA colB
<dbl> <chr> <chr>
1 1 <NA> <NA>
2 2 abc mno
3 3 def uvw
4 3 ghi xyz 因为leaf2df是递归的,只要任何行中的所有叶子都有相同的父级,那么它应该继续工作。例如,下面我们已经将最后一行中的列表做得更深了一点,而且它仍然有效。
df <- tibble(id = c(1, 2, 3),
branch = list(NULL, list(colA = 'abc', colB = 'mno'),
list(list(list(colA = 'def', colB = 'uvw'),
(list(colA = 'ghi', colB = 'xyz'))))))发布于 2022-09-09 14:20:08
有点复杂,但这里有一个可能的解决方案:
如果df
list,则names(df$branch[[index]])unnest_wider()library(tidyr)
library(dplyr)
library(purrr)
map_df(1:nrow(df), function(x) {
if (is.null(names(df$branch[[x]]))) {
df %>% slice(x) %>% unnest_longer(branch)
} else {
df %>% slice(x)
}
}) %>%
unnest_wider(branch)返回:
# A tibble: 4 × 3
id colA colB
<dbl> <chr> <chr>
1 1 NA NA
2 2 abc mno
3 3 def uvw
4 3 ghi xyz发布于 2022-09-09 14:42:01
library(tidyverse)
df <- tibble(
id = c(1, 2, 3),
branch = list(
NULL, list(colA = "abc", colB = "mno"),
list(
list(colA = "def", colB = "uvw"),
list(colA = "ghi", colB = "xyz")
)
)
)
unnester <- function(x, grp) {
if (grp) {
x <- x |> unnest_longer(branch)
}
unnest_wider(x, branch)
}
df |>
rowwise() |>
mutate(grp = length(names(unlist(branch))) > 2) |>
ungroup() |>
split(~grp) |>
imap_dfr(~ unnester(.x, .y)) |>
select(-grp)https://stackoverflow.com/questions/73663318
复制相似问题