Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return nested list with nested level and value

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:

enter image description here


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.

like image 918
Boxuan Avatar asked Dec 15 '16 05:12

Boxuan


People also ask

How do you extract an element from a nested list in Python?

Approach #2 : Using zip and unpacking(*) operator This method uses zip with * or unpacking operator which passes all the items inside the 'lst' as arguments to zip function. Thus, all the first element will become the first tuple of the zipped list. Returning the 0th element will thus, solve the purpose.

How do I add a value to a nested list?

To add new values to the end of the nested list, use append() method. When you want to insert an item at a specific position in a nested list, use insert() method. You can merge one list into another by using extend() method. If you know the index of the item you want, you can use pop() method.

How do I print a nested list in Python?

Method-1 :join() operator. Inner print with a comma ensures that inner list's elements are printed in a single line. Outer print ensures that for the next inner list, it prints in next line.


1 Answers

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
like image 59
sirallen Avatar answered Oct 05 '22 06:10

sirallen