问题
Out of interest and as a thought exercise, I was aiming to replicate the
tree
function
from the windows command line in R. tree
generates ASCII trees similar
to the following example (taken from
here
and modified). If n
is the hierarchical level, note that each file or
folder has (n-1)*3
spaces, followed by +---
+---Desktop
+---Documents
+---Custom Office Templates
+---Fiddler2
+---Captures
+---Requests
+---Responses
+---Scripts
+---Favorites
+---Links
I use list.files()
to extract the filenames (albeit this function
ignores empty directories) and the recursive function dir_tree()
(inspired by this
answer) to capture the
hierarchy in a nested list.
library(purrr)
library(stringr)
dirs <- list.files(recursive = TRUE)
# To create a reproducible example, I create dirs manually
dirs <- c("Desktop",
"Documents",
"Documents/Custom Office Templates",
"Documents/Fiddler2",
"Documents/Fiddler2/Captures",
"Documents/Fiddler2/Captures/Requests",
"Documents/Fiddler2/Captures/Responses",
"Documents/Fiddler2/Scripts",
"Documents/Favorites",
"Documents/Favorites/Links"
)
dir_tree <- function(dirs) {
first <- map_chr(str_split(dirs,"/"),~.x[1])
rest <- map_chr(str_split(dirs,"/"),~paste(.x[-1],collapse = "/"))
zi <- nchar(dirs) == 0L
myli <- split(rest[!zi], first[!zi])
map(myli, ~dir_tree(.x))
}
# creates a nested list
dir_nl <- dir_tree(dirs)
str(dir_nl)
## List of 2
## $ Desktop : Named list()
## $ Documents:List of 3
## ..$ Custom Office Templates: Named list()
## ..$ Favorites :List of 1
## .. ..$ Links: Named list()
## ..$ Fiddler2 :List of 2
## .. ..$ Captures:List of 2
## .. .. ..$ Requests : Named list()
## .. .. ..$ Responses: Named list()
## .. ..$ Scripts : Named list()
All I need to do now is to walk recursively through the nested list and
print the names, prepending it with (n-1)*3
spaces and +---
. The
Question I have is: How do I retrieve n
, i.e. the hierarchical
level!?
recursive_print <- function(dir_nl){
imap(dir_nl,function(x,y){
if(is.list(x)){
print(paste("+---",y))
recursive_print(x)
}
})
}
recursive_print(dir_nl) %>% invisible()
## [1] "+--- Desktop"
## [1] "+--- Documents"
## [1] "+--- Custom Office Templates"
## [1] "+--- Favorites"
## [1] "+--- Links"
## [1] "+--- Fiddler2"
## [1] "+--- Captures"
## [1] "+--- Requests"
## [1] "+--- Responses"
## [1] "+--- Scripts"
回答1:
I haven't been able to solve it myself, but found a package that does it for me. This kind of defeats the purpose of learning recursive functions, but I'll place this here in case anyone lands here.
library(data.tree)
tree <- FromListSimple(dir_nl)
print(tree)
## levelName
## 1 Root
## 2 ¦--Desktop
## 3 °--Documents
## 4 ¦--Custom Office Templates
## 5 ¦--Favorites
## 6 ¦ °--Links
## 7 °--Fiddler2
## 8 ¦--Captures
## 9 ¦ ¦--Requests
## 10 ¦ °--Responses
## 11 °--Scripts
And for the record, data.tree
has a method to directly parse a string of filepaths into a tree, so dir_tree()
becomes obsolete.
as.Node(data.frame(paths = dirs),pathName = "paths")
## levelName
## 1 Desktop
## 2 ¦--Custom Office Templates
## 3 ¦--Fiddler2
## 4 ¦ ¦--Captures
## 5 ¦ ¦ ¦--Requests
## 6 ¦ ¦ °--Responses
## 7 ¦ °--Scripts
## 8 °--Favorites
## 9 °--Links
来源:https://stackoverflow.com/questions/65819395/r-recursive-function-in-deeply-nested-list-accessing-level-of-hierarchy