如何在R语言中按名称提取嵌套列表的终端ID
问题
给定如下数据集:
data <- data.frame("group1" = c(rep("a",10),rep("b",10)),"group2" = c(rep(c("a","b"),5),rep(c("c","d"),5)))
数据预览:
group1 group2 1 a a 2 a b 3 a a 4 a b 5 a a 6 a b 7 a b 8 a b 9 a a 10 a b 11 b c 12 b d 13 b c 14 b d 15 b c 16 b d 17 b c 18 b d 19 b c 20 b d
通过shinyWidgets包的create_tree函数生成树形列表:
tree <- create_tree(data)
树形列表结构:
str(tree) # List of 2 # $ :List of 3 # ..$ text : chr "a" # ..$ id : chr "tree7337428" # ..$ children:List of 2 # .. ..$ :List of 2 # .. .. ..$ text: chr "a" # .. .. ..$ id : chr "tree7904513" # .. ..$ :List of 2 # .. .. ..$ text: chr "b" # .. .. ..$ id : chr "tree7346861" # $ :List of 3 # ..$ text : chr "b" # ..$ id : chr "tree6379478" # ..$ children:List of 2 # .. ..$ :List of 2 # .. .. ..$ text: chr "c" # .. .. ..$ id : chr "tree500704" # .. ..$ :List of 2 # .. .. ..$ text: chr "d" # .. .. ..$ id : chr "tree8058601"
需要提取终端节点的id,生成如下结果数据集:
group1 group2 tree_id 1 a a tree7904513 2 a b tree7346861 3 b c tree500704 4 b d tree8058601
解决方案
方法一:使用purrr包简洁提取
利用purrr::map_dfr遍历嵌套树形结构,逐层提取父节点与终端子节点的信息,直接拼接成目标格式:
library(purrr) result <- map_dfr(tree, function(parent_node) { map_dfr(parent_node$children, function(child_node) { data.frame( group1 = parent_node$text, group2 = child_node$text, tree_id = child_node$id, stringsAsFactors = FALSE ) }) }) # 输出结果 result
方法二:基础R循环实现
如果不想依赖第三方包,用基础R的双重循环也能完成提取:
# 初始化空数据框 result <- data.frame( group1 = character(), group2 = character(), tree_id = character(), stringsAsFactors = FALSE ) # 遍历顶层节点 for (i in seq_along(tree)) { parent <- tree[[i]] # 遍历终端子节点 for (j in seq_along(parent$children)) { child <- parent$children[[j]] result <- rbind(result, data.frame( group1 = parent$text, group2 = child$text, tree_id = child$id, stringsAsFactors = FALSE )) } } # 输出结果 result
两种方法均可得到目标数据集,purrr写法更简洁,适合处理嵌套结构;基础R循环则更直观,适合不熟悉tidyverse生态的用户。
内容的提问来源于stack exchange,提问作者AyeTown
相关产品推荐
相关产品推荐

