R:source()和源文件的路径

eri*_*fas 5 r function relative-path chdir

在R中必须有一些我对这个source()命令不了解的东西.我还是新手,但我不能为我的生活理解它是如何得到它的目录的!我的问题是:

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

我用Google搜索并找到了许多不同的主题,但这个问题似乎很清楚.我理解它的方式,我正在做的方式应该工作.显然,我误解了一些事情.我对该线程的阅读使我相信它source()可以在调用文件所在的目录中工作source().我的阅读也让我相信我不应该使用chdir = TRUE,因为我想保留广告的相对目录.

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

and*_*rew 13

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

  1. 将所需的所有内容放入一个独立的脚本中并分发.

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

  • “将所需的所有内容放入一个独立的脚本中并进行分发。” 不好,不好,不好的编程习惯。可读性很重要。 (3认同)
  • “在最简单的形式中,包只是一个目录......”这过于简单化了。包的_source_是一个包含某些文件和子目录的目录,但要实际将包_加载_到R中,必须首先对其进行编译。这对于初学者来说可能很棘手。 (3认同)

小智 8

您可以使用here包进行此操作。它使用“加载程序包时的当前工作目录”。换句话说,您从中开始R会话的目录。

在您的情况下,代码为:

source(here::here('functions.R'))
Run Code Online (Sandbox Code Playgroud)

即使包装程序脚本wrapper.R位于项目中的其他目录中,该方法也将起作用。

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

source(here::here('subdirectory', 'functions.R'))
Run Code Online (Sandbox Code Playgroud)