我有一个名为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需要知道自己的路径。我该怎么做呢?
当前回答
你可以使用commandArgs函数获取Rscript传递给实际R解释器的所有选项,并搜索——file=。如果你的脚本是从路径启动的,或者它是以一个完整的路径启动的,下面的script.name将以'/'开头。否则,它必须是相对于cwd,你可以连接两个路径,以获得完整的路径。
编辑:听起来你只需要上面的script.name,并剥离路径的最后一个组件。我已经删除了不需要的cwd()样本,并清理了主脚本,并张贴了我的其他. r。只需要保存这个脚本和其他脚本。R脚本放到同一个目录下,chmod +x它们,然后运行主脚本。
主要。接待员:
#!/usr/bin/env Rscript
initial.options <- commandArgs(trailingOnly = FALSE)
file.arg.name <- "--file="
script.name <- sub(file.arg.name, "", initial.options[grep(file.arg.name, initial.options)])
script.basename <- dirname(script.name)
other.name <- file.path(script.basename, "other.R")
print(paste("Sourcing",other.name,"from",script.name))
source(other.name)
其他。接待员:
print("hello")
输出:
burner@firefighter:~$ main.R
[1] "Sourcing /home/burner/bin/other.R from /home/burner/bin/main.R"
[1] "hello"
burner@firefighter:~$ bin/main.R
[1] "Sourcing bin/other.R from bin/main.R"
[1] "hello"
burner@firefighter:~$ cd bin
burner@firefighter:~/bin$ main.R
[1] "Sourcing ./other.R from ./main.R"
[1] "hello"
我相信这就是德曼在找的东西。
其他回答
解决方案在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"
到控制台。
Supressingfire回答的简化版本:
source_local <- function(fname){
argv <- commandArgs(trailingOnly = FALSE)
base_dir <- dirname(substring(argv[grep("--file=", argv)], 8))
source(paste(base_dir, fname, sep="/"))
}
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块。
我也有这个问题,上面的解决方案都不适合我。也许是来源之类的,但还不够清楚。
我找到了这个,对我来说很优雅的解决方案:
paste0(gsub("\\", "/", fileSnapshot()$path, fixed=TRUE),"/")
其中重要的是fileSnapshot(),它提供了关于文件的大量信息。它返回一个包含8个元素的列表。当您选择path作为列表元素时,路径将以\\作为分隔符返回,因此其余代码只是更改这一点。
我希望这能有所帮助。
这对我很有用
library(rstudioapi)
rstudioapi::getActiveDocumentContext()$path