如何用类似XPath的方法提取R列表中的所有baz元素?
在R中实现嵌套列表的类XPath元素提取
针对你提到的嵌套列表元素提取需求,这里提供两种实用方案:
方案一:生成路径后筛选提取
完全贴合你设想的names_as_paths + extract_by_path思路,手动实现路径生成与元素提取函数:
1. 定义路径生成与提取函数
library(purrr) library(stringr) # 生成所有元素的完整路径 names_as_paths <- function(x, parent_path = "") { if (is.list(x)) { map2(x, names(x), function(el, nm) { current_path <- if (parent_path == "") paste0("/", nm) else paste0(parent_path, "/", nm) names_as_paths(el, current_path) }) %>% unlist() } else { parent_path } } # 根据路径提取对应元素 extract_by_path <- function(x, paths) { map(paths, function(path) { nodes <- str_split(path, "/")[[1]] %>% discard(~ .x == "") reduce(nodes, function(current, node) current[[node]], .init = x) }) }
2. 实际使用示例
# 生成所有元素的路径 all_paths <- names_as_paths(l) # 筛选所有以/baz结尾的路径 baz_paths <- str_subset(all_paths, "/baz$") # 提取对应元素 extract_by_path(l, baz_paths) #> [[1]] #> [1] "apple" #> #> [[2]] #> [1] "orange"
方案二:用现成工具包直接提取
如果不想手动写函数,可以借助purrr或rlist包实现更简洁的递归提取:
用purrr快速提取
无需额外安装包(tidyverse已包含purrr),递归提取所有名为baz的元素:
map(l, ~ map(.x, "baz")) %>% flatten() #> [[1]] #> [1] "apple" #> #> [[2]] #> [1] "orange"
用rlist包实现类XPath查询
rlist包专门用于列表操作,支持类XPath的语法:
library(rlist) # 搜索所有名为baz的元素并返回值 list.search(l, baz, value = TRUE) #> [[1]] #> [1] "apple" #> #> [[2]] #> [1] "orange"
内容的提问来源于stack exchange,提问作者Magnus
相关产品推荐
相关产品推荐

