我在R中有一个列表:
my_list <- list(a = 1, b = 2, c = list(d = 4, e = 5))
Run Code Online (Sandbox Code Playgroud)
假设我不知道列表的结构,但我知道在这个列表的某个地方,有一个名为d嵌套或不嵌套的元素.我想要:
c)是否有一个简单的方法/包可以解决这个看似简单的问题?
这是另一种递归方法,与 @JosephWood 的答案非常相似,它概括了解决方案,以便您可以同时搜索多个元素,并找到所有匹配元素(如果有多个):
find_all <- function(x, elements) {
lists <- vapply(x, is.list, logical(1)) # find sublists
# find all elements in sublists
out <- lapply(x[lists], find_all, elements)
out <- out[!vapply(out, is.null, logical(1))]
# output any found elements
if (any(elements %in% names(x)))
out <- c(out, x[names(x) %in% elements])
if (length(out) == 0) NULL else out
}
Run Code Online (Sandbox Code Playgroud)
示例问题:
my_list <- list(a = 1, b = 2, c = list(d = 4, e = 5))
str(find_all(my_list, "e"))
#> List of 1
#> $ c:List of 1
#> ..$ e: num 5
Run Code Online (Sandbox Code Playgroud)
@JosephWood 的奇异例子更加复杂:
exotic_list <-
list(
a = 1,
b = 2,
c = list(d = 4, e = 5),
f = list(g = 6, h = list(k = 7, j = 8)),
l = list(m = 6, n = list(o = 7, p = 8)),
q = list(r = 5, s = 11),
t = 12,
n = 13
)
str(find_all(exotic_list, c("n", "q")))
#> List of 3
#> $ l:List of 1
#> ..$ n:List of 2
#> .. ..$ o: num 7
#> .. ..$ p: num 8
#> $ q:List of 2
#> ..$ r: num 5
#> ..$ s: num 11
#> $ n: num 13
Run Code Online (Sandbox Code Playgroud)
purrr包,我们还可以去掉vapplys,使函数更加简洁,也许也更具可读性:
library(purrr)
find_all2 <- function(x, elements) {
# find all elements in sublists
out <- map(keep(x, is.list), find_all, elements)
out <- compact(out) # drop nulls
# output any found elements
if (any(elements %in% names(x)))
out <- c(out, x[names(x) %in% elements])
if (length(out) == 0) NULL else out
}
identical(
find_all(exotic_list, c("n", "q")),
find_all2(exotic_list, c("n", "q"))
)
#> [1] TRUE
Run Code Online (Sandbox Code Playgroud)
由reprex 包(v0.2.0)于 2018 年 3 月 15 日创建。