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

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

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

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


当前回答

参见R.utils包的findSourceTraceback(),其中

查找source()在所有调用帧中生成的所有'srcfile'对象。 这使得可以找出当前由source()编写脚本的文件。

其他回答

我在一个高性能计算集群环境中工作。我在不同的地方开发代码,而不是在生产运行的地方。在开发过程中,我通常从命令行交互式地调用R(而不是使用RStudio)。有很多来源(“foo.R”)正在进行。

在生产运行期间,我通常编写一个bash脚本,尝试不同的参数,并在单独的目录中运行每一组参数。bash脚本利用了工作负载管理器(即SLURM)。在这种环境中,设置环境变量很简单。考虑到这一点,下面的解决方案最适合我。

其他。R

my_message <- function(){
return("R is awkward")
}

foo。R

srcpath = Sys.getenv("R_SRC")
# Check if runnning w/o setting R_SRC - presumably done in directory of development, i.e. /path/to/R/code
if(srcpath == ""){
    srcpath="./"
}
source(sprintf("%s/other.R", srcpath))
string = my_message()
print(string)

如果从R交互式shell中运行,并且在/path/到/R/code中运行,那么简单

> source("foo.R")

如果不是从交互式shell运行,也不是从/path/to/R/code运行,首先设置环境变量R_SRC,然后调用Rscript

$ export R_SRC=/path/to/R/code/
$ Rscript /path/to/R/code/foo.R

我喜欢这种方法:

this.file <- sys.frame(tail(grep('source',sys.calls()),n=1))$ofile
this.dir <- dirname(this.file)

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

Supressingfire回答的简化版本:

source_local <- function(fname){
    argv <- commandArgs(trailingOnly = FALSE)
    base_dir <- dirname(substring(argv[grep("--file=", argv)], 8))
    source(paste(base_dir, fname, sep="/"))
}

这对我很有用

library(rstudioapi)    
rstudioapi::getActiveDocumentContext()$path