16

I work more and more with highly nested lists such as:

mynestedlist<-list(list(LETTERS,month.name),list(list(seq(1,100,5),1,1),seq(1,100,5),seq(1,100,5)))

and sometimes I struggle to understand the structure of the list I am working on. I was wondering if there is any way to display the hierarchical structure of a list, using dendrogram-like graphs maybe.

I know I can use str to print the structure of a list:

str(mynestedlist,max.level=1)

However, a graphical way to display lists would be more useful!

matmar
  • 318
  • 2
  • 13

2 Answers2

18

You may check the data.tree package. It allows to print nested list pretty nicely and it doesn't need you to write complicated function. Here is an example:

library(data.tree)
> dt <- FromListSimple(mynestedlist)
> dt
  levelName
1 Root     
2  ¦--1    
3  °--2    
4      °--1

This allows you to check at the level of list, and you can combine this with str to get a full picture of your list structure.

Psidom
  • 209,562
  • 33
  • 339
  • 356
  • This might help you to understand it even better: `print(tree, fields = function(n) paste(n$fields, collapse = ", "))` . It gets a bit head-twisting because neither sub-lists nor elements are named, so data.tree simply assigns running numbers to both. So named list elements would indeed make things much easier, if possible at all. – Christoph Glur May 17 '16 at 14:21
  • 1
    data.tree definitely helps to interpret the structure of nested lists, thanks Psidom! – matmar May 19 '16 at 13:06
6

You could also do some nifty recursion if you want:

get_str_recur <- function(x,text2,y){

  text <- paste0(text2,"Element[",y,"] is a List of length ",length(x), " --> ")

  for (i in (1:(length(x)))){
    subs <- x[[i]]
    if (is.list(subs)){
      get_str_recur(subs,text,i)

    }else{
      print(paste0(text," Element [",i,"] is a ",class(subs)," of length ",length(subs)))
    }
  }
}
get_str_recur(mynestedlist,"",0)

#[1] "Element[0] is a List of length 2 --> Element[1] is a List of length 2 --#>  Element [1] is a character of length 26"
#[1] "Element[0] is a List of length 2 --> Element[1] is a List of length 2 -->  #Element [2] is a character of length 12"
#[1] "Element[0] is a List of length 2 --> Element[2] is a List of length 3 --> #Element[1] is a List of length 3 -->  Element [1] is a numeric of length 20"
#[1] "Element[0] is a List of length 2 --> Element[2] is a List of length 3 --> #Element[1] is a List of length 3 -->  Element [2] is a numeric of length 1"
#[1] "Element[0] is a List of length 2 --> Element[2] is a List of length 3 --> #Element[1] is a List of length 3 -->  Element [3] is a numeric of length 1"
#[1] "Element[0] is a List of length 2 --> Element[2] is a List of length 3 -->  #Element [2] is a numeric of length 20"
#[1] "Element[0] is a List of length 2 --> Element[2] is a List of length 3 -->  #Element [3] is a numeric of length 20"

This provides a nice visual flow chart of each branch of your list tree.

Mike H.
  • 13,960
  • 2
  • 29
  • 39