Recursive function to add children to nested list

I am working on making nested lists for visualisation in a tree map. For this, I am looking for a recursive function that can insert new children based on a key match

To illustrate let's say we have the below nested list

# hierarchy with dataframes
level1 <- data.frame(name = c("gp1", "gp2","gp3"), value = c(30, 40, 30)) # granpa
level11 <- data.frame(name = c("pA", "pB"), value = c(10,20))   # 2nd level parent
level12 <- data.frame(name = c("pD", "pE"), value = c(20,20))
level111 <- data.frame(name = c("c1", "c2"), value = c(3,7))    # 3rd level child
level112 <- data.frame(name = c("c3", "c4"), value = c(10,5))
level1121 <- data.frame(name = c("b1", "b2"), value = c(2,6))   # 4th level baby
level112[1, "children"][[1]] <- list(level1121)
level11[1, "children"][[1]] <- list(level111)
level11[2, "children"][[1]] <- list(level112)
level1[1, "children"][[1]] <- list(level11)
level1[2, "children"][[1]] <- list(level12)

When we convert this to a JSON it will look like this:

library(jsonify)
jsonlite::toJSON(level1, pretty = TRUE, auto_unbox = TRUE)
[
  {
    "name": "gp1",
    "value": 30,
    "children": [
      {
        "name": "pA",
        "value": 10,
        "children": [
          {
            "name": "c1",
            "value": 3
          },
          {
            "name": "c2",
            "value": 7
          }
        ]
      },
      {
        "name": "pB",
        "value": 20,
        "children": [
          {
            "name": "c3",
            "value": 10,
            "children": [
              {
                "name": "b1",
                "value": 2
              },
              {
                "name": "b2",
                "value": 6
              }
            ]
          },
          {
            "name": "c4",
            "value": 5,
            "children": {}
          }
        ]
      }
    ]
  },
  {
    "name": "gp2",
    "value": 40,
    "children": [
      {
        "name": "pD",
        "value": 20
      },
      {
        "name": "pE",
        "value": 20
      }
    ]
  },
  {
    "name": "gp3",
    "value": 30,
    "children": {}
  }
]

And the tree graph will look as follows:

Screenshot 2022-10-28 at 10 27 03

As you can see it gets very confusing to add extra child elements and I am looking for a function that can recursively go through the nested list and add a new child based on a key match (level independent).
Something like this:

# 5th level baby
level11211 <- data.frame(name = c("d1", "d2"), value = c(5,6))   # 5th level baby

child_map <- function(df, key, value, children){
if(key == value){
#add children to df 
}
level1_mapped <- child_map(level1, "name", "b1", level11211)
library(jsonify)
jsonlite::toJSON(level1_mapped, pretty = TRUE, auto_unbox = TRUE)
[
  {
    "name": "gp1",
    "value": 30,
    "children": [
      {
        "name": "pA",
        "value": 10,
        "children": [
          {
            "name": "c1",
            "value": 3
          },
          {
            "name": "c2",
            "value": 7
          }
        ]
      },
      {
        "name": "pB",
        "value": 20,
        "children": [
          {
            "name": "c3",
            "value": 10,
            "children": [
              {
                "name": "b1",
                "value": 2,
                "children": [  #New children added based on "b1"key match
                  {
                    "name": "d1",
                    "value": 5
                  },
                  {
                    "name": "d2",
                    "value": 6
                  }
                ]
              },
              {
                "name": "b2",
                "value": 6,
                "children": {}
              }
            ]
          },
          {
            "name": "c4",
            "value": 5,
            "children": {}
          }
        ]
      }
    ]
  },
  {
    "name": "gp2",
    "value": 40,
    "children": [
      {
        "name": "pD",
        "value": 20
      },
      {
        "name": "pE",
        "value": 20
      }
    ]
  },
  {
    "name": "gp3",
    "value": 30,
    "children": {}
  }

And the updated tree will look like this:

Screenshot 2022-10-28 at 10 25 38

BONUS

If there are already children it should append the new data to the existing children.

The rlist package has useful functions for working with lists.

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.