R 将目录树表示为递归列表

R 将目录树表示为递归列表,r,list,recursive-datastructures,directory-tree,R,List,Recursive Datastructures,Directory Tree,我被某项任务困住了。我想要的是一个函数,给定一个目录路径,它将返回一个递归列表作为输出 输出的格式应为myList$dir$subdir$subdir$subdir$fullFilePath 所以基本上我想把目录树表示成一个特定的列表。我获取了所有文件,获取了每个文件的所有子目录,但我一直在思考如何将所有文件放入一个具有多个级别的列表中。这里有一个难看的破解 mypath <- 'a/b/c/d' makelist <- function(filepath, fsep = '/'

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

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

所以基本上我想把目录树表示成一个特定的列表。我获取了所有文件,获取了每个文件的所有子目录,但我一直在思考如何将所有文件放入一个具有多个级别的列表中。

这里有一个难看的破解

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   

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

这里有一个使用递归的解决方案:

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
}

tree.list下面是@flodel使用
purr
包的精彩解决方案的一个简短变体:

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)
}
库(purrr)
树列表%set\u名称(basename(.))%>%map\u如果(dir.exists,f)
}
第一行定义一个函数
f
,该函数使用
list.files(…,full.names=TRUE,include.dirs=TRUE)展开其参数
然后将
tree\u list()
应用于展开


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

谢谢!这是如此优雅,令人心痛。现在不会太慢。对于解析,我仍然不知道如何在解析后创建递归列表。在strsplit之后,我会有如下内容:list(dir=myDir,subdir1=mySubdir1,subdir2=mySubdir2,file=myFile)。For循环无法与列表[[“myDir”][[mySubdir1][[mySubdir2][[myFile]]一起使用,谢谢!弗洛德尔想出了一个更简洁的答案。如果不是这样的话,我会欣然接受你的回答。顺便问一下,我注意到了——你的财富是什么?@KarolisKoncevičius。看到了吧,我真希望我在做这件事之前就看到了!
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"
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)
}