问题
I am stuck with a certain task. What I want is a function that, given a directory path, would return a recursive-list as an output.
The output should be of the form myList$dir$subdir$subdir$fullFilePath
So basically I want to represent a directory tree as a certain list. I obtain all the files, get all the subdirectories for each of the file, but I am stuck as to how to throw it all into a list with multiple levels.
回答1:
Here is a solution using recursion:
tree.list <- function(file.or.dir) {
isdir <- file.info(file.or.dir)$isdir
if (!isdir) {
out <- file.or.dir
} else {
files <- list.files(file.or.dir, full.names = TRUE,
include.dirs = TRUE)
out <- lapply(files, tree.list)
names(out) <- basename(files)
}
out
}
I have tested it here on a small directory
test.dir <- tree.list("./test")
test.dir
# $a
# $a$`1.txt`
# [1] "./test/a/1.txt"
#
# $a$aa
# $a$aa$`2.txt`
# [1] "./test/a/aa/2.txt"
#
# $b
# $b$`3.txt`
# [1] "./test/b/3.txt"
If this is too slow for your needs, I would consider reading all the files into a single call to list.files
with recursive = TRUE
then do a bit of parsing.
回答2:
Here is an ugly hack.
mypath <- 'a/b/c/d'
makelist <- function(filepath, fsep = '/'){
unlisted <- unlist(strsplit(filepath, fsep))
nsubs <- length(unlisted)
mylistcall <- paste(paste(rep('list(', nsubs), unlisted, collapse = '='),
'= NULL', paste(rep(')', nsubs), collapse = ''))
mylist <- eval(parse(text = mylistcall))
return(mylist)
}
makelist(mypath)
$a
$a$b
$a$b$c
$a$b$c$d
NULL
Remembering
fortune(106)
If the answer is parse() you should usually rethink the question.
-- Thomas Lumley
R-help (February 2005)
In this case however, I would say I should be rethinking the answer.
回答3:
Here's a shorter variant of @flodel's wonderful solution using the purrr
package:
library( purrr )
tree_list <- function( file_or_dir ) {
f <- partial(list.files, full.names=TRUE, include.dirs=TRUE) %>%
compose(tree_list, .)
file_or_dir %>% set_names( basename(.) ) %>% map_if(dir.exists, f)
}
The first line defines a function f
that expands its argument using list.files( ..., full.names=TRUE, include.dirs=TRUE)
then applies tree_list()
to the expansion.
The second line applies the defined function f
to all directories in the original argument.
来源:https://stackoverflow.com/questions/14188197/representing-a-directory-tree-as-a-recursive-list