有效地将文件目录转换为 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 上有几篇文章是理想的教程文章。
我目前开始将 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 上有几篇文章是理想的教程文章。