我正在构建一个RStudio项目(项目2(,我想访问另一个已经构建的RStudio项目(项目1(中包含的某些脚本。项目1包含各种脚本,其中一些脚本通过source()
调用相互引用。有什么办法做到这一点吗?我最初认为在项目1中使用here::here((或box::file((可以促进这一点,但我意识到这两个函数都将引用项目2的工作目录,而不是项目1的工作目录。
例如,假设项目1包含以下文件结构:
> list.files(withr::with_dir("./Project_1", getwd()))
[1] "assumptions.R" "launch.R" "output.R"
[4] "project_env.R" "renv" "renv.lock"
[7] "run_scenarios.R" "Project_1.Rproj" "sample_script_1.R"
[10] "sample_script_2.R" "selected_assumptions.R"
Launch.R是为所有剩余脚本(下面的代码(启动代码的脚本。
启动.R
source("assumptions.R")
source("project_env.R")
project_env$launch_mode = project_env$scenario_toggle$DEFAULT
source("assumptions.R")
source("selected_assumptions.R")
source("output.R")
source("run_scenarios.R")
有没有办法从项目1之外执行Launch.R脚本?由于Project 1的脚本是绑定在一起的,如果我尝试从项目之外的任何地方执行Launch.R,那么它一尝试执行source("assumptions.R")
命令就会出现错误。
任何帮助都将不胜感激。
要使box::file()
返回当前脚本的目录路径而不是当前工作目录,您需要将脚本作为模块加载。最基本的是,这意味着用对box::use
的调用替换source
调用。原因是"box"提供了模块系统,而不是单独的辅助功能;因此box::file
等假设它们是在模块的上下文中被调用的。"盒子"包装小插曲提供了更多信息。
作为用法的一个示例,对于"box"模块,Launch.R
脚本将如下所示:
box::use(
./assumptions[...],
./project_env[...],
./assumptions[...],
./selected_assumptions[...],
./output[...],
./run_scenarios[...],
)
其中:
- 模块名称不带引号
./…
表示这是一个本地的、相对的模块名称(而不是以不同方式搜索的包或全局安装的模块([...]
表示:附加模块内部定义的所有名称;默认情况下,"box"在加载模块时不附加任何导出。默认情况下不会进行附加,因为通常不建议进行附加
请注意,每个模块都有自己的作用域,就像R包一样。因此,语句project_env$launch_mode = project_env$scenario_toggle$DEFAULT
在已加载的模块中没有任何作用。要使模块在调用代码中看到变量,需要将它们显式地传递到模块中。
有了这些更改,其中一个模块内的box::file()
调用将返回该模块目录的路径;并且box::file('some_file')
将返回嵌套在模块内的some_file
的绝对路径(再次,有关更多细节,请参见上面链接的渐晕(。
最后,要在项目之外执行Launch.R
,有了上述更改,您只需运行例如Rscript path/to/Launch.R
,就可以了。或者,您也可以将Launch.R
视为一个模块,并通过box::use
加载它。要在项目外部执行此操作,您需要通过box.path
选项配置"box"搜索路径。之后,您可以通过绝对导入指令(与之前的本地相对的导入指令相反(使用该模块:
box::use(projectname/Launch)
projectname
这里是包含Launch.R
脚本的文件夹的文件夹名称,box.path
选项需要包括其父目录的路径
我遇到了同样的问题,我可以用解决它
here::i_am("path_to_script")
source("path_to_script")
详见here
套餐网站。https://cran.r-project.org/web/packages/here/vignettes/here.html