Mam skrypt o nazwie, foo.R
który zawiera inny skrypt other.R
, który znajduje się w tym samym katalogu:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
Ale chcę R
to stwierdzić other.R
bez względu na bieżący katalog roboczy.
Innymi słowy, foo.R
musi znać własną ścieżkę. Jak mogę to zrobić?
Odpowiedzi:
Tutaj jest proste rozwiązanie problemu. To polecenie:
zwraca ścieżkę bieżącego pliku skryptu. Działa po zapisaniu skryptu.
źródło
dirname(sys.frame(1)$ofile)
bezpośrednio z Rstudio. Działa dobrze, gdy skrypt jest wykonywany przy użyciu źródła („other.R”) idirname(sys.frame(1)$ofile)
jest w środku"other.R"
.NULL
gdy ten znajduje się w server.R podczas korzystania błyszcząceMożesz użyć tej
commandArgs
funkcji, aby pobrać wszystkie opcje przekazane przez Rscript do rzeczywistego interpretera języka R i wyszukać je--file=
. Jeśli skrypt został uruchomiony ze ścieżki lub jeśli został uruchomiony z pełną ścieżką,script.name
poniżej rozpocznie się od'/'
. W przeciwnym razie musi być względnacwd
i można połączyć dwie ścieżki, aby uzyskać pełną ścieżkę.Edycja: brzmi tak, jakbyś potrzebował tylko
script.name
powyższego i zdjął ostatni element ścieżki. Usunąłem niepotrzebnącwd()
próbkę, wyczyściłem główny skrypt i opublikowałem mójother.R
. Po prostu zapisz ten skrypt iother.R
skrypt w tym samym kataloguchmod +x
i uruchom skrypt główny.main.R :
other.R :
wyjście :
Tego właśnie szuka Dehmann.
źródło
source
tak, jak myślałem, że OP chce - ale może źle zrozumiałem jego / jej wymagania. Ale nie mogę cofnąć downmodu :( Przepraszamy!other.name <- file.path(script.basename, "other.R")
commandArgs(trailingOnly = FALSE)
serwer server.R w błyszczącej aplikacji, dostaję[1] "RStudio" "--interactive"
. Brak informacji o katalogu, z którego został wywołany.Nie mogłem zmusić rozwiązania Suppressingfire do działania, gdy „źródło” pochodziło z konsoli R.
Nie mogłem zmusić rozwiązania Hadley do działania podczas korzystania z Rscript.
Najlepsze z obu światów?
źródło
Rscript
isource()
wewnątrz R. Sugerowałbym zrobienienormalizePath()
obu wersji, aby w obu przypadkach zapewniała pełną ścieżkę.library(base)
zajęło mi trochę czasu, aby dowiedzieć się, że lolsource(file.path(dirname(thisFile()), "other.R"))
wfoo.R
. To działa dla mnie.main.R
które źródła,helper.R
które wywołujethisFile()
. Spowoduje to pobranie ścieżkimain.R
zamiasthelper.R
. Wszelkie wskazówki tutaj?Nie pytaj mnie, jak to działa, ponieważ zapomniałem: /
źródło
sys.frames
zwraca środowiska stosu wywołań, więc ma to sens tylko wtedy, gdy jest wywoływane z funkcji. Spróbuj npfoo <- function() {bar <- function() print(sys.frames()); bar()}; foo()
. Nie mogę jednak rozgryźć kodu @ hadley, ponieważ środowiska nie mająofile
członka.source("~/code/test.r")
,PATH
zostanie ustawiony na~/desktop
. Jeśli tylko ocenisz go na najwyższym poziomie, zwróci NULL.x$ofile
jest niezdefiniowany, więcframe_files
jest pusty.To działa dla mnie
źródło
Error: RStudio not running
.""
w moim przypadkuOdpowiedź rakensi z Pierwsze ścieżki skryptu R jest najbardziej poprawna i naprawdę genialna IMHO. Jednak wciąż jest to hack z funkcją manekina. Cytuję to tutaj, aby inni mogli łatwiej to znaleźć.
Daje to katalog pliku, w którym została umieszczona instrukcja (w którym zdefiniowano funkcję fikcyjną). Następnie można go użyć do ustawienia katalogu roboczego i ścieżek względnych, np
lub stworzyć ścieżki bezwzględne
źródło
sourceDir
było puste.character(0)
. Propozycje?Moje wszystko w jednym! (--01 / 09/2019 zaktualizowany w celu obsługi konsoli RStudio)
źródło
Odchudzony wariant odpowiedzi Supressingfire:
źródło
To działa dla mnie. Po prostu wyłapuje go z argumentów wiersza poleceń, usuwa niechciany tekst, robi nazwę katalogu i w końcu uzyskuje pełną ścieżkę z tego:
źródło
Skompletowałem i rozszerzyłem odpowiedzi na to pytanie do nowej funkcji
thisfile()
w rprojroot . Działa również na drutachknitr
.źródło
Podobało mi się rozwiązanie steamer25, ponieważ wydaje się najbardziej niezawodne do moich celów. Jednak podczas debugowania w RStudio (w systemie Windows) ścieżka nie zostanie ustawiona poprawnie. Powodem jest to, że jeśli w RStudio ustawiony jest punkt przerwania, w źródle pliku używana jest alternatywna komenda „źródło debugowania”, która nieco inaczej ustawia ścieżkę skryptu. Oto ostateczna wersja, której obecnie używam, która dotyczy tego alternatywnego zachowania w RStudio podczas debugowania:
źródło
Próbowałem prawie wszystkiego z tego pytania, Uzyskiwanie ścieżki skryptu R , Uzyskiwanie ścieżki bieżącego skryptu , Znajdź lokalizację bieżącego pliku .R i polecenia R do ustawienia katalogu roboczego na lokalizację pliku źródłowego w Rstudio , ale na końcu znalazłem się ręcznie przeglądanie tabeli CRAN i znalezione
scriptName
bibliotekaktóra udostępnia
current_filename()
funkcję, która zwraca prawidłową pełną ścieżkę skryptu podczas pobierania w RStudio, a także podczas wywoływania za pomocą pliku wykonywalnego R lub RScript.źródło
Package ‘scriptName’ was removed from the CRAN repository.
- co teraz? : oMiałem również ten problem i żadne z powyższych rozwiązań nie działało dla mnie. Może z
source
takimi lub podobnymi rzeczami, ale nie było to wystarczająco jasne.Dla mnie to eleganckie rozwiązanie:
Ważną rzeczą jest to,
fileSnapshot()
że daje wiele informacji o pliku. Zwraca listę 8 elementów. Po wybraniupath
jako elementu listy ścieżka jest zwracana za pomocą\\
jako separator, więc reszta kodu jest po prostu to zmienić.Mam nadzieję, że to pomoże.
źródło
Możesz owinąć skrypt rw skrypt bash i pobrać ścieżkę skryptu jako zmienną bash w następujący sposób:
źródło
Podoba mi się to podejście:
źródło
Właśnie to wypracowałem. Aby zapewnić przenośność skryptu, zawsze zaczynaj od:
Działa, ponieważ „.” tłumaczy jak polecenie Unix $ PWD. Przypisanie tego ciągu do obiektu znakowego pozwala następnie wstawić ten obiekt znakowy do setwd () i Presto twój kod zawsze będzie działał z bieżącym katalogiem jako katalogiem roboczym, bez względu na to, na której maszynie się znajduje lub gdzie w strukturze pliku jest usytuowany. (Dodatkowa premia: Obiekt wd może być używany z file.path () (tzn. File.path (wd, „katalog_wyjściowy”), aby umożliwić utworzenie standardowego katalogu wyjściowego niezależnie od ścieżki pliku prowadzącej do nazwanego katalogu. Wymaga to utworzenia nowego katalogu przed odwołaniem się do niego w ten sposób, ale to również może być pomocne w przypadku obiektu wd.
Alternatywnie poniższy kod wykonuje dokładnie to samo:
lub jeśli nie potrzebujesz ścieżki pliku w obiekcie, możesz po prostu:
źródło
Zauważ, że pakiet getopt udostępnia
get_Rscript_filename
funkcję, która wykorzystuje tylko to samo rozwiązanie przedstawione tutaj, ale jest już dla Ciebie napisana w standardowym module R, więc nie musisz kopiować i wklejać funkcji „pobierz ścieżkę skryptu” do każdego skryptu ty piszesz.źródło
R -e "library(getopt); testscript.R"
Rscript
.Zobacz
findSourceTraceback()
na R.utils pakietu, któryźródło
Miałem problemy z powyższymi implementacjami, ponieważ mój skrypt jest obsługiwany z katalogu z dowiązaniami symbolicznymi, a przynajmniej dlatego uważam, że powyższe rozwiązania nie działały dla mnie. Wzdłuż linii odpowiedzi @ ennuikiller, zawinąłem swój skrypt Rscript w bash. Ustawiam zmienną ścieżkową za pomocą
pwd -P
, która rozwiązuje dowiązania struktur katalogów. Następnie przekaż ścieżkę do Rscript.Bash.sh
foo.R
źródło
Użyłbym wariantu podejścia @ steamer25. Chodzi o to, że wolę uzyskać ostatni skrypt, nawet jeśli moja sesja została uruchomiona za pomocą Rscript. Poniższy fragment kodu, jeśli jest zawarty w pliku, zapewni zmienną
thisScript
zawierającą znormalizowaną ścieżkę skryptu. Przyznaję się do (ab) użycia źródła, więc czasami wywołuję Rscript, a skrypt podany w--file
źródłach argumentów ma inny skrypt, który pobiera inny ... Pewnego dnia zainwestuję w przekształcenie mojego niechlujnego kodu w pakiet.źródło
99% przypadków, których możesz po prostu użyć:
Nie zadziała w przypadku szalonych wywołań, w których skrypt nie jest pierwszym argumentem, tj
source(some args, file="myscript")
. Użyj @ hadley w tych fantazyjnych przypadkach.źródło
Podejście Steamer25 działa, ale tylko wtedy, gdy na ścieżce nie ma białych znaków. Na MacOS przynajmniej
cmdArgs[match]
powraca coś/base/some~+~dir~+~with~+~whitespace/
dla/base/some\ dir\ with\ whitespace/
.Obejrzałem to, zastępując „~ + ~” prostą białą spacją przed jej zwróceniem.
Oczywiście nadal możesz rozszerzyć blok else, tak jak zrobił to aprstar.
źródło
Jeśli zamiast skryptu,
foo.R
znając jego lokalizację ścieżki, możesz zmienić kod tak, aby zawsze odwoływał się do wszystkichsource
ścieżek ze wspólnego,root
to mogą być bardzo pomocne:Dany
/app/deeply/nested/foo.R
/app/other.R
To zadziała
Zobacz https://rprojroot.r-lib.org/, aby dowiedzieć się, jak zdefiniować katalog główny projektu.
źródło
źródło
Zadziwiające, że w R nie ma struktury typu „0 $”! Możesz to zrobić za pomocą wywołania system () skryptu bash napisanego w języku R:
Następnie po prostu podziel nazwę scriptpath.sh dla other.R
źródło
readLink: illegal option -- e usage: readLink [-FlLnqrsx] [-f format] [-t timefmt] [file ...]
Patrząc na stos wywołań, możemy uzyskać ścieżkę pliku każdego wykonywanego skryptu, dwa najbardziej przydatne będą prawdopodobnie albo aktualnie wykonywanym skryptem, albo pierwszym skryptem, który zostanie pozyskany (pozycja).
źródło