将目录树表示为递归列表

时间:2013-01-07 00:09:21

标签: r list recursive-datastructures directory-tree

我遇到了某项任务。我想要的是一个函数,给定一个目录路径,它将返回一个递归列表作为输出。

输出的格式应为myList $ dir $ subdir $ subdir $ fullFilePath

所以基本上我想将目录树表示为某个列表。我获取了所有文件,获取了每个文件的所有子目录,但是我不知道如何将它全部放入具有多个级别的列表中。

3 个答案:

答案 0 :(得分:6)

以下是使用递归的解决方案:

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
}

我已经在一个小目录上测试了它

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"

如果这对您的需求来说太慢,我会考虑将所有文件读入list.files recursive = TRUE并{{1}},然后进行一些解析。

答案 1 :(得分:2)

这是一个丑陋的黑客。

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   

记住

fortune(106)

If the answer is parse() you should usually rethink the question.
   -- Thomas Lumley
      R-help (February 2005)

在这种情况下,我会说我应该重新考虑答案。

答案 2 :(得分:0)

以下是使用purrr软件包的@flodel出色解决方案的简短变体:

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)
}

第一行定义一个函数f,该函数使用list.files( ..., full.names=TRUE, include.dirs=TRUE)扩展其自变量,然后将tree_list()应用于扩展。

第二行将定义的函数f应用于原始参数中的所有目录。