Ich habe ein Skript namens foo.R
, das ein anderes Skript enthält other.R
, das sich im selben Verzeichnis befindet:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
Aber ich möchte R
das finden, other.R
egal was das aktuelle Arbeitsverzeichnis ist.
Mit anderen Worten, foo.R
muss seinen eigenen Weg kennen. Wie kann ich das machen?
Antworten:
Hier gibt es eine einfache Lösung für das Problem. Dieser Befehl:
Gibt den Pfad der aktuellen Skriptdatei zurück. Es funktioniert, nachdem das Skript gespeichert wurde.
quelle
dirname(sys.frame(1)$ofile)
direkt von Rstudio aus auszuführen. Es funktioniert in Ordnung, wenn das Skript mit source ("other.R") ausgeführt wird und sich darindirname(sys.frame(1)$ofile)
befindet"other.R"
.NULL
geliere, wenn dies in Server.R platziert wird, wenn glänzend verwendetMit der
commandArgs
Funktion können Sie alle Optionen abrufen, die von Rscript an den eigentlichen R-Interpreter übergeben wurden, und nach ihnen suchen--file=
. Wenn Ihr Skript über den Pfad gestartet wurde oder wenn es mit einem vollständigen Pfad gestartet wurde,script.name
beginnt das Folgende mit einem'/'
. Andernfalls muss es relativ zu seincwd
und Sie können die beiden Pfade zusammenfassen, um den vollständigen Pfad zu erhalten.Bearbeiten: Es hört sich so an, als würden Sie nur das
script.name
Obige benötigen und die letzte Komponente des Pfades entfernen. Ich habe das nicht benötigtecwd()
Beispiel entfernt, das Hauptskript bereinigt und meinother.R
. Speichern Sie dieses Skript und dasother.R
Skript einfach im selben Verzeichnischmod +x
und führen Sie das Hauptskript aus.main.R :
other.R :
Ausgabe :
Ich glaube, das ist es, wonach Dehmann sucht.
quelle
source
wie ich dachte, dass das OP es wollte - aber vielleicht habe ich seine / ihre Anforderung falsch verstanden. Aber ich kann nicht un-downmod :( Entschuldigung!other.name <- file.path(script.basename, "other.R")
commandArgs(trailingOnly = FALSE)
in server.R in einer glänzenden Anwendung zu laufen, bekomme ich[1] "RStudio" "--interactive"
. Keine Informationen zu dem Verzeichnis, aus dem es aufgerufen wurde.Ich konnte die Lösung von Suppressingfire nicht zum Laufen bringen, wenn ich von der R-Konsole aus "quelle".
Ich konnte Hadleys Lösung nicht zum Laufen bringen, wenn ich Rscript verwendete.
Beste aus beiden Welten?
quelle
Rscript
undsource()
innerhalb von R funktioniert . Ich würde vorschlagen, esnormalizePath()
mit beiden Versionen zu tun , damit es in beiden Fällen den vollständigen Pfad angibt.library(base)
eine Weilesource(file.path(dirname(thisFile()), "other.R"))
infoo.R
. Das funktioniert bei mir.main.R
welche Quellenhelper.R
welche Anrufe tätigenthisFile()
. Es wird den Pfad vonmain.R
statt abrufenhelper.R
. Irgendwelche Tipps hier?Frag mich aber nicht, wie es funktioniert, denn ich habe vergessen: /
quelle
sys.frames
die Umgebungen des Aufrufstapels zurück, sodass es nur dann wirklich Sinn macht, wenn es von einer Funktion aufgerufen wird. Versuchen Sie es zfoo <- function() {bar <- function() print(sys.frames()); bar()}; foo()
. Ich kann den Code von @ hadley jedoch nicht herausfinden, da Umgebungen keinofile
Mitglied haben.source("~/code/test.r")
,PATH
wird festgelegt werden~/desktop
. Wenn Sie es nur auf der obersten Ebene auswerten, wird NULL zurückgegeben.x$ofile
ist undefiniert,frame_files
ist also leer.Das funktioniert bei mir
quelle
Error: RStudio not running
.""
in meinem Fall nicht das richtige Ergebnis gebenDie Antwort von Rakensi aus dem Pfad eines R-Skripts ist meiner Meinung nach die korrekteste und wirklich brillanteste. Dennoch ist es immer noch ein Hack mit einer Dummy-Funktion. Ich zitiere es hier, damit es von anderen leichter gefunden wird.
Dies gibt das Verzeichnis der Datei an, in der die Anweisung platziert wurde (in der die Dummy-Funktion definiert ist). Es kann dann verwendet werden, um das Arbeitsverzeichnis festzulegen und relative Pfade zu verwenden, z
oder um absolute Pfade zu erstellen
quelle
sourceDir
war leer.character(0)
. Vorschläge?Mein alles in einem! (--01 / 09/2019 aktualisiert, um mit RStudio Console umzugehen)
quelle
Eine abgespeckte Variante von Supressingfires Antwort:
quelle
Das funktioniert bei mir. Greift es einfach aus den Befehlszeilenargumenten heraus, entfernt den unerwünschten Text, macht einen Verzeichnisnamen und erhält schließlich den vollständigen Pfad daraus:
quelle
Ich habe die Antworten auf diese Frage in eine neue Funktion
thisfile()
in rprojroot eingepackt und erweitert . Funktioniert auch zum Stricken mitknitr
.quelle
Ich mochte die Lösung von steamer25, da sie für meine Zwecke am robustesten erscheint. Beim Debuggen in RStudio (in Windows) wurde der Pfad jedoch nicht richtig festgelegt. Der Grund dafür ist, dass bei der Festlegung eines Haltepunkts in RStudio für die Beschaffung der Datei ein alternativer Befehl "Debug-Quelle" verwendet wird, mit dem der Skriptpfad etwas anders festgelegt wird. Hier ist die endgültige Version, die ich derzeit verwende und die dieses alternative Verhalten in RStudio beim Debuggen berücksichtigt:
quelle
Ich habe fast alles aus dieser Frage heraus versucht: Pfad eines R-Skripts abrufen , Pfad des aktuellen Skripts abrufen , Speicherort der aktuellen R-Datei suchen und R-Befehl zum Festlegen des Arbeitsverzeichnisses auf den Speicherort der Quelldatei in Rstudio , aber am Ende fand ich mich manuell Durchsuchen der CRAN-Tabelle und gefunden
scriptName
Bibliothekcurrent_filename()
Dies bietet eine Funktion, die beim Sourcing in RStudio und auch beim Aufrufen über die ausführbare Datei R oder RScript den richtigen vollständigen Pfad des Skripts zurückgibt.quelle
Package ‘scriptName’ was removed from the CRAN repository.
- was jetzt? : oIch hatte auch dieses Problem und keine der oben genannten Lösungen funktionierte für mich. Vielleicht mit dem
source
oder solchen Dingen, aber es war nicht klar genug.Ich fand diese für mich elegante Lösung:
Das Wichtigste dabei ist,
fileSnapshot()
dass Sie viele Informationen über eine Datei erhalten. Es wird eine Liste mit 8 Elementen zurückgegeben. Wenn Siepath
als Listenelement auswählen , wird der Pfad\\
als Trennzeichen zurückgegeben, sodass der Rest des Codes nur dazu dient, dies zu ändern.Ich hoffe das hilft.
quelle
Sie können das r-Skript in ein Bash-Skript einschließen und den Pfad des Skripts als Bash-Variable wie folgt abrufen:
quelle
Ich mag diesen Ansatz:
quelle
Ich habe das einfach selbst herausgefunden. Um die Portabilität Ihres Skripts sicherzustellen, beginnen Sie immer mit:
Es funktioniert, weil "." übersetzt wie der Unix-Befehl $ PWD. Wenn Sie diese Zeichenfolge einem Zeichenobjekt zuweisen, können Sie dieses Zeichenobjekt in setwd () einfügen. Presto Ihr Code wird immer mit seinem aktuellen Verzeichnis als Arbeitsverzeichnis ausgeführt, unabhängig davon, auf welchem Computer er sich befindet oder wo in der Dateistruktur er sich befindet gelegen. (Zusätzlicher Bonus: Das wd-Objekt kann mit file.path () (dh file.path (wd, "output_directory") verwendet werden, um unabhängig vom Dateipfad, der zu Ihrem benannten Verzeichnis führt, ein Standardausgabeverzeichnis zu erstellen. Dazu müssen Sie das neue Verzeichnis erstellen, bevor Sie es auf diese Weise referenzieren. Dies kann jedoch auch mit dem wd-Objekt unterstützt werden.
Alternativ führt der folgende Code genau dasselbe aus:
Wenn Sie den Dateipfad in einem Objekt nicht benötigen, können Sie einfach:
quelle
Beachten Sie, dass das getopt-Paket die
get_Rscript_filename
Funktion bereitstellt , die nur die hier vorgestellte Lösung verwendet, jedoch bereits in einem Standard-R-Modul für Sie geschrieben wurde, sodass Sie die Funktion "get script path" nicht in jedes Skript kopieren und einfügen müssen du schreibst.quelle
R -e "library(getopt); testscript.R"
Rscript
.Siehe
findSourceTraceback()
das R.utils- Paket, dasquelle
Ich hatte Probleme mit den oben genannten Implementierungen, da mein Skript von einem Symlink-Verzeichnis aus betrieben wird, oder zumindest denke ich, dass die oben genannten Lösungen für mich nicht funktioniert haben. In Anlehnung an die Antwort von @ ennuikiller habe ich mein Rscript in Bash eingewickelt. Ich setze die
pwd -P
Pfadvariable mit , die symlinked Verzeichnisstrukturen auflöst. Übergeben Sie dann den Pfad in das Rscript.Bash.sh
foo.R
quelle
Ich würde eine Variante des Ansatzes von @ steamer25 verwenden. Der Punkt ist, dass ich es vorziehen würde, das Skript mit der letzten Quelle zu erhalten, selbst wenn meine Sitzung über Rscript gestartet wurde. Das folgende Snippet enthält, wenn es in einer Datei enthalten ist, eine Variable,
thisScript
die den normalisierten Pfad des Skripts enthält. Ich gestehe die (ab) Verwendung von source'ing, deshalb rufe ich manchmal Rscript auf und das im--file
Argument angegebene Skript liefert ein anderes Skript, das ein anderes liefert ... Eines Tages werde ich investieren, um meinen unordentlichen Code in ein Paket zu verwandeln.quelle
99% der Fälle könnten Sie einfach verwenden:
Es funktioniert nicht für verrückte Anrufe, bei denen das Skript nicht das erste Argument ist, d
source(some args, file="myscript")
. H. Verwenden Sie @ hadley in diesen ausgefallenen Fällen.quelle
Der Ansatz von Steamer25 funktioniert, jedoch nur, wenn der Pfad kein Leerzeichen enthält. Unter macOS gibt das zumindest so
cmdArgs[match]
etwas wie/base/some~+~dir~+~with~+~whitespace/
für zurück/base/some\ dir\ with\ whitespace/
.Ich habe dies umgangen, indem ich das "~ + ~" durch ein einfaches Leerzeichen ersetzt habe, bevor ich es zurückgegeben habe.
Natürlich können Sie den else-Block immer noch wie aprstar erweitern.
quelle
Wenn Sie anstelle des Skripts,
foo.R
wenn Sie dessen Pfadposition kennen, Ihren Code so ändern können, dass er immer auf allesource
d-Pfade eines gemeinsamen Pfads verweist ,root
können diese eine große Hilfe sein:Gegeben
/app/deeply/nested/foo.R
/app/other.R
Das wird funktionieren
Informationen zum Definieren von Projektwurzeln finden Sie unter https://rprojroot.r-lib.org/ .
quelle
quelle
Erstaunlich, dass es in R keine Struktur vom Typ '$ 0' gibt! Sie können dies mit einem system () -Aufruf eines in R geschriebenen Bash-Skripts tun:
Teilen Sie dann einfach den Namen scriptpath.sh für other.R auf
quelle
readLink: illegal option -- e usage: readLink [-FlLnqrsx] [-f format] [-t timefmt] [file ...]
Wenn wir uns den Aufrufstapel ansehen, können wir den Dateipfad jedes ausgeführten Skripts ermitteln. Die beiden nützlichsten sind wahrscheinlich entweder das aktuell ausgeführte Skript oder das erste Skript, das bezogen wird (Eintrag).
quelle