在R中递归列出文件到特定层级

6

有没有一种优雅的方法来递归列出文件,直到某个特定级别为止? 我有一个非常复杂的文件夹结构,递归搜索所有xml文件需要几秒钟时间。对我来说,只搜索到某个特定级别就足够了,但是我编写的代码看起来很丑陋,我想知道是否有更优雅的方法。例如,搜索到第四级会变得很丑陋...

list.files(c(list.dirs(recursive=FALSE), # first level
             list.dirs(list.dirs(recursive=FALSE), recursive=FALSE)), # second level 
             pattern='\\.xml$',
             full.names=TRUE, 
             recursive=FALSE)

也许将递归设置为TRUE并使用过滤器丢弃具有超过N个“/”的实例? - Dominic Comtois
“list.dirs”函数已经需要很长时间了,因为文件夹结构比较复杂。所以我更倾向于只搜索到特定深度。 - drmariod
3个回答

4

为了简洁,我会编写一个带有 n 参数的小型递归工具,您可以在之后使用它。例如:

list.dirs.depth.n <- function(p, n) {
  res <- list.dirs(p, recursive = FALSE)
  if (n > 1) {
    add <- list.dirs.depth.n(res, n-1)
    c(res, add)
  } else {
    res
  }
}

list.dirs.depth.n(".", n = 3)

然后在调用list.files时使用此命令。

这是我尝试过的,但是我无法以某种方式使其运行... 我会再试一次。 - drmariod

2

这里有一种使用 Sys.glob 的方法:

getFiles <- function(ext, depth){
  wildcards <- Reduce(
    file.path, x = rep("*", depth), init = paste0("*.", ext),
    right = TRUE, accumulate = TRUE
  )
  Sys.glob(wildcards)
}
getFiles("xml", 4)

0

这个例子非常类似于递归解决方案#1,但它是针对文件完成的。

lfbl=function(pattern,level=1){
    if(!exists("lof")) lof=vector("character",0)
    temp=list.files(pattern=pattern,no..=T)
    if(!is.na(temp[1])) lof=c(lof,paste0(getwd(),"/",temp))
    if(level>0){
        dirf=list.dirs(full.names=F,recursive=F)
        for(i in dirf){
            setwd(i)
            lof=c(lof,lfbl(pattern,level-1))
            setwd("..")
        }
    }
    return(lof)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接