2011-01-20 12 views
44

Questa potrebbe essere una domanda molto facile per qualcuno - Sono in grado di utilizzare list.files() per ottenere un elenco di file in una determinata directory, ma se voglio ottenere un elenco di directory, come faccio? È in qualche modo proprio di fronte a me come opzione entro list.files()?Come ottenere un elenco di directory all'interno di una directory, come list.files(), ma invece "list.dirs()"

Inoltre, sto utilizzando Windows, quindi se la risposta è eseguire il comando di shell su un comando Linux/unix, non funzionerà per me.

.NET ad esempio ha un metodo Directory.GetFiles() e un metodo separato , quindi ho pensato che R avrebbe avuto una coppia analoga. Grazie in anticipo.

risposta

59

Aggiornamento: Una funzione list.dirs è stato aggiunto al pacchetto base in revisione 54353, che è stata inclusa nella versione R-2.13.0 nel mese di aprile, 2011.

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

Quindi la mia funzione qui sotto è stato utile solo per pochi mesi. :)


non riuscivo a trovare una funzione di base R per fare questo, ma sarebbe abbastanza facile da scrivere il proprio utilizzando:

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

Aggiornamento: ecco una funzione (ora corretto per Timothy Jones' commento):

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

forma inappropriato chiamare dir() due volte - le cose potrebbero cambiare tra chiamate (sì, p = 0,0000001), ma ancora ... Un giorno! – Spacedman

+0

@Spacedman - Sono d'accordo, era più un one-liner proof-of-concept. Vedi il mio aggiornamento. –

+0

Dovrai rimuovere l'argomento ricorsivo da quello altrimenti la tua funzione non funzionerà. In tali circostanze, 'list.files' e' dir' non elencano le directory che trova come "file" separati, invece, R elenca tutti i file trovati * all'interno di * quelle directory. Poiché tutti questi saranno file e non directory, la tua funzione restituirà un vettore di 'NA' –

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

potrebbe essere utile?

Come potremmo farlo in modo ricorsivo? (l'argomento recursive di dir interrompe queste funzioni perché non restituisce mai nomi di directory, solo i file all'interno di ciascuna directory, ecc.).

+0

anche questo non funziona, ma grazie per aver risposto. Mi limiterò a giocare con file.info e $ dir finché non avrò qualcosa che funziona – user297400

+3

@ user297400 Non avresti dovuto accettare la mia risposta come corretta se non ha funzionato per te. –

+0

@ user297400 funziona perfettamente per me ... – Michele

2

Si dice che non si desidera eseguire il bombardamento su un comando Linux/UNIX, ma presumo che sia possibile eseguire il comando di shell in un comando di Windows. In questo caso lo farebbe:

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

e questo avrebbe fatto in modo ricorsivo:

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

Normalmente io preferirei le soluzioni indipendenti dalla piattaforma di altri qui, ma in particolare per l'uso interattivo in cui si sono solo preoccupati con l'ottenere la risposta nel modo più semplice e diretto possibile, questo potrebbe essere meno lavoro.

16

solo per aggiornare questa discussione:

vedo che nella versione più recente di R (attualmente sto usando 2.5.1), v'è ora una funzione list.dirs incluso nella base di installazione:

list.dirs ha implicitamente ha tutti i file = TRUE e se ricorsivo = TRUE, la risposta include il percorso stesso (purché sia ​​una directory leggibile).

+0

Hai usato la funzione integrata? Non riesco a far funzionare 'all.files = TRUE', non mostra l'intero percorso. – AnjaM

+0

no? intendi ora? – nsheff

+0

Sì, la risposta accettata non è più aggiornata. 'list.dirs()' è il modo migliore per ottenere questo ora. – rensa

-1

Ho avuto questo problema un po 'indietro e ho usato questo codice ricorsivo per trovare tutte le directory. Forse questo può essere utile?

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

Che dire qualcosa di simile, fare un tentativo:

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

base R include ora un list.dirs function, così varianti fatta in casa non sono più necessari.

Ad esempio:

list.dirs('.', recursive=FALSE) 
Problemi correlati