pobierz nazwę pliku i ścieżkę do pliku źródłowego


W jaki sposób plik
source
d lub
Sweave
d może znać własną ścieżkę?
Tło:
Dużo pracuję ze skryptami .R lub plikami .Rnw.
Moje projekty są zorganizowane w strukturę katalogów, ale ścieżka do katalogu podstawowego projektu często różni się na różnych komputerach (na przykład, ponieważ wykonuję część analizy danych dla kogoś innego, a ich struktura katalogów różni się od mojej: mają podstawowe katalogi projektów ~/Projects/StudentName/lub ~/Projects/Studentname/Projectname, a większość uczniów, którzy mają tylko jeden projekt, zwykle ma go pod ~/Measurements/lub ~/DataAnalysis/lub coś w tym stylu - to nie pracować dla mnie).
Dlatego
setwd (my.own.path ())

byłoby niezwykle przydatne, ponieważ zapewniłoby, że katalog roboczy jest podstawową ścieżką projektu bez względu na to, gdzie projekt jest faktycznie zlokalizowany. Bez konieczności zastanawiania się przez użytkownika nad ustawieniem katalogu roboczego.
Pozwól, że wyjaśnię: szukam rozwiązania, które będzie współpracować ze skrótem klawiaturowym edytora/IDE
source
lub
Sweave
przez nie myślącego użytkownika.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Po prostu FYI,
knitr
będzie
setwd ()
w katalogu pliku wejściowego podczas (i tylko wtedy) oceniania fragmentów kodu, to znaczy, jeśli wywołasz
knit ( 'path/to/input.Rnw')
, katalog roboczy zostanie tymczasowo przełączony na
path/to/
. Jeśli chcesz poznać katalog wejściowy w fragmentach kodu, obecnie możesz wywołać nieeksportowaną funkcję
knitr ::: input_dir ()
(mogę ją wyeksportować w przyszłości).
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Opierając się na sugestiach Seba gsk3, oto pomysł dla Ciebie:
  • do wybrania żądanego katalogu można użyć kombinacji nazwy użytkownika (loginu) i adresu IP lub nazwy komputera.

Powoduje to coś takiego:
setwd (switch (paste (Sys.info () [c ("user", "nodename")], collapse="."), 
user.laptop = "~/Messungen",
user2.server = "~/Projekte/Projekt/",
))

Jest więc automatyczne rozwiązanie
  • współpracuje z
    source
  • współpracuje z
    Sweave
  • działa nawet dla sesji interaktywnych, w których polecenia są wysyłane wiersz po wierszu
  • kombinacja
    user
    i
    nodename
    musi oczywiście być specyficzna
  • jednakże ścieżki należy edytować ręcznie.

Ulepszenia są mile widziane!
Aktualizacja:
Gabor Grothendieck odpowiedział dzisiaj na powiązane pytanie dotyczące r-help w następujący sposób:
this.dir <- dirname(parent.frame(2)$ofile)
setwd(this.dir)

która będzie działać dla
source
.
Kolejna aktualizacja: teraz wykonuję większość prac związanych z analizą danych w projektach RStudio. RStudio w zasadzie rozwiązuje problem: RStudio zmienia katalog roboczy na katalog główny projektu za każdym razem, gdy przełączam się między projektami.
Więc mogę umieścić katalog projektu tak nisko w drzewie katalogów, jak chcę (a uczniowie mogą również umieścić swoją kopię w dowolnym miejscu) i zsynchronizować pliki danych i skrypty/
.Rnw
z kontrolą wersji ( używamy prywatnego serwera git). Pliki projektu RStudio są przechowywane poza kontrolą źródła, to znaczy
.gitignore
zawiera
.Rproj.user
.
Jest oczywiste, że w

struktura

strukturę katalogów projektu należy zsynchronizować.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz użyć
sys.calls ()
, aby pobrać polecenie używane dla pliku źródłowego. Następnie potrzebujesz małej sztuczki wyrażenia regularnego, aby uzyskać ścieżkę, pamiętając, że
source („coś/nazwa pliku”)
mogło użyć ścieżki bezwzględnej lub względnej. Oto pierwsza próba połączenia wszystkich elementów razem: spróbuj wkleić następujące wiersze na początku pliku źródłowego.
whereFrom=sys.calls()[[1]]
# This should be an expression that looks something like
# source("pathname/myfilename.R")
whereFrom=as.character(whereFrom[2]) # get the pathname/filename
whereFrom=paste(getwd(),whereFrom,sep="/") # prefix it with the current working directory
pathnameIndex=gregexpr(".*/",whereFrom) # we want the string up to the final '/'
pathnameLength=attr(pathnameIndex[[1]],"match.length")
whereFrom=substr(whereFrom,1,pathnameLength-1)
print(whereFrom) # or "setwd(whereFrom)" to set the working directory

Nie jest to zbyt solidne - na przykład zawiedzie w oknach z
source ("pathname \\ filename")
i nie testowałem, co się stanie, jeśli jeden plik szuka innego pliku - ale możesz zbudować na tym rozwiązanie.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Nie mam bezpośredniego rozwiązania, jak uzyskać katalog samego pliku, ale jeśli masz ograniczony zakres katalogów i struktur katalogów, prawdopodobnie możesz użyć
if(file.exists("c:/somedir")==TRUE){setwd("c:/somedir")}

Możesz sprawdzić wzorzec danego katalogu, a następnie zainstalować katalog. Czy to ci pomoże?
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Dodatkowym problemem jest to, że katalog roboczy jest zmienną globalną, którą każdy skrypt może zmienić, więc jeśli twój skrypt wywoła inny skrypt, będzie musiał przywrócić wd. W RStudio używam Session - & > Ustaw katalog roboczy - & > Do lokalizacji pliku źródłowego (wiem, że to nie jest idealne), a następnie robi to mój skrypt
wd = getwd ()...
source ("mySubDir/myOtherScript.R", chdir=TRUE); setwd (wd)...
source ("anotherSubDir/anotherScript.R", chdir=TRUE); setwd (wd)

W ten sposób można zachować stos katalogów roboczych. Naprawdę chciałbym zobaczyć to zaimplementowane w samym języku.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Ta odpowiedź działa zarówno dla
source
, jak i dla
nvim-R
- nie mam pojęcia, czy działa z
knitr
i podobnymi rzeczami. Wszelkie uwagi są mile widziane.
Jeśli masz wiele wzajemnych skryptów
source
, ważne jest, aby uzyskać poprawny. To znaczy, największy
i
, dla którego istnieje
sys.frame (i) $ ofile
.
get.full.path.to.this.sourced.script = function() { 
for(i in sys.nframe():1) { # Go through all the call frames,
# in *reverse* order.
x = sys.frame(i)$ofile
if(!is.null(x)) # if $ofile exists,
return(normalizePath(x)) # then return the full absolute path
}
}

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się