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"