Überprüfen Sie das Vorhandensein des Verzeichnisses und erstellen Sie, wenn es nicht existiert

Ich finde oft, dass ich R-Skripte schreibe, die viel Output erzeugen. Ich finde es sauberer, diese Ausgabe in eigene Verzeichnisse zu setzen. Was ich unten geschrieben habe, wird nach dem Vorhandensein eines Verzeichnisses suchen und sich darin bewegen, oder das Verzeichnis erstellen und dann in dieses hineingehen. Gibt es einen besseren Weg, um das zu erreichen?

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

   

Verwenden Sie showWarnings = FALSE :

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

dir.create() stürzt nicht ab, wenn das Verzeichnis bereits existiert, sondern nur eine Warnung dir.create() . Wenn Sie mit Warnungen leben können, gibt es kein Problem damit, dies einfach zu tun:

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

Ab dem 16. April 2015 gibt es mit der Veröffentlichung von R 3.2.0 eine neue function namens dir.exists() . Um diese function zu verwenden und das Verzeichnis zu erstellen, falls es nicht existiert, können Sie Folgendes verwenden:

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

Dies gibt FALSE wenn das Verzeichnis bereits existiert oder unreatabel ist, und TRUE wenn es nicht existiert, aber erfolgreich erstellt wurde.

Beachten Sie, dass Sie einfach überprüfen können, ob das Verzeichnis existiert

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

In Bezug auf die allgemeine Architektur würde ich die folgende Struktur in Bezug auf die Verzeichniserstellung empfehlen. Dadurch werden die meisten möglichen Probleme abgedeckt und alle anderen Probleme bei der Verzeichniserstellung werden durch den Aufruf von dir.create erkannt.

 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') auch, dass, wenn ~/foo nicht existiert, ein Aufruf von dir.create('~/foo/bar') fehlschlägt, es sei denn, Sie geben recursive = TRUE .

Die Verwendung von file.exists (), um das Vorhandensein des Verzeichnisses zu testen, ist ein Problem im ursprünglichen Post. Wenn subDir den Namen einer vorhandenen Datei (und nicht nur einen Pfad) enthält, gibt file.exists () TRUE zurück, aber der Aufruf von setwd () würde fehlschlagen, weil das Arbeitsverzeichnis nicht auf eine Datei verweisen kann.

Ich würde die Verwendung von file_test (op = “- d”, subDir) empfehlen, die “TRUE” zurückgibt, wenn subDir ein vorhandenes Verzeichnis ist, aber FALSE, wenn subDir eine vorhandene Datei oder eine nicht vorhandene Datei oder ein Verzeichnis ist. Ebenso kann das Suchen nach einer Datei mit op = “- f” durchgeführt werden.

Wie in einem anderen Kommentar beschrieben, ist das Arbeitsverzeichnis außerdem Teil der R-Umgebung und sollte vom Benutzer gesteuert werden, nicht von einem Skript. Skripte sollten idealerweise die R-Umgebung nicht verändern. Um dieses Problem zu beheben, verwende ich options (), um ein global verfügbares Verzeichnis zu speichern, in dem ich alle meine Ausgaben haben wollte.

Betrachten Sie die folgende Lösung, wobei someUniqueTag nur ein vom Programmierer definiertes Präfix für den Optionsnamen ist, wodurch es unwahrscheinlich ist, dass bereits eine Option mit demselben Namen existiert. (Wenn Sie beispielsweise ein Paket namens “filer” entwickeln, können Sie filer.mainDir und filer_Dir verwenden).

Der folgende Code wird verwendet, um Optionen festzulegen, die später in anderen Skripts zur Verwendung verfügbar sind (wodurch die Verwendung von setwd () in einem Skript vermieden wird) und den Ordner bei Bedarf zu erstellen:

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

In einem nachfolgenden Skript, das eine Datei in subDir bearbeiten muss, können Sie dann Folgendes verwenden:

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

Diese Lösung lässt das Arbeitsverzeichnis unter der Kontrolle des Benutzers.

Ich hatte ein Problem mit R 2.15.3, wobei ich beim Versuch, eine Baumstruktur rekursiv auf einem freigegebenen Netzlaufwerk zu erstellen, einen Berechtigungserrors erhalten würde.

Um diese Kuriosität zu umgehen, erstelle ich die Struktur manuell.

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

Hier ist die einfache Überprüfung , und erstellt das Verzeichnis, wenn nicht existiert:

 ## 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!") } 

Um herauszufinden, ob ein Pfad ein gültiges Verzeichnis ist, versuchen Sie Folgendes:

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

file.info sich nicht für einen Schrägstrich am Ende.

file.exists unter Windows wird für ein Verzeichnis fehlschlagen, wenn es in einem Schrägstrich endet und ohne es erfolgreich ist. Dies kann nicht verwendet werden, um festzustellen, ob ein Pfad ein Verzeichnis ist.

 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"]