我有一个名为foo的脚本。R包含另一个脚本other。R,在同一个目录下:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
但我想让R找到另一个。R,不管当前工作目录是什么。
换句话说,就是foo。R需要知道自己的路径。我该怎么做呢?
我有一个名为foo的脚本。R包含另一个脚本other。R,在同一个目录下:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
但我想让R找到另一个。R,不管当前工作目录是什么。
换句话说,就是foo。R需要知道自己的路径。我该怎么做呢?
当前回答
在我看来,从R脚本的获取路径中得到的rakensi的答案是最正确和真正精彩的。然而,它仍然是一个包含哑函数的黑客。我在这里引用它,是为了让别人更容易发现。
sourceDir <- getSrcDirectory(函数(dummy) {dummy})
这给出了放置语句的文件的目录(在那里定义了dummy函数)。然后可以使用它来设置工作目录并使用相对路径。
setwd(sourceDir)
source("other.R")
或者创建绝对路径
source(paste(sourceDir, "/other.R", sep=""))
其他回答
我已经将这个问题的答案打包并扩展为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"
到控制台。
我也有这个问题,上面的解决方案都不适合我。也许是来源之类的,但还不够清楚。
我找到了这个,对我来说很优雅的解决方案:
paste0(gsub("\\", "/", fileSnapshot()$path, fixed=TRUE),"/")
其中重要的是fileSnapshot(),它提供了关于文件的大量信息。它返回一个包含8个元素的列表。当您选择path作为列表元素时,路径将以\\作为分隔符返回,因此其余代码只是更改这一点。
我希望这能有所帮助。
当从R控制台“来源”时,我无法得到Suppressingfire的解决方案。 当使用Rscript时,我无法得到hadley的解决方案。
两全其美?
thisFile <- function() {
cmdArgs <- commandArgs(trailingOnly = FALSE)
needle <- "--file="
match <- grep(needle, cmdArgs)
if (length(match) > 0) {
# Rscript
return(normalizePath(sub(needle, "", cmdArgs[match])))
} else {
# 'source'd via R console
return(normalizePath(sys.frames()[[1]]$ofile))
}
}
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块。