我有一个名为foo的脚本。R包含另一个脚本other。R,在同一个目录下:

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

但我想让R找到另一个。R,不管当前工作目录是什么。

换句话说,就是foo。R需要知道自己的路径。我该怎么做呢?


当前回答

这个问题有一个简单的解决办法。这个命令:

script.dir <- dirname(sys.frame(1)$ofile)

返回当前脚本文件的路径。它在保存脚本后工作。

其他回答

frame_files <- lapply(sys.frames(), function(x) x$ofile)
frame_files <- Filter(Negate(is.null), frame_files)
PATH <- dirname(frame_files[[length(frame_files)]])

不要问我它是如何工作的,因为我已经忘记了:/

我已经将这个问题的答案打包并扩展为rprojroot中的新函数thisfile()。也适用于编织与针织。

解决方案在2016年出现。非常感谢作者,Sahil Seth!

CRAN和github上的funr包提供了sys.script()函数,该函数获取当前脚本的完整路径。它甚至引用了一个类似的SO帖子。

因此,解是:

myscript。接待员:

#!/usr/bin/env Rscript
f  <-  funr::sys.script()
show(f)

然后执行命令:

user@somewhere:/home$ Rscript myscript.R

将在命令行输出,例如:

"/home/path/to/myscript.R"

到控制台。

如果而不是脚本,foo。R,知道它的路径位置,如果你可以改变你的代码,总是从一个公共根引用所有的源路径,那么这些可能会有很大的帮助:

https://github.com/r-lib/rprojroot或https://rprojroot.r-lib.org/ https://here.r-lib.org/

鉴于

/ app /深度/嵌套/ foo。R /应用程序/其他。R

这是可行的

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

参见https://rprojroot.r-lib.org/了解如何定义项目根。

Steamer25的方法是有效的,但前提是路径中没有空白。在macOS上,至少cmdArgs[match]返回类似/base/some~+~dir~+~带~+~空格/ for /base/some\ dir\带\空格/。

我通过在返回之前用一个简单的空格替换“~+~”来解决这个问题。

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))
  }
}

显然,你仍然可以像aprstar那样扩展else块。