在处理大型代码库时,使用相对路径获取文件很有用.其他编程语言具有明确定义的机制,用于使用相对于所源文件的目录的路径来获取文件.一个例子是Ruby的require_relative
.在R中实施相对路径采购的好方法是什么?
下面是我使用各种食谱和R论坛帖子拼凑的一段时间.它对于我的直接开发来说效果很好,但并不健全.例如,特别是在通过testthat
库加载文件时它会中断auto_test()
.rscript_stack()
回报character(0)
.
# Returns the stack of RScript files
rscript_stack <- function() {
Filter(Negate(is.null), lapply(sys.frames(), function(x) x$ofile))
}
# Returns the current RScript file path
rscript_current <- function() {
stack <- rscript_stack()
r <- as.character(stack[length(stack)])
first_char <- substring(r, 1, 1)
if (first_char != '~' && first_char != .Platform$file.sep) {
r <- file.path(getwd(), r)
}
r
}
# Sources relative to the current script
source_relative <- function(relative_path, ...) {
source(file.path(dirname(rscript_current()), relative_path), ...)
}
Run Code Online (Sandbox Code Playgroud)
你知道更好的source_relative
实现吗?
Sim*_*Sim 70
在与GitHub上的@hadley 讨论之后,我意识到我的问题与R中的共同开发模式背道而驰.
似乎在源文件中的R文件通常假设工作目录(getwd()
)设置为它们所在的目录.为了使其工作,source
有一个chdir
默认值为的参数FALSE
.设置为时TRUE
,它会将工作目录更改为要获取的文件的目录.
综上所述:
假设source
始终是相对的,因为要获取的文件的工作目录设置为文件所在的目录.
要使其工作,请始终chdir=T
在从其他目录中获取文件时进行设置,例如source('lib/stats/big_stats.R', chdir=T)
.
为了方便地以可预测的方式获取整个目录,我写sourceDir
了一个按字母顺序从源目录中获取文件的方法.
sourceDir <- function (path, pattern = "\\.[rR]$", env = NULL, chdir = TRUE)
{
files <- sort(dir(path, pattern, full.names = TRUE))
lapply(files, source, chdir = chdir)
}
Run Code Online (Sandbox Code Playgroud)