如何提取R列表中所有深度嵌套子列表的名称?
提取R列表中所有深度嵌套的最底层子列表名称
问题说明
需要从R的嵌套列表中提取所有最底层非列表元素对应的名称,示例列表list_tmp可模拟动态变化的复杂嵌套结构,优先用Base R实现,也可使用tidyverse系列包简化操作。
示例列表生成代码
# 创建Col_A和Col_B列的矩阵 mat_tmp <- matrix(0, nrow = 2, ncol = 2) colnames(mat_tmp) <- c("Col_A","Col_B") # 构建嵌套列表 list_tmp1 <- list( Top = list( Middle_One = list( A = mat_tmp, B = mat_tmp, Total = mat_tmp ), Middle_Two = list( A = mat_tmp, Total = mat_tmp ) ) ) list_tmp2 <- list( Top = list( Total = mat_tmp ) ) list_tmp3 <- list( Top = list( Other = matrix(0, nrow = 2, ncol = 1) ) ) list_tmp <- c(list_tmp1,list_tmp2, list_tmp3)
解决方案
Base R递归实现
通过自定义递归函数遍历列表,判断元素是否为最底层(非列表类型),收集对应名称:
get_bottom_names <- function(x) { res <- character(0) for (i in seq_along(x)) { if (is.list(x[[i]])) { # 递归处理子列表 res <- c(res, get_bottom_names(x[[i]])) } else { # 记录最底层元素的名称 res <- c(res, names(x)[i]) } } return(res) } # 调用函数获取结果 bottom_names <- get_bottom_names(list_tmp) print(bottom_names)
运行结果:
[1] "A" "B" "Total" "A" "Total" "Total" "Other"
tidyverse实现(purrr包)
利用purrr的递归遍历工具简化代码:
library(purrr) get_bottom_names_tidy <- function(x) { map_depth(x, .depth = Inf, ~names(.x)) %>% flatten_chr() %>% discard(is.null) } # 调用函数获取结果 bottom_names_tidy <- get_bottom_names_tidy(list_tmp) print(bottom_names_tidy)
运行结果与Base R版本完全一致。
补充说明
- 两种方法均支持任意深度的嵌套列表,适配动态变化的列表结构;
- 仅收集末端非列表元素的名称,不会误将中间层级的列表名称纳入结果。
内容的提问来源于stack exchange,提问作者Village.Idyot
相关产品推荐
相关产品推荐

