Die Verwendung von file.exists(), um das Vorhandensein des Verzeichnisses zu testen, ist ein Problem im Originalbeitrag. Wenn subDir den Namen einer vorhandenen Datei enthielte (anstelle eines einfachen Pfads), würde file.exists() TRUE zurückgeben, aber der Aufruf von setwd() würde fehlschlagen, weil man das Arbeitsverzeichnis nicht auf eine Datei setzen kann.
Ich würde die Verwendung von file_test(op="-d", subDir) empfehlen, das "TRUE" zurückgibt, wenn subDir ein vorhandenes Verzeichnis ist, aber "FALSE", wenn subDir eine vorhandene Datei oder eine nicht vorhandene Datei oder Verzeichnis ist. Ebenso kann das Testen auf eine Datei mit op="-f" erreicht werden.
Zusätzlich, wie in einem anderen Kommentar beschrieben, ist das Arbeitsverzeichnis Teil der R-Umgebung und sollte vom Benutzer kontrolliert werden, nicht von einem Skript. Skripte sollten idealerweise die R-Umgebung nicht ändern. Um dieses Problem zu lösen, könnte ich options() verwenden, um ein global verfügbares Verzeichnis zu speichern, in dem ich all meine Ausgaben haben möchte.
Also, betrachten Sie die folgende Lösung, wobei someUniqueTag nur ein vom Programmierer definierter Präfix für den Optionnamen ist, was es unwahrscheinlich macht, dass bereits eine Option mit dem gleichen Namen existiert. (Zum Beispiel, wenn Sie ein Paket mit dem Namen "filer" entwickeln würden, könnten Sie filer.mainDir und filer.subDir verwenden).
Der folgende Code würde verwendet werden, um Optionen festzulegen, die später in anderen Skripts verwendet werden können (um so die Verwendung von setwd() in einem Skript zu vermeiden) und um das Verzeichnis bei Bedarf zu erstellen:
mainDir = "c:/Pfad/zum/hauptverzeichnis"
subDir = "outputVerzeichnis"
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("Der Pfad kann nicht erstellt werden, weil bereits eine Datei mit diesem Namen existiert.")
} else {
dir.create(file.path(mainDir, subDir))
}
}
Dann, in einem beliebigen nachfolgenden Skript, das eine Datei in subDir manipulieren müsste, könnten Sie etwas wie das folgende verwenden:
mainDir = getOption(someUniqueTag.mainDir)
subDir = getOption(someUniqueTag.subDir)
filename = "zuErstellendeDatei.txt"
file.create(file.path(mainDir, subDir, filename))
Diese Lösung lässt das Arbeitsverzeichnis unter der Kontrolle des Benutzers.
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.0 Stimmen
@Chase Aber du brauchst nicht
setwd
, um mit Netzwerkpfaden zu arbeiten. Du musst einfach Pfade angeben, um Ergebnisse zu speichern und trotzdem mit dem aktuellen Pfad zu arbeiten (dem, der festgelegt ist, wenn die R-Sitzung gestartet wurde). Oder starte R im gewünschten Arbeitsverzeichnis.1 Stimmen
@Marek - ahh, ich verstehe. Du willst also sagen, dass ich meine Aufrufe von
setwd()
durch etwas wiewrite.table(file = "Pfad/zum/Ausgabeverzeichnis", ...)
ersetzen soll?8 Stimmen
Yep. Oder parametrisieren Sie
out_dir <- "pfad/zum/ausgabe/verzeichnis"
und verwenden Sie dannwrite.table(file = file.path(out_dir,"tabelle_1.csv"), ...)
. Oder sogarout_file <- function(fnm) file.path("pfad/zum/ausgabe/verzeichnis", fnm)
und dannwrite.table(file = out_file("tabelle_1.csv"), ...)
(ähnliche Methode, die ich beim Arbeiten mit Netzlaufwerken verwende).0 Stimmen
@Marek - Nun habe ich etwas Neues gelernt, Zeit nach Hause zu gehen! Vielen Dank für die Tipps, das ist sehr hilfreich.
0 Stimmen
@hadley das ist gut zu wissen. Was ist mit der Verwendung von setwd() auf der obersten Ebene, so dass sich das Arbeitsverzeichnis ändert, wenn Sie den Code einfügen, aber es ist immer noch relativ tragbar? Meiner Meinung nach ist der Hauptgrund für die Verwendung von
setwd()
, wenn Sie an einem Projekt arbeiten, das Pfade benötigt, aber nicht langfristig genug ist, um das Standardverzeichnis von RStudio zu ändern. Gibt es auch technische Probleme bei der Verwendung vonsetwd()
oder handelt es sich eher um ein paradigmatisches Problem? Danke!!0 Stimmen
@PaulHurleyuk, waren Sie auf der Suche nach
tempdir()
undtempfile()
? Theoretisch könntetempdir()
für die Speicherung der Ausgabe verwendet werden, solange die Ausgabe nach Beendigung der R-Sitzung nicht mehr benötigt wird.