Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display names of column of recursive list as tree

Tags:

r

Is there a (built'in/easy) way to recursively display the names of a interlinked list as a tree? (with possibly an output similar to the tree shell command. )

For instance with list X, with two column A and B, A consiting in two subcolumn a1 and a2

nametree(x)
X
├── A
│   ├── a1
│   └── a2
└── B

names(X) would just display [1] "A" "B"

like image 768
AdrieanKhisbe Avatar asked Aug 08 '13 09:08

AdrieanKhisbe


2 Answers

Here is a recursive solution:

nametree <- function(X, prefix = "")
  if( is.list(X) )
    for( i in seq_along(X) ) { 
      cat( prefix, names(X)[i], "\n", sep="" )
      nametree(X[[i]], paste0(prefix, "  "))
    }
X <- list(X = list( A = list( a1=1:10, a2=1:10 ), B = 1:10 ))
nametree(X)
# X
#   A
#     a1
#     a2
#   B

Displaying the tree structure with branches rather than spaces is slightly trickier:

nametree <- function(X, prefix1 = "", prefix2 = "", prefix3 = "", prefix4 = "")
  if( is.list(X) )
    for( i in seq_along(X) ) { 
      cat( if(i<length(X)) prefix1 else prefix3, names(X)[i], "\n", sep="" )
      prefix <- if( i<length(X) ) prefix2 else prefix4
      nametree(
        X[[i]], 
        paste0(prefix, "├──"),
        paste0(prefix, "│  "),
        paste0(prefix, "└──"),
        paste0(prefix, "   ")
      )
    }
nametree(X)
# X
# +--A
# ¦  +--a1
# ¦  +--a2
# +--B
# +--C
#    +--a
#    +--b
like image 162
Vincent Zoonekynd Avatar answered Oct 23 '22 23:10

Vincent Zoonekynd


A simple example:

> mylist <- list(A=data.frame(A1=1:3,A2=4:6),B=7:9)
> out <- lapply(mylist,names)
$A
[1] "A1" "A2"

$B
NULL

This assumes you only have dataframes one level below the list...so it's not recursive per se, but it sounds like this is similar to your data structure.

DrMike and Henrik's suggestion to use str(mylist) will be recursive and is, in fact, able to control both how deep into the structure and the display of the output.

SimonO101's example of recursion:

> df <- data.frame( A = runif(3) , B = runif(3) )
> ll <- list( A = df , B = list( C = df , D = df ) , E = 1 )
> str(ll)
List of 3
 $ A:'data.frame':      3 obs. of  2 variables:
  ..$ A: num [1:3] 0.948 0.356 0.467
  ..$ B: num [1:3] 0.2319 0.7574 0.0312
 $ B:List of 2
  ..$ C:'data.frame':   3 obs. of  2 variables:
  .. ..$ A: num [1:3] 0.948 0.356 0.467
  .. ..$ B: num [1:3] 0.2319 0.7574 0.0312
  ..$ D:'data.frame':   3 obs. of  2 variables:
  .. ..$ A: num [1:3] 0.948 0.356 0.467
  .. ..$ B: num [1:3] 0.2319 0.7574 0.0312
 $ E: num 1

Some examples of output:

> str(mylist)
List of 2
 $ A:'data.frame':      3 obs. of  2 variables:
  ..$ A1: int [1:3] 1 2 3
  ..$ A2: int [1:3] 4 5 6
 $ B: int [1:3] 7 8 9

> str(mylist, give.attr=FALSE, give.length=FALSE, give.head=FALSE, vec.len=0, 
indent.str="|", comp.str="----")
List of 2
|----A:'data.frame':    3 obs. of  2 variables:
| ..$ A1:NULL ...
| ..$ A2:NULL ...
|----B:NULL ...
like image 44
Thomas Avatar answered Oct 24 '22 00:10

Thomas