R语言中:如何替代list.dirs返回命名嵌套列表而非字符向量?
将文件夹路径转换为命名嵌套列表的最简方法
场景说明
我们有如下层级的文件夹结构(可通过以下R代码创建,实际为已存在的目录):
c("Level1/Level1A/Level1AA", "Level1/Level1A/Level1AB", "Level1/Level1B/Level1BA", "Level1/Level1B/Level1BB", "Level2/Level2A/Level2AA", "Level2/Level2A/Level2AB", "Level2/Level2B/Level2BA", "Level2/Level2B/Level2BB") %>% purrr::map(dir.create, recursive = TRUE)
在父目录执行list.dirs()会返回一个扁平的字符向量:
[1] "." "./Level1" "./Level1/Level1A" "./Level1/Level1A/Level1AA" "./Level1/Level1A/Level1AB" [6] "./Level1/Level1B" "./Level1/Level1B/Level1BA" "./Level1/Level1B/Level1BB" "./Level2" "./Level2/Level2A" [11] "./Level2/Level2A/Level2AA" "./Level2/Level2A/Level2AB" "./Level2/Level2B" "./Level2/Level2B/Level2BA" "./Level2/Level2B/Level2BB"
但我们需要将其转换为命名嵌套列表,格式如下:
list(Level1 = list(Level1A = list("Level1AA", "Level1AB"), Level1B = list("Level1BA", "Level1BB")), Level2 = list(Level2A = list("Level2AA", "Level2AB"), Level2B = list("Level2BA", "Level2BB")))
最简解决方案
使用data.tree包可以快速实现需求,该包专门用于树形结构的处理,代码简洁直观:
- 先安装并加载包:
install.packages("data.tree") library(data.tree)
- 执行转换代码:
# 获取所有目录路径,排除当前目录(".") dir_paths <- list.dirs(recursive = TRUE, full.names = FALSE)[-1] # 将路径转换为树形结构,再导出为嵌套列表 dir_tree <- as.Node(data.frame(path = paste0("root/", dir_paths), stringsAsFactors = FALSE)) result <- dir_tree$ToListExcludeRoot()
执行后result就是目标格式的命名嵌套列表。
替代方案(仅用tidyverse工具)
如果不想额外安装包,也可以用tidyverse的组合函数实现:
library(tidyverse) dir_paths <- list.dirs(recursive = TRUE, full.names = FALSE)[-1] result <- dir_paths %>% # 拆分每个路径的层级 str_split("/", simplify = TRUE) %>% as.data.frame(stringsAsFactors = FALSE) %>% # 转长格式并过滤空值 pivot_longer(cols = everything(), names_to = "depth", values_to = "name", values_drop_na = TRUE) %>% mutate(depth = as.integer(depth)) %>% # 按层级去重并嵌套 group_by(depth) %>% distinct(name) %>% nest() %>% # 逐层构建嵌套列表 mutate(data = map(data, ~ set_names(map(.$name, list), .$name))) %>% pull(data) %>% reduce(function(prev, curr) map(prev, ~ c(., curr[names(.)])))
内容的提问来源于stack exchange,提问作者J. Doe
相关产品推荐
相关产品推荐

