Vérifier l’existence du répertoire et créer si n’existe pas

Je me retrouve souvent à écrire des scripts R qui génèrent beaucoup de résultats. Je trouve cela plus propre de mettre cette sortie dans son propre répertoire (s). Ce que j’ai écrit ci-dessous vérifiera l’existence d’un répertoire et y entrera, ou créera le répertoire, puis y passera. Y a-t-il une meilleure façon d’aborder cela?

mainDir <- "c:/path/to/main/dir" subDir <- "outputDirectory" if (file.exists(subDir)){ setwd(file.path(mainDir, subDir)) } else { dir.create(file.path(mainDir, subDir)) setwd(file.path(mainDir, subDir)) } 

Utilisez showWarnings = FALSE :

 dir.create(file.path(mainDir, subDir), showWarnings = FALSE) setwd(file.path(mainDir, subDir)) 

dir.create() ne dir.create() pas si le répertoire existe déjà, il dir.create() simplement un avertissement. Donc, si vous pouvez vivre avec des avertissements, il n’y a pas de problème à le faire:

 dir.create(file.path(mainDir, subDir)) setwd(file.path(mainDir, subDir)) 

Au 16 avril 2015, avec la sortie de R 3.2.0 il y a une nouvelle fonction appelée dir.exists() . Pour utiliser cette fonction et créer le répertoire s’il n’existe pas, vous pouvez utiliser:

 ifelse(!dir.exists(file.path(mainDir, subDir)), dir.create(file.path(mainDir, subDir)), FALSE) 

Cela retournera FALSE si le répertoire existe déjà ou est non-créable, et TRUE s’il n’existe pas mais a été créé avec succès.

Notez que pour vérifier simplement si le répertoire existe, vous pouvez utiliser

 dir.exists(file.path(mainDir, subDir)) 

En termes d’architecture générale, je recommanderais la structure suivante en ce qui concerne la création de répertoires. Cela couvrira la plupart des problèmes potentiels et tout autre problème dir.create la création de répertoire sera détecté par l’appel dir.create .

 mainDir <- "~" subDir <- "outputDirectory" if (file.exists(paste(mainDir, subDir, "/", sep = "/", collapse = "/"))) { cat("subDir exists in mainDir and is a directory") } else if (file.exists(paste(mainDir, subDir, sep = "/", collapse = "/"))) { cat("subDir exists in mainDir but is a file") # you will probably want to handle this separately } else { cat("subDir does not exist in mainDir - creating") dir.create(file.path(mainDir, subDir)) } if (file.exists(paste(mainDir, subDir, "/", sep = "/", collapse = "/"))) { # By this point, the directory either existed or has been successfully created setwd(file.path(mainDir, subDir)) } else { cat("subDir does not exist") # Handle this error as appropriate } 

dir.create('~/foo/bar') également que si ~/foo n'existe pas, un appel à dir.create('~/foo/bar') échouera à moins que vous n'indiquiez recursive = TRUE .

L’utilisation de file.exists () pour tester l’existence du répertoire est un problème dans la publication d’origine. Si subDir incluait le nom d’un fichier existant (plutôt qu’un simple chemin), file.exists () renverrait TRUE, mais l’appel à setwd () échouerait car vous ne pouvez pas définir le répertoire de travail pour pointer un fichier.

Je recommande l’utilisation de file_test (op = “- d”, subDir), qui renverra “TRUE” si subDir est un répertoire existant, mais FALSE si subDir est un fichier existant ou un fichier ou répertoire inexistant. De même, la recherche d’un fichier peut être effectuée avec op = “- f”.

De plus, comme décrit dans un autre commentaire, le répertoire de travail fait partie de l’environnement R et doit être contrôlé par l’utilisateur et non par un script. Les scripts ne devraient idéalement pas modifier l’environnement R. Pour résoudre ce problème, je pourrais utiliser options () pour stocker un répertoire disponible globalement où je voulais toute ma sortie.

Considérons donc la solution suivante, où someUniqueTag est juste un préfixe défini par le programmeur pour le nom de l’option, ce qui rend peu probable l’existence d’une option portant le même nom. (Par exemple, si vous développiez un package appelé “filer”, vous pourriez utiliser filer.mainDir et filer.subDir).

Le code suivant serait utilisé pour définir les options disponibles pour une utilisation ultérieure dans d’autres scripts (évitant ainsi l’utilisation de setwd () dans un script) et pour créer le dossier si nécessaire:

 mainDir = "c:/path/to/main/dir" subDir = "outputDirectory" options(someUniqueTag.mainDir = mainDir) options(someUniqueTag.subDir = "subDir") if (!file_test("-d", file.path(mainDir, subDir)){ if(file_test("-f", file.path(mainDir, subDir)) { stop("Path can't be created because a file with that name already exists.") } else { dir.create(file.path(mainDir, subDir)) } } 

Ensuite, dans tout script ultérieur nécessitant de manipuler un fichier dans subDir, vous pourriez utiliser quelque chose comme:

 mainDir = getOption(someUniqueTag.mainDir) subDir = getOption(someUniqueTag.subDir) filename = "fileToBeCreated.txt" file.create(file.path(mainDir, subDir, filename)) 

Cette solution laisse le répertoire de travail sous le contrôle de l’utilisateur.

J’ai rencontré un problème avec R 2.15.3: lorsque j’essayais de créer une arborescence de manière récursive sur un lecteur réseau partagé, je recevais une erreur de permission.

Pour contourner cette bizarrerie, je crée manuellement la structure;

 mkdirs <- function(fp) { if(!file.exists(fp)) { mkdirs(dirname(fp)) dir.create(fp) } } mkdirs("H:/foo/bar") 

Voici la vérification simple , et crée le répertoire s’il n’existe pas:

 ## Provide the dir name(ie sub dir) that you want to create under main dir: output_dir <- file.path(main_dir, sub_dir) if (!dir.exists(output_dir)){ dir.create(output_dir) } else { print("Dir already exists!") } 

Pour savoir si un chemin est un répertoire valide, essayez:

 file.info(cacheDir)[1,"isdir"] 

file.info ne se soucie pas d’une barre oblique à la fin.

file.exists sous Windows échouera pour un répertoire s’il se termine par une barre oblique et réussit sans lui. Donc, cela ne peut pas être utilisé pour déterminer si un chemin d’access est un répertoire.

 file.exists("R:/data/CCAM/CCAMC160b_echam5_A2-ct-uf.-5t05N.190to240E_level1000/cache/") [1] FALSE file.exists("R:/data/CCAM/CCAMC160b_echam5_A2-ct-uf.-5t05N.190to240E_level1000/cache") [1] TRUE file.info(cacheDir)["isdir"]