Method to insert new elements
nvelden opened this issue · 1 comments
I am working on making nested lists for visualisation in a tree map. For this, I was wondering if it would be possible using your package to insert new elements into nested lists by key matching.
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 it would be very helpful if I could use your package to for instance do something like this:
# 5th level baby
level11211 <- data.frame(name = c("d1", "d2"), value = c(5,6)) # 5th level baby
child1 <- rrapply(
child1,
condition = \(x, .xname)
.xname == "b1", # Insert new children where name == "b1"
f = \(x) list(children = level11211),
how = "insert"
)
@nvelden: it seems this can be done using the (default) option how = "replace"
,
## insert new children data.frame
level1 <- rrapply(
level1,
classes = c("list", "data.frame"),
condition = \(x) "b1" %in% x$name,
f = \(x) { x[x$name == "b1", "children"][[1]] <- list(level11211); x }
)
str(level1)
#> 'data.frame': 3 obs. of 3 variables:
#> $ name : chr "gp1" "gp2" "gp3"
#> $ value : num 30 40 30
#> $ children:List of 3
#> ..$ :'data.frame': 2 obs. of 3 variables:
#> .. ..$ name : chr "pA" "pB"
#> .. ..$ value : num 10 20
#> .. ..$ children:List of 2
#> .. .. ..$ :'data.frame': 2 obs. of 2 variables:
#> .. .. .. ..$ name : chr "c1" "c2"
#> .. .. .. ..$ value: num 3 7
#> .. .. ..$ :'data.frame': 2 obs. of 3 variables:
#> .. .. .. ..$ name : chr "c3" "c4"
#> .. .. .. ..$ value : num 10 5
#> .. .. .. ..$ children:List of 2
#> .. .. .. .. ..$ :'data.frame': 2 obs. of 3 variables:
#> .. .. .. .. .. ..$ name : chr "b1" "b2"
#> .. .. .. .. .. ..$ value : num 2 6
#> .. .. .. .. .. ..$ children:List of 2
#> .. .. .. .. .. .. ..$ :'data.frame': 2 obs. of 2 variables:
#> .. .. .. .. .. .. .. ..$ name : chr "d1" "d2"
#> .. .. .. .. .. .. .. ..$ value: num 5 6
#> .. .. .. .. .. .. ..$ : NULL
#> .. .. .. .. ..$ : NULL
#> ..$ :'data.frame': 2 obs. of 2 variables:
#> .. ..$ name : chr "pD" "pE"
#> .. ..$ value: num 20 20
#> ..$ : NULL
If you think a separate option (e.g. how = "insert"
) is required for this purpose, perhaps you could share an example where the current options how = "replace"
and/or how = "list"
would be insufficient? Thanks!