Return nested list with nested level and value
nested-lists, networkd3, r, recursion
Solution
Using a `data.table`-style merge:
library(data.table)
dt = data.table(idx=1:length(value), level, parent=value)
dt = dt[dt[, .(i=idx, level=level-1, child=parent)], on=.(level, idx < i), mult='last']
dt[is.na(parent), parent:= 'root'][, c('idx','level'):= NULL]
> dt
# parent child
# 1: root a
# 2: a b
# 3: b c
# 4: c d
# 5: c e
# 6: b f
# 7: f g
# 8: f h
# 9: root i
# 10: i j
# 11: j k
Now we can use the solution from the other post:
x = maketreelist(as.data.frame(dt))
> identical(x, my_list)
# [1] TRUE
Problem
I would like to visualize some deeply nested data using networkD3. I can't figure out how to get the data into the right format before sending to `radialNetwork`. Here is some sample data: ``` level <- c(1, 2, 3, 4, 4, 3, 4, 4, 1, 2, 3) value <- letters[1:11] ``` where `level` indicates the level of the nest, and `value` is the name of the node. By using these two vectors, I need to get the data into the following format: ``` my_list <- list( name = "root", children = list( list( name = value[1], ## a children = list(list( name = value[2], ## b children = list(list( name = value[3], ## c children = list( list(name = value[4]), ## d list(name = value[5]) ## e ) ), list( name = value[6], ## f children = list( list(name = value[7]), ## g list(name = value[8]) ## h ) )) )) ), list( name = value[9], ## i children = list(list( name = value[10], ## j children = list(list( name = value[11] ## k )) )) ) ) ) ``` Here is the deparsed object: ``` > dput(my_list) # structure(list(name = "root", # children = list( # structure(list( # name = "a", # children = list(structure( # list(name = "b", # children = list( # structure(list( # name = "c", children = list( # structure(list(name = "d"), .Names = "name"), # structure(list(name = "e"), .Names = "name") # ) # ), .Names = c("name", # "children")), structure(list( # name = "f", children = list( # structure(list(name = "g"), .Names = "name"), # structure(list(name = "h"), .Names = "name") # ) # ), .Names = c("name", # "children")) # )), .Names = c("name", "children") # )) # ), .Names = c("name", # "children")), structure(list( # name = "i", children = list(structure( # list(name = "j", children = list(structure( # list(name = "k"), .Names = "name" # ))), .Names = c("name", # "children") # )) # ), .Names = c("name", "children")) # )), # .Names = c("name", # "children")) ``` Then I can pass it to the final plotting function: ``` library(networkD3) radialNetwork(List = my_list) ``` The output will look similar to this: Question: How can I create the nested list? Note: As pointed out by @zx8754, there is already a solution in this SO post, but that requires `data.frame` as input. Due to the inconsistency in my `level`, I don't see a simple way to transform it into a `data.frame`.