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:
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:
BONUS
If there are already children it should append the new data to the existing children.