有效地将文件目录转换为 R 中的列表,可能使用 Rcpp

Efficiently turn a file directory into a list in R, possibly with Rcpp

我目前开始将 shinyTree 用于我的一个应用程序,但我无法找到一种有效的方法来将我的目录转换为列表。我的假设是最简单的方法是使用 Rcpp 之类的东西来利用 C++ 的速度,但我并不认同这个想法。但是,如果那是要走的路,我在那个领域的技能几乎为零,所以我希望有人能够提供一些代码片段让我朝着正确的方向开始。

这是我目前用来实现我想要做的事情的代码:

create_directory_tree = function(root) {
  tree = list()
  file_lookup = data.frame(id=character(0), file_path=character(0), stringsAsFactors=FALSE)
  files = list.files(root, all.files=F, recursive=T, include.dirs=T)

  walk_directory = function(tree, path) {
    fp = file.path(root, path)
    is_dir = file.info(fp)$isdir
    if (is.null(is_dir) | is.na(is_dir)) {
      print(fp)
      return(NULL)
    }
    path = gsub("'|\"", "", path)
    folders = str_split(path, "/")[[1]]
    if (is.na(dir) | is.null(dir)) {
      print(paste("Failed:", fp))
      return(NULL)
    }
    if (is_dir) {
      txt = paste("tree", paste("$'", folders, "'", sep="", collapse=""), " = numeric(0)", sep="")
    } else {
      txt = paste("tree", paste("$'", folders, "'", sep="", collapse=""), " = structure('', sticon='file')", sep="")
    }
    eval(parse(text = txt))
    return(tree)
  }

  for (i in 1:length(files)) {
    tmp = data.frame(id=paste0("j1_", i), file_path=file.path(root, files[i]), stringsAsFactors=FALSE)
    file_lookup = rbind(file_lookup, tmp)
    tree = walk_directory(tree, files[i])
    save(tree, file_lookup, file="www/dir_tree.Rdata")
  }
}

这花了很长时间,我希望有更好的东西。提前致谢。

问题是您在

中将 data.frame 增加了 rbind
file_lookup = rbind(file_lookup, tmp)

可能 root 的目录有很多很多内容,因此,在不断复制和重新创建 data.frame 时会发生速度减慢。您已经有了文件数量的长度(例如 length(files)),因此使用

预先创建 data.frame
files = list.files(root, all.files=F, recursive=T, include.dirs=T)
nfiles = length(files)
file_lookup = data.frame(id=character(nfiles), file_path=character(nfiles), stringsAsFactors=FALSE)

此外,您的目标是在 for 循环中不断保存对象的进度,这是一个 I/O 瓶颈。我会移动:

save(tree, file_lookup, file="www/dir_tree.Rdata")

循环外。

最后,Rcpp Gallery 上有几篇文章是理想的教程文章。