Je me demande s'il existe une solution plus simple pour désimbriquer du JSON dans une trame de données. J'ai le JSON suivant d'une API :

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"         
          }       
        ]     
    }   
  }
}'

Ensuite, je le transforme généralement en un tibble, puis je commence à utiliser tidyr::unnest_wider pour chaque colonne de la liste :

## 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 = "_")

Le processus ci-dessus fonctionne très bien, mais j'ai l'impression qu'il existe un moyen plus simple de désimbriquer toutes ces colonnes sans avoir à entrer des noms de colonnes individuels. Notez que le nombre de colonnes et les noms de colonnes peuvent changer en fonction de la requête API spécifique, donc une solution capable de gérer ces variations serait idéale.

0
Chad Peltier 10 nov. 2020 à 20:59

1 réponse

Meilleure réponse

J'ai finalement trouvé la réponse d'akrun ici. J'ai créé une fonction pour désimbriquer tout ce qui peut être utilisé séquentiellement pour chaque couche de colonnes de liste imbriquées.

## 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()

0
Chad Peltier 8 déc. 2020 à 21:39