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`.

Original source

Related problems