r - 混合 unnest_longer 和 unnest_wider

标签 r json tidyr purrr

我(再一次)被扁平化嵌套列表困住了。

我有一些列表列(源自 JSON 格式)。

    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 行包含一个列表列表,我必须先取消 nest_longer:

bind_rows(
  df %>% slice(1,2),
  df %>% slice(3) %>% unnest_longer(branch)) %>% 
  unnest_wider(branch)

上面的代码给出了所需的输出,但我正在寻找一个通用的解决方案,例如:

如果'branch'列的一个元素是'unnamed list'类型(表示有一个lists of lists)那么unnest_longer。然后将 unnest_wider 应用于整个“分支”列

感谢任何帮助!

最佳答案

首先将叶子转换为数据框,然后取消嵌套。

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'))))))

关于r - 混合 unnest_longer 和 unnest_wider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73663318/

相关文章:

java - Android Json数组数据错误并且无法从json数组索引中查找或获取数据

R:使用棘手的分隔符将列分成行

r - 从文本文件导入单个向量作为 R 中的变量

在 R 中使用时间窗口运行测试

json - JacksonProviderProxy在json输出中写出空值

python - 如何通过flask返回json文件而不保存在磁盘上?

r - 在R中的另一列下方插入多列

r - tidyr - 获得组合的独特方式(仅使用 tidyverse)

r - 结合 R 中不同训练集构建的随机森林

r - 如何使用 R 中的 dplyr 根据跨多列的条件过滤数据框