Home > OS >  Retaining only a specific list(s) in a list of lists by name
Retaining only a specific list(s) in a list of lists by name

Time:10-09

I saw this implementation to iteratively remove NA lists in a list of lists as shown with remove_empty. I was hoping to use a similar implementation and structure to actually check for a specific named list and keep that while discarding the rest. Is there a simple way to adjust my find_specific_list to accomplish this task?

library(tidyverse)

x <- list(seta = c(lista = list(c("A", "B"),
                                listb = NA, 
                                listc = NA, 
                                listd = NA)), 
          setb = c(lista2 = list(c("C","E"), 
                                 listb2 = NA, 
                                 listc2 = "D", 
                                 listd2 = NA, 
                                 liste2 = NA))
)

remove_empty <- function(x){
  if(is.list(x)) {
    x %>%
      purrr::discard(rlang::is_na) %>%
      purrr::map(remove_empty)
  } else {
    x
  }
}


remove_empty(x)
#> $seta
#> $seta$lista1
#> [1] "A" "B"
#> 
#> 
#> $setb
#> $setb$lista21
#> [1] "C" "E"
#> 
#> $setb$lista2.listc2
#> [1] "D"



find_specific_list <- function(x,y){
  
  if(is.list(x)) {
    x %>%
      purrr::discard(function(x){
        names(x) == y
      })%>%
      purrr::map(find_specific_list)
  } else {
    x
  }
}



y <- "lista21"

find_specific_list(x,y)
#> Error in `.f()`:
#> ! Predicate functions must return a single `TRUE` or `FALSE`, not a logical vector of length 4

Created on 2022-10-06 by the reprex package (v2.0.1)

CodePudding user response:

Not 100% sure about your desired final result but here is one possible approach:

library(purrr)

find_specific_list <- function(x, y) {
  if (is.list(x)) {
    ret <- if (!y %in% names(x)) {
      purrr::map(x, find_specific_list, y = y)
    } else {
      x[y]
    }
  } else {
    ret <- list()
  }
  purrr::discard(ret, is_empty)
}

y <- "lista21"

find_specific_list(x, y)
#> $setb
#> $setb$lista21
#> [1] "C" "E"
  • Related