21

Is there an easy way (i.e. a function) to determine the level of nesting in list? I know there is str which can be used to get this information. But is there something that simply gives back the result? And can I use such a function to get the names of all levels of alist (recursively) ?

Matt Bannert
  • 26,475
  • 36
  • 138
  • 202

4 Answers4

24

A little recursive function can do this for you:

depth <- function(this,thisdepth=0){
  if(!is.list(this)){
    return(thisdepth)
  }else{
    return(max(unlist(lapply(this,depth,thisdepth=thisdepth+1))))    
  }
}

If you've got package:testthat, here's a test set:

l1=list(1,2,3)
l2=list(1,2,l1,4)
l3=list(1,l1,l2,5)

require(testthat)
expect_equal(depth(l1),1)
expect_equal(depth(l2),2)
expect_equal(depth(l3),3)

Apologies for using lower-case L in variable names. Readability fail.

Spacedman
  • 89,688
  • 12
  • 125
  • 209
6

You can now use depth() from the purrr package!

Note: currently the function is part of the development version of purrr but will become part of the official CRAN version once the package gets a version bump

Manuel R
  • 3,616
  • 4
  • 23
  • 41
  • 6
    I think its now in CRAN as `purrr::vec_depth`, but there's also `plotrix::listDepth` – Spacedman Mar 13 '18 at 10:36
  • `listDepth` was removed from the `plotrix` package in version 3.8-1. But +1 for `purrr::vec_depth`, which gets the job done. – dbc Sep 23 '21 at 15:14
2

If all elements are named, you could use this (from the code of unlist):

mylist <- list(a=list(x=1),b=list(c=list(y=c(2,3)),d=c("a","b")))
names(.Internal(unlist(mylist, TRUE, TRUE)))
#[1] "a.x"    "b.c.y1" "b.c.y2" "b.d1"   "b.d2" 
Roland
  • 122,144
  • 10
  • 182
  • 276
0

Another approach using rrapply() in the rrapply-package (extension of base rapply()):

library(rrapply)

l1 <- list(1, 2, 3)
l2 <- list(1, 2, l1, 4)
l3 <- list(1, l1, l2, 5)

max(rrapply(l1, f = function(x, .xpos) length(.xpos), how = "unlist"))
#> [1] 1
max(rrapply(l2, f = function(x, .xpos) length(.xpos), how = "unlist"))
#> [1] 2
max(rrapply(l3, f = function(x, .xpos) length(.xpos), how = "unlist"))
#> [1] 3
Joris C.
  • 4,801
  • 3
  • 10
  • 24