Определить путь к исполняемому скрипту - PullRequest
220 голосов
/ 29 ноября 2009

У меня есть скрипт с именем foo.R, который включает другой скрипт other.R, который находится в том же каталоге:

#!/usr/bin/env Rscript
message("Hello")
source("other.R")

Но я хочу, чтобы R нашел это other.R независимо от текущего рабочего каталога.

Другими словами, foo.R должен знать свой собственный путь. Как я могу это сделать?

Ответы [ 24 ]

0 голосов
/ 13 марта 2018

Удивительно, что в R нет структуры типа '$ 0'! Вы можете сделать это с помощью вызова system () скрипта bash, написанного на R:

write.table(c("readlink -e $0"), file="scriptpath.sh",col=F, row=F, quote=F)
thisscript <- system("sh scriptpath.sh", intern = TRUE)

Затем просто выделите имя файла scriptpath.sh для других.R

splitstr <- rev(strsplit(thisscript, "\\/")[[1]])
otherscript <- paste0(paste(rev(splitstr[2:length(splitstr)]),collapse="/"),"/other.R")
0 голосов
/ 05 января 2018

Если вместо сценария, foo.R, зная местоположение его пути, если вы можете изменить свой код так, чтобы он всегда ссылался на все source 'd пути из общего root, то это может быть очень полезно:

Дано

  • /app/deeply/nested/foo.R
  • /app/other.R

Это будет работать

#!/usr/bin/env Rscript
library(here)
source(here("other.R"))

См. https://rprojroot.r -lib.org / для определения корней проекта.

0 голосов
/ 29 июля 2017

Подход Steamer25 работает, но только если в пути нет пробелов. В macOS по крайней мере cmdArgs[match] возвращает что-то вроде /base/some~+~dir~+~with~+~whitespace/ для /base/some\ dir\ with\ whitespace/.

Я обошел это, заменив "~ + ~" простым пробелом перед его возвратом.

thisFile <- function() {
  cmdArgs <- commandArgs(trailingOnly = FALSE)
  needle <- "--file="
  match <- grep(needle, cmdArgs)
  if (length(match) > 0) {
    # Rscript
    path <- cmdArgs[match]
    path <- gsub("\\~\\+\\~", " ", path)
    return(normalizePath(sub(needle, "", path)))
  } else {
    # 'source'd via R console
    return(normalizePath(sys.frames()[[1]]$ofile))
  }
}

Очевидно, что вы можете расширить блок else, как это сделал aprstar.

0 голосов
/ 23 ноября 2014
#!/usr/bin/env Rscript
print("Hello")

# sad workaround but works :(
programDir <- dirname(sys.frame(1)$ofile)
source(paste(programDir,"other.R",sep='/'))
source(paste(programDir,"other-than-other.R",sep='/'))
...