66

在处理大型代码库时,使用相对路径获取文件非常有用。其他编程语言具有明确定义的机制,用于使用相对于源文件目录的路径来获取文件。一个例子是 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), ...)
}

你知道更好的source_relative实现吗?

4

1 回答 1

76

在GitHub 上与 @hadley讨论后,我意识到我的问题与 R 中的常见开发模式背道而驰。

似乎在源文件中通常假定工作目录 ( getwd()) 设置为它们所在的目录。要使其工作,source有一个chdir默认值为FALSE. 当设置为 时TRUE,它会将工作目录更改为要获取的文件的目录。

总之:

  1. 假设它source始终是相对的,因为所获取文件的工作目录设置为文件所在的目录。

  2. 为了使这项工作,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)
}
于 2012-09-02T06:54:54.393 回答