使用 purrr 递归处理任意层次结构 [英] Processing arbitrary hierarchies recursively with purrr
问题描述
假设我想根据某个特定标准修剪由 R 中嵌套列表的层次结构组成的树.我可以使用 lapply
来轻松"地做到这一点:
Suppose that I wanted to prune a tree consisting of a hierarchy of nested lists in R, based on some particular criterion. I can do this "easily" enough using lapply
:
# Based an example from the NetworkD3 documentation
# https://christophergandrud.github.io/networkD3/
URL <- paste0(
"https://cdn.rawgit.com/christophergandrud/networkD3/",
"master/JSONdata//flare.json")
flare <- jsonlite::fromJSON(URL, simplifyDataFrame = FALSE)
# Leaf nodes have a "size" attribute. Let's say we want to
# prune all the nodes with size < 5000.
prune <- function(tree) {
if ("children" %in% names(tree)) {
p <- lapply(tree$children, prune)
pp <- p[!unlist(lapply(p, is.null))]
copied_tree = list()
copied_tree$name = tree$name
copied_tree$children = pp
return(copied_tree)
} else if (tree$size < 5000) {
return(NULL)
}
return(tree)
}
pruned <- prune(flare)
在 R for Data Science 中,Hadley Wickham 讨论 purrr
可以代替 apply
函数系列来处理分层数据的许多场景.然而,这些例子似乎要么处理单嵌套列表,要么处理深度嵌套列表的特定节点.
In R for Data Science, Hadley Wickham discusses a number of scenarios in which purrr
can replace the apply
family of functions for handling hierarchical data. However, these examples seem to deal either with singly nested lists, or with specific nodes of deeply nested lists.
有没有办法使用 purrr
来完成上面讨论的递归任务?
Is there a way to use purrr
to accomplish recursive tasks such as the one discussed above?
推荐答案
library(purrr)
prune_2 <- function(tree) {
# print(tree$name)
# print(map_lgl(tree$children, ~ "size" %in% names(.x)))
tree$children %<>%
map_if(~ "children" %in% names(.x), prune_2) %>%
discard(~ if ("size" %in% names(.x)) .x$size < 5000 else FALSE)
tree
}
pruned_2 <- prune_2(flare)
identical(pruned, pruned_2)
# [1] TRUE
这篇关于使用 purrr 递归处理任意层次结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!