使用 purrr 递归处理任意层次结构 [英] Processing arbitrary hierarchies recursively with purrr

查看:46
本文介绍了使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆