Home > Enterprise >  How to keep list elements at a certain list depth level
How to keep list elements at a certain list depth level

Time:08-31

I have a list with many levels. I want to only keep elements at the 1st level.

Example list:

 my_list <-
   list(
    a.1 = "some text",
    b.1 = NA,
    c.1 = integer(0),
    d.1 = "some text",
    e.1 = list(a.2 = "some text", b.2 = "a2"),
    f.1 = list(c.2 = "some text", d.2 = integer(10), e.2 = list(a.3 = "some deep text"))
   )

... and I'd like to end up with:

 my_list2 <-
   list(
     a.1 = "some text",
     b.1 = NA,
     c.1 = integer(0),
     d.1 = "some text"
   )

Given the real list is messy and many levels deep I'd like to be able to use something like purrr::keep to simply remove further nested items.

I have tried using keep but the predicate functions throw back errors:

 map_depth(my_list, 1, ~ keep(.x, vec_depth(.x) > 1))

 Error in probe(.x, .p, ...) : length(.p) == length(.x) is not TRUE

Thanks.

CodePudding user response:

Or maybe this solution in tidyverse:

library(purrr)

my_list %>% 
  keep(~ vec_depth(.x) == 1)

$a.1
[1] "some text"

$b.1
[1] NA

$c.1
integer(0)

$d.1
[1] "some text"

CodePudding user response:

You could subset your list to only include items that are not themselves lists using:

my_list[!sapply(my_list, is.list)]
#> $a.1
#> [1] "some text"
#>
#> $b.1
#> [1] NA
#>
#> $c.1
#> integer(0)
#>
#> $d.1
#> [1] "some text"

CodePudding user response:

Using collapse::atomic_elem to "to extract [...] the atomic [...] elements at the top-level of the list tree"

collapse::atomic_elem(my_list)
# $a.1
# [1] "some text"
#
# $b.1
# [1] NA
#
# $c.1
# integer(0)
# 
# $d.1
# [1] "some text"
  • Related