507 Stimmen

Ordnerverwaltung mit r: Überprüfen Sie das Vorhandensein eines Verzeichnisses und erstellen Sie es, wenn es nicht existiert.

Ich finde oft, dass ich R-Skripte schreibe, die eine Menge Output generieren. Ich finde es sauberer, diesen Output in seinem eigenen Verzeichnis(zu) platzieren. Was ich unten geschrieben habe, überprüft die Existenz eines Verzeichnisses und wechselt dorthin oder erstellt das Verzeichnis und wechselt dann dorthin. Gibt es einen besseren Weg, dies anzugehen?

mainDir <- "c:/pfad/zum/hauptverzeichnis"
subDir <- "outputVerzeichnis"

if (file.exists(subDir)){
    setwd(file.path(mainDir, subDir))
} else {
    dir.create(file.path(mainDir, subDir))
    setwd(file.path(mainDir, subDir))

}

1 Stimmen

Ich bin mir sicher, dass es eine R-Funktion gibt, die ein temporäres Verzeichnis mit einem zufällig generierten Namen erstellt und den Namen zurückgibt. Ich glaube, es gibt eine ähnliche Funktion, die eine temporäre Datei erstellt. Ich kann sie gerade nicht finden, aber das Databel-Paket (cran.r-project.org/web/packages/DatABEL/index.html) hat eine Funktion get_temporary_file_name.

65 Stimmen

Du solltest nie setwd() im R-Code verwenden - es untergräbt im Grunde genommen die Idee der Verwendung eines Arbeitsverzeichnisses, weil du deinen Code nicht mehr leicht zwischen Computern verschieben kannst.

7 Stimmen

@hadley Interessantes Thema zum Nachdenken, ich würde Ihre Gedanken zu anderen Methoden zum selben Zweck schätzen. Bei der Arbeit sind alle Computer mit demselben Netzwerk synchronisiert, sodass Dateipfade konsistent sind. Wenn sie es nicht sind, haben wir größere Probleme zu lösen als die Tragbarkeit eines Skripts. In diesem speziellen Beispiel habe ich ein Skript geschrieben, das auf einer Maschine geladen wird, die zwei Jahre lang in unseren Nationalparks herumgetragen wird. Dieses Skript wird Daten aus einer lokalen SQL-Instanz abrufen, einige Verarbeitungen durchführen und eine .csv-Datei ausgeben. Das Endprodukt wird eine .bat Datei sein, die der Endbenutzer nie ändern muss.

505voto

robbrit Punkte 16948

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, es gibt nur eine Warnung aus. Wenn Sie also mit Warnungen leben können, gibt es kein Problem damit, einfach Folgendes zu tun:

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

72 Stimmen

Bitte beachten Sie, dass bei der Verwendung von showWarnings = FALSE auch andere Warnungen ausgeblendet werden, wie z.B. die Unmöglichkeit, das Verzeichnis zu erstellen.

6 Stimmen

^ Gibt es eine Möglichkeit, nur eine bestimmte Warnung zu unterdrücken?

3 Stimmen

Hallo, ich möchte ein verschachteltes Verzeichnis erstellen, zum Beispiel, wenn ich im Ordner test1 bin, dann darin test2, darin test3 ... aber im Moment habe ich ein Problem. Gibt es eine Möglichkeit, dass ich 3 Ebenen von Verzeichnissen erstellen kann, auch wenn Verzeichnis1 nicht vorhanden ist ??

201voto

Molx Punkte 6590

Ab dem 16. April 2015, mit der Veröffentlichung von R 3.2.0, gibt es eine neue Funktion namens dir.exists(). Um diese Funktion 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 zurück, wenn das Verzeichnis bereits existiert oder nicht erstellt werden kann, und TRUE, wenn es nicht existierte, aber erfolgreich erstellt wurde.

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

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

13 Stimmen

Nur zur Kenntnis: Es ist keine gute Praxis, ifelse() für nicht-vektorielle Verzweigungen zu verwenden.

0 Stimmen

Was ist der zusätzliche Vorteil der Verwendung von dir.exists() gegenüber file_test("-d", dir), wie von @G Poole vorgeschlagen? Ich ziehe es vor, letzteres zu verwenden, weil es abwärtskompatibel ist.

3 Stimmen

@Bas, weil dein Code fälschlicherweise so aussieht, als würde etwas vektorisiertes passieren. Es ist ähnlich wie die Verwendung von vektorisiertem | anstelle von skalarem ||. Es funktioniert, ist aber schlechte Praxis.

40voto

Surya Punkte 9736

Hier ist der einfache Check, und erstellt das Verzeichnis, wenn es nicht existiert:

## Geben Sie den Verzeichnisnamen (d. h. Unterverzeichnis) an, das Sie unter dem Hauptverzeichnis erstellen möchten:
output_dir <- file.path(main_dir, sub_dir)

if (!dir.exists(output_dir)){
dir.create(output_dir)
} else {
    print("Verzeichnis existiert bereits!")
}

36voto

den2042 Punkte 347

Einzellinie:

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

Beispiel:

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

19voto

zelanix Punkte 3071

In Bezug auf die allgemeine Architektur würde ich die folgende Struktur für die Verzeichniserstellung empfehlen. Dies wird die meisten potenziellen Probleme abdecken, und alle anderen Probleme mit der Verzeichniserstellung werden durch den dir.create-Aufruf erkannt.

mainDir <- "~"
subDir <- "outputDirectory"

if (file.exists(paste(mainDir, subDir, "/", sep = "/", collapse = "/"))) {
    cat("subDir existiert in mainDir und ist ein Verzeichnis")
} else if (file.exists(paste(mainDir, subDir, sep = "/", collapse = "/"))) {
    cat("subDir existiert in mainDir, ist aber eine Datei")
    # Sie werden wahrscheinlich wollen, dass Sie dies separat behandeln
} else {
    cat("subDir existiert nicht in mainDir - wird erstellt")
    dir.create(file.path(mainDir, subDir))
}

if (file.exists(paste(mainDir, subDir, "/", sep = "/", collapse = "/"))) {
    # Zu diesem Zeitpunkt existierte das Verzeichnis entweder oder wurde erfolgreich erstellt
    setwd(file.path(mainDir, subDir))
} else {
    cat("subDir existiert nicht")
    # Behandeln Sie diesen Fehler entsprechend
}

Denken Sie auch daran, dass wenn ~/foo nicht existiert, ein Aufruf von dir.create('~/foo/bar') fehlschlagen wird, es sei denn, Sie geben recursive = TRUE an.

6 Stimmen

Gibt es ein bestimmten Grund, warum du paste( ... ) anstelle von file.path(mainDir, subDir) verwendest? Außerdem könntest du, wenn du einen Pfad erstellst mit path <- file.path(mainDir, subDir), diesen fünfmal wiederverwenden und die if-Anweisungen dadurch lesbarer machen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X