Home > Mobile >  Recursive R function to flatten hierarchical json dataset
Recursive R function to flatten hierarchical json dataset

Time:08-05

I have a json file that looks like this:

{
  "data": [
    {
      "sense": "a_lot.r.01",
      "frequency": 20,
      "level": 0,
      "childrenSenses": []
    },
    {
      "sense": "succeed.v.01",
      "frequency": 64,
      "level": 0,
      "childrenSenses": [
        {
          "sense": "achieve.v.01",
          "frequency": 21,
          "level": 1,
          "childrenSenses": [
            {
              "sense": "reach.v.07",
              "frequency": 12,
              "level": 2,
              "childrenSenses": []
            },
            {
              "sense": "come_to.v.03",
              "frequency": 5,
              "level": 2,
              "childrenSenses": []
            }
          ]
        },
        {
          "sense": "pull_off.v.03",
          "frequency": 14,
          "level": 1,
          "childrenSenses": []
        },
        {
          "sense": "arrive.v.02",
          "frequency": 10,
          "level": 1,
          "childrenSenses": []
        },
        {
          "sense": "work.v.03",
          "frequency": 15,
          "level": 1,
          "childrenSenses": []
        }
      ]
    }
  ]
}

I need a recursive function that will build a single dataframe that contains 4 fields out of a json file of this structure with any number of levels of parent-child relationships:

the dataframe will have 4 fields described as:

id: contains the value of "sense"
label: also contains the value of "sense"
parent: contains the value of the parent "sense"
value: contains the value of the "frequency" for the sense

CodePudding user response:

The code below is my implementation of my question above. The recursive function loop_tree will traverse the structure to whatever level required and build a single dataframe containing the data as I require it. I was struggling to try and do it with lapply and mapply but I just couldnt get it to work like that. Maybe someone else can do a better implementation now its clearer what I was looking for.

library(tidyverse)
library(jsonlite)

nestedjson<-fromJSON("./file.json", flatten = TRUE)
df <- as.data.frame(nestedjson$data)


loop_tree <- function(node, parent) {
 
  bld <- setNames(data.frame(matrix(ncol = 4, nrow = 0)), c("parent", "id","label", "value"))
  for(i in 1:nrow(node)) {       # for-loop over rows
    row <- node[i,]
    
   bld[nrow(bld)  1,] <- c(parent,row$sense,row$sense,row$frequency)
   if (length(row$childrenSenses[[1]])>0)
   {
      bldchld <- loop_tree(row$childrenSenses[[1]], row$sense )
      bld <- rbind(bld,bldchld)
   }
     
  }
  return(bld)
}

loopdf <- loop_tree(df,"root")
  • Related