【问题标题】:Unnest multiple columns from json从 json 中取消嵌套多个列
【发布时间】:2020-11-10 17:59:06
【问题描述】:

我想知道是否有更简单的解决方案可以将一些 JSON 取消嵌套到数据框中。我有来自 API 的以下 JSON:

library(tidyverse)
library(jsonlite)

json <- '{   
  "result": {
    "id": "id_1",     
    "description": "description",     
    "var1": {       
        "var1Id": "a",       
        "var1Title": "aTitle"     
    },     
    "var2": {       
        "var1Id": "b",       
        "var2Title": "bTitle"     
    },     
    "var3": {       
        "var3Id": "c",       
        "var3Info": "c123",       
        "var3Type": "cType"     
    },     
    "var4": {       
        "var4Lvl2": [         
          {           
              "var4Id": "d",           
              "var4Title": "dTitle"         
            },         
          {  
              "var4Id": "d2", 
              "var4Title": "d2Title"         
          }       
        ]     
    }   
  }
}'

接下来我通常把它变成一个小标题,然后开始为每个列表列使用tidyr::unnest_wider

## Note I use bind_rows to simulate how my actual data looks

json2 <- json %>%
    fromJSON() %>%
    tibble() %>%
    bind_rows(fromJSON(json) %>% tibble()) 


json2 %>%
    unnest_wider(".") %>%
    unnest_wider("var1", names_sep = "_") %>%
    unnest_wider("var2", names_sep = "_") %>%
    unnest_wider("var3", names_sep = "_") %>%
    unnest_wider("var4", names_sep = "_") %>%
    unnest_wider("var4_var4Lvl2") %>%
    unnest_wider("var4Id", names_sep = "_") %>%
    unnest_wider("var4Title", names_sep = "_")

上述过程运行良好,但我觉得有一种更简单的方法可以取消所有这些列的嵌套,而无需输入各个列名。请注意,列数和列名可能会根据特定的 API 查询而变化,因此可以处理这些变化的解决方案会很棒。

【问题讨论】:

  • 我不是复制你的例子的例子。 json2 是一个带有一个变量 . 和两条记录的小标题。 unnest 命令给出错误Error: Can't extract columns that don't exist. x Column 'var1' doesn't exist. 我正在使用最新版本的 tidyverse 包和 jsonlite。
  • 对不起 - 错过了从我的脚本中复制它的一行。现在应该可以正常工作了。

标签: r tidyr jsonlite


【解决方案1】:

最终找到akrun's answer here。我做了一个函数来取消嵌套所有可以顺序使用的嵌套列表列层。

## create unnest_all function
unnest_all <- function(data){
  list_cols <- names(select(data, where(is.list)))
  data_non_list <- data %>%
    select(!where(is.list)) 
  
  if(length(list_cols) != 0){  
    map_dfc(list_cols, ~
              data %>%
              select(.x) %>%
              unnest_wider(c(!!.x), names_sep= "_", names_repair = 'unique')) %>%
      bind_cols(data_non_list, .) 
  } else {
    data %>%
      janitor::clean_names() 
  }
}

## use on json data
json %>%
  fromJSON() %>%
  tibble() %>%
  bind_rows(fromJSON(json) %>% tibble()) %>%
  unnest_wider(".") %>%
  unnest_all() %>%
  unnest_all() %>%
  unnest_all()

【讨论】:

    猜你喜欢
    • 2022-01-10
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 2019-10-18
    • 2018-09-16
    • 1970-01-01
    相关资源
    最近更新 更多