web-dev-qa-db-fra.com

Lister tous les fichiers correspondant à un motif de chemin complet dans R

J'essaie d'obtenir la liste des fichiers correspondant à un chemin complet pattern. Jusqu'à présent, j'ai utilisé list.files () mais cela n'a pas fonctionné.

Supposons que nous ayons l'organisation de répertoires suivante:

results
   |- A
   |  |- data-1.csv
   |  |- data-2.csv
   |
   |- B
      |- data-1.csv
      |- data-2.csv

Puis la commande suivante:

list.files(pattern='data-.*\\.csv', recursive=TRUE)

retournera tous les fichiers correspondant au motif. Cela fonctionne, mais le problème apparaît lorsqu’on utilise un chemin complet pattern. Par exemple, si je veux obtenir tous les fichiers CSV du répertoire résultats/A, je pourrais faire:

list.files(pattern='results/A/data-.*\\.csv', recursive=TRUE)

Cela ne fonctionne pas, cependant. D'une manière ou d'une autre, il semble que R ne soit pas en mesure d'utiliser un modèle de chemin complet comme expression régulière. Dans ce cas, la solution pourrait simplement consister à utiliser résultats/A comme chemin de base. Mais dans les problèmes plus complexes, cela ne peut pas être fait. Par exemple, nous voudrons peut-être faire correspondre les sous-répertoires contenant uniquement des caractères:

list.files(pattern='results/[A-Z]+/data-.*\\.csv', recursive=TRUE)

Est-il possible de faire cela en R?

UPDATE: Après avoir utilisé des solutions ad hoc pendant un moment, j'ai décidé d'arrêter de taper la même chose encore et encore. J'ai donc créé une library pour simplifier cette tâche.

23
betabandido

Tout d'abord, notez que vous n'utilisez pas de modèles d'expression régulière. Votre premier exemple devrait être:

list.files(pattern='data-.*\\.csv', recursive=TRUE)

Ensuite, il semble que la correspondance de modèle à l'intérieur de list.files soit appliquée aux noms de base de fichiers (c'est-à-dire, n'incluant pas le chemin du répertoire) afin que vous puissiez scinder la tâche en:

  1. Recherchez tous les fichiers correspondant au nom de base uniquement et renvoyez leurs chemins d'accès complets:

    basename.matches <- list.files(pattern='data-.*\\.csv', recursive=TRUE,
                                   full.names = TRUE)
    basename.matches
    # [1] "./results/A/data-1.csv" "./results/A/data-2.csv" "./results/B/data-1.csv"
    # [4] "./results/B/data-2.csv"
    
  2. Ne conservez que ceux qui correspondent au (x) répertoire (s) attendu (s):

    full.matches <- grep(pattern='^\\./results/A/', basename.matches, value = TRUE)
    full.matches
    # [1] "./results/A/data-1.csv" "./results/A/data-2.csv"
    
28
flodel

Vous ne pouvez pas faire cela avec uniquement list.files car il boucle sur chaque élément de path et applique l'expression régulière aux fichiers qu'il contient. Mais comme l'argument path de list.files peut accepter un vecteur, vous pouvez l'utiliser pour résoudre votre problème.

dirs <- grep("[A-Z]+$",list.dirs("results",recursive=FALSE),value=TRUE)
list.files(dirs, "data-.*\\.csv", recursive=TRUE, full.names=TRUE)
7
Joshua Ulrich

J'utiliserai 

paths <- list.files(results, pattern= glob2rx("*data-*.csv$*"), full.names=T, recursive=T)
0
mga302

Je pense qu'il existe une solution encore plus simple:

Sys.glob(file.path(results, "[A-Z]", "data-*.csv"))

0
michael