2011-01-20 37 views
44

這可能是某人一個非常簡單的問題 - 我能夠用list.files()獲得列表給定目錄中的文件,但如果我想獲取目錄列表,我該怎麼做?作爲list.files()中的一個選項,它在某種程度上是否正確?如何獲取一個目錄中的目錄列表,像list.files(),而是「list.dirs()」

另外,我使用的是Windows,所以如果答案是掏出來一些Linux/UNIX命令,這不會爲我工作。例如,.NET有一個Directory.GetFiles()方法和一個單獨的Directory.GetDirectories() 方法,所以我認爲R有一個類似的對。提前致謝。

回答

59

更新:一個list.dirs功能加入到基本包在修訂54353,這是包含在四月的R-2.13.0發佈,2011年

list.dirs(path = ".", full.names = TRUE, recursive = TRUE) 

所以我下面的功能只是有用幾個月。 :)


我無法找到一個基礎R功能,要做到這一點,但它會很容易寫你自己的使用:

dir()[file.info(dir())$isdir] 

更新:這裏是一個函數(現在糾正蒂莫西·瓊斯評論):

list.dirs <- function(path=".", pattern=NULL, all.dirs=FALSE, 
    full.names=FALSE, ignore.case=FALSE) { 
    # use full.names=TRUE to pass to file.info 
    all <- list.files(path, pattern, all.dirs, 
      full.names=TRUE, recursive=FALSE, ignore.case) 
    dirs <- all[file.info(all)$isdir] 
    # determine whether to return full names or just dir names 
    if(isTRUE(full.names)) 
    return(dirs) 
    else 
    return(basename(dirs)) 
} 
+0

不好的形式調用兩次DIR() - 事情都有可能調用之間改變(是的,P = 0.0000001),但仍...一天! – Spacedman 2011-01-20 16:43:40

+0

@Spacedman - 我同意,它更多的是證明了概念需要一行代碼。查看我的更新。 – 2011-01-20 16:45:41

+0

您將需要從中刪除遞歸參數,否則您的函數將無法工作。在這種情況下,`list.files`和`dir`沒有列出它發現作爲單獨的「文件」的任何目錄,而是,R列表中的*這些目錄*找到的所有文件。由於所有的這些都將是文件,而不是目錄,你的函數返回NA` – 2011-01-20 16:56:57

8
list.dirs <- function(...) { 
    x <- dir(...) 
    x[file_test("-d", x)] 
} 

可能是有用的?

我們如何遞歸地做到這一點? (參數dir打破了這些功能,因爲它永遠不會返回目錄名稱,只是每個目錄內的文件等)。

2

你提到你不想掏出一個Linux/UNIX命令,但我認爲它可以掏出一個Windows命令。在這種情況下,這將做到這一點:

shell("dir/ad/b", intern = TRUE) 

,這將遞歸地做到這一點:

shell("dir/ad/b/s", intern = TRUE) 

通常我會在這裏,但特別喜歡別人的平臺獨立解決方案交互使用,你只是關注儘可能簡單直接地得到答案,這可能是較少的工作。

16

只是爲了更新這個帖子:

我看到,在R(我目前使用2.5.1)的新版本,現在包括在基地list.dirs功能安裝:

list.dirs隱含地具有all.files = TRUE,並且如果recursive = TRUE,則 答案包括路徑本身(假設它是可讀目錄)。

-1

我有這個問題而回,並使用該遞歸代碼,找出所有目錄。也許這可以是有用的?

list.dirs <- function(parent=".") # recursively find directories 
{ 
    if (length(parent)>1)   # work on first and then rest 
     return(c(list.dirs(parent[1]), list.dirs(parent[-1]))) 
    else {       # length(parent) == 1 
     if (!is.dir(parent)) 
      return(NULL)   # not a directory, don't return anything 
     child <- list.files(parent, full=TRUE) 
     if (!any(is.dir(child))) 
      return(parent)   # no directories below, return parent 
     else 
      return(list.dirs(child)) # recurse 
    } 
} 

is.dir <- function(x) # helper function 
{ 
    ret <- file.info(x)$isdir 
    ret[is.na(ret)] <- FALSE 
    ret 
} 
2

什麼這樣的事情,不妨一試:

dir('.')[file.info(dir('.',full.names=T))$isdir] 
17

base [R現在包括list.dirs function,所以自釀變種不再是必要的。

例如:

list.dirs('.', recursive=FALSE) 
相關問題