web-dev-qa-db-fra.com

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

Je me trouve souvent en train d'écrire des scripts R qui génèrent beaucoup de résultats. Je trouve plus propre de mettre cette sortie dans son propre (ses) répertoire (s). Ce que j'ai écrit ci-dessous vérifie l'existence d'un répertoire et passe dans celui-ci, ou crée le répertoire puis se déplace dans celui-ci. 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))

}
348
Chase

Utilisez showWarnings = FALSE:

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

dir.create() ne plante pas si le répertoire existe déjà, il affiche simplement un avertissement. Donc, si vous pouvez vivre avec les avertissements, cela ne pose aucun problème:

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

À compter du 16 avril 2015, avec la sortie de R 3.2.0, 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)

Ceci retournera FALSE si le répertoire existe déjà ou est incréable, et TRUE s'il n'existait pas mais avait é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))
149
Molx

En termes d'architecture générale, je recommanderais la structure suivante en ce qui concerne la création de répertoires. Ceci couvrira la plupart des problèmes potentiels et tout autre problème lié à la création du 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
}

Sachez également que si ~/foo n'existe pas, l'appel de dir.create('~/foo/bar') échouera sauf si vous spécifiez recursive = TRUE.

17
zelanix

Voici le contrôle simple, et crée le répertoire s'il n'existe pas:

## Provide the dir name(i.e 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!")
}
10
Surya

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

Je recommanderais 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. Idéalement, les scripts ne devraient pas modifier l'environnement R. Pour résoudre ce problème, je pourrais utiliser options () pour stocker un répertoire disponible globalement dans lequel je voulais toute ma sortie.

Ainsi, considérons la solution suivante, où someUniqueTag est simplement un préfixe défini par le programmeur pour le nom de l’option, ce qui rend peu probable qu’une option portant le même nom existe déjà. (Par exemple, si vous développez un package appelé "filer", vous pouvez 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 qui doit manipuler un fichier dans subDir, vous pouvez 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.

8
G Poole

J'ai eu un problème avec R 2.15.3 qui provoquait une erreur d'autorisation lorsque j'essayais de créer une arborescence de manière récursive sur un lecteur réseau partagé.

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")
6
user425678

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 elle. Cela ne peut donc pas être utilisé pour déterminer si un chemin 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"]
2
user3807179

Bon mot:

if (!dir.exists(output_dir)) {dir.create(output_dir)}

Exemple:

dateDIR <- as.character(Sys.Date())
outputDIR <- file.path(outD, dateDIR)
if (!dir.exists(outputDIR)) {dir.create(outputDIR)}
0
den2042