Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Find which elements of a nested list are dataframes

Suppose that I have a nested list like the following

test <- list(
  a = data.frame(x = 1),
  b = "foo",
  c = list(
    d = 1:5,
    e = data.frame(y = 1),
    f = "a",
    list(g = "hello")
  )
)
test
#> $a
#>   x
#> 1 1
#> 
#> $b
#> [1] "foo"
#> 
#> $c
#> $c$d
#> [1] 1 2 3 4 5
#> 
#> $c$e
#>   y
#> 1 1
#> 
#> $c$f
#> [1] "a"
#> 
#> $c[[4]]
#> $c[[4]]$g
#> [1] "hello"

I want to know the location of character elements in this nested list. In this
case, I want to return a named vector or a named list with TRUE if the element
is a character and FALSE otherwise.

I can do that with rapply, that unlists everything:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

rapply(test, is.character)
#>   a.x     b   c.d c.e.y   c.f   c.g 
#> FALSE  TRUE FALSE FALSE  TRUE  TRUE

However, I can’t do that to find all dataframes because rapply() also unlists
dataframes (note that the first element is a.x and not only a).

rapply(test, is.data.frame)
#>   a.x     b   c.d c.e.y   c.f   c.g 
#> FALSE FALSE FALSE FALSE FALSE FALSE

Therefore, is there a way to find which elements of a nested list are dataframes?
Note that the solution should work with any number of levels in the nested
list.

I’m looking for a solution in base R only.

>Solution :

1) rrapply

library(rrapply)

cls <- c("data.frame", "ANY")
rrapply(test, f = is.data.frame, classes = cls, how = "unlist")
##     a     b   c.d   c.e   c.f   c.g 
##  TRUE FALSE FALSE  TRUE FALSE FALSE 

2) recursion

findDF <- function(x) {
  if (is.data.frame(x)) TRUE
  else if (is.list(x)) lapply(x, findDF)
  else FALSE
}

unlist(findDF(test))
##     a     b   c.d   c.e   c.f   c.g 
##  TRUE FALSE FALSE  TRUE FALSE FALSE 
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading