R:source()和源文件路径

时间:2017-03-15 16:45:52

标签: r function relative-path chdir

我必须对R中的source()命令有所了解。我还不熟悉它,但我不能为我的生活理解它是如何得到它的目录的从!我的问题是:

我有一个包装器脚本wrapper.R和一个包含一些函数functions.R的源文件。这两个都在同一个目录中。如果我在包装器脚本中调用source('functions.R'),当站在两个文件所在的目录中时,一切都很好。但是,我希望能够从某些其他目录运行我的wrapper.R脚本,即。而不是这些脚本所在的目录。如果我为另一个目录运行我的包装器,它不起作用,我收到cannot open the file错误。

我用Google搜索并找到了许多不同的主题,但this question似乎非常清楚。我理解它的方式,我做它的方式应该可以工作。显然,我误解了一些事情。我对该主题的阅读使我相信source()适用于调用source()的文件所在的目录。我的阅读也让我相信我不应该使用{{1因为我想保留广告的相对目录。

看到它不起作用......我有什么误解?当从其他地方调用时,如何从与我的包装器脚本相同的目录中获取文件?

5 个答案:

答案 0 :(得分:11)

如果您要向同事分发脚本,那么您真的不应该编写源自其他脚本的脚本。如果您希望将来重命名或移动functions.R该怎么办?如果您需要修改functions.R中的函数,但wrapper.R依赖于该函数的旧版本,该怎么办?这是一个脆弱的解决方案,会导致头痛。我会推荐以下任何一种。

  1. 将所需的所有内容放入一个自包含的脚本中并分发。

  2. 如果确实想要将代码分成不同的文件,请编写一个包。可能听起来有点矫枉过正,但包装实际上可以非常简单轻巧。在最简单的形式中,包只是一个带有DESCRIPTIONNAMESPACE文件以及R/目录的目录。哈德利很好地打破了这个问题:http://r-pkgs.had.co.nz/

答案 1 :(得分:4)

您可以使用here包执行此操作。它使用“加载包时的当前工作目录”。换句话说,您从。

开始R会话的目录

在您的情况下,代码将是:

source(here::here('functions.R'))

即使包装脚本wrapper.R位于项目的不同目录中,这也会有效。

如果functions.R位于项目的子目录中,只需将其添加到here()的调用中,即可完成相对路径:

source(here::here('subdirectory', 'functions.R'))

答案 2 :(得分:2)

也许您可以在wrapper.R中定义一个帮助函数,它将尝试从同一目录加载其他文件。例如

source_here <- function(x, ...) {
    dir <- "."
    if(sys.nframe()>0) {
        frame <- sys.frame(1)
        if (!is.null(frame$ofile)) {
            dir <- dirname(frame$ofile)
        }
    }
    source(file.path(dir, x), ...)
}

然后你会打电话给

# inside wrapper.R
source_here("functions.R")

然后您将拥有源wrapper.R,它将在同一目录中查找functions.R

答案 3 :(得分:2)

我尚未看到的一个答案是仅使用绝对路径。 source("myfunctions.R")时,它使用的是getwd()中的隐式相对路径。更改工作目录时,请使用完整路径来避免出现问题。

答案 4 :(得分:2)

source 根本不支持这一点。其他答案显示了一些在有限情况下有效但在某些(常见)情况下都失败的解决方法。尤其是,正如您自己指出的那样,chdir = TRUE 不是一个好的选择。

更好的解决方案是从“box”包中获取box::use。该包允许您将 R 源代码视为适当的模块。这样做的一个特性是模块可以加载本地模块。

在您的 wrapper.R 中,将 source 调用替换为

box::use(./functions[...])

或者,如果您想从您的 wrapper.R 模块导出这些函数(而不是仅仅在内部使用它们),请改为执行以下操作:

#' @export
box::use(./functions[...])

并加载 wrapper.R 本身,使用

box::use(project/wrapper)

其中 project 是项目名称,需要与您的 wrapper.R 脚本所在的文件夹名称相对应。

请参阅 Get started 小插图以了解有关“box”模块用法的更多信息。