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

je me retrouve souvent à écrire des scripts R qui génèrent beaucoup de sorties. Je trouve plus propre de mettre cette sortie dans son propre répertoire. Ce que j'ai écrit ci-dessous permettra de vérifier l'existence d'un répertoire et de se déplacer dedans, ou créer le répertoire, puis avancez. Est-il une meilleure façon d'aborder cette question?

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))

}
299
r
demandé sur Rob 2010-11-18 18:53:45

7 réponses

utiliser showWarnings = FALSE :

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

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

dir.create(file.path(mainDir, subDir))
setwd(file.path(mainDir, subDir))
308
répondu robbrit 2014-08-15 08:42:41

en date du 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 de 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)

renvoie FALSE si le répertoire existe déjà ou est introuvable, 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))
121
répondu Molx 2015-04-21 23:39:29

en termes d'architecture générale, je recommande 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 avec la création de répertoires 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 aussi que si ~/foo n'existe pas alors un appel à dir.create('~/foo/bar') échouera à moins que vous spécifiez recursive = TRUE .

16
répondu zelanix 2014-03-12 16:18:25

l'utilisation de file.exists() pour tester l'existence de l'annuaire est un problème dans le post original. Si subDir incluait le nom d'un fichier existant (plutôt qu'un chemin), fichier.exists () retournerait TRUE, mais l'appel à setwd () échouerait parce que vous ne pouvez pas définir le répertoire de travail pour pointer vers un fichier.

je recommande l'utilisation de file_test (op= "-d", subDir), qui retournera "TRUE" si subDir est un répertoire existant, mais FALSE si subDir est un répertoire fichier existant ou fichier ou répertoire inexistant. De même, la vérification 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 pas, idéalement, changer l'environnement R. Pour résoudre ce problème, je pourrais utiliser options() pour stocker un répertoire globalement disponible où je voulais tout mon output.

ainsi, considérez 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 qu'une option avec le même nom existe déjà. (Par exemple, si vous développiez un paquet appelé "filer", vous pourriez utiliser filer.mainDir et filer.subDir).

Le code suivant devrait être utilisé pour définir les options qui sont disponibles pour une utilisation ultérieure dans d'autres scripts (évitant ainsi l'utilisation de setwd() dans un script), et à 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))
  }
}

alors, dans n'importe quel script ultérieur qui devait 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.

8
répondu G Poole 2015-09-13 07:44:07

j'ai eu un problème avec R 2.15.3 par lequel tout en essayant de créer une structure d'arbre récursivement sur un lecteur de réseau partagé j'obtiendrais 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")
6
répondu user425678 2015-09-29 09:57:48

voici le simple check , et crée le dir si 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!")
}
4
répondu Surya 2017-09-01 21:19:46

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 à l'extrémité.

file.exists sur Windows échouera pour un répertoire si il se termine dans une barre oblique, et réussit sans elle. Donc, ce ne peut 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
répondu user3807179 2014-08-15 08:43:15