Reputation: 184
I'm building an RStudio project (Project 2) where I would like to access certain scripts that are contained within another already-built RStudio project (Project 1). Project 1 contains various scripts, some of which reference one another through source()
calls. Is there any way to achieve this? I originally thought that by using here::here() or box::file() in Project 1 could facilitate this, however I realized that both of those functions will reference the working directory of Project 2 as opposed to that of Project 1.
For example, let's say Project 1 contains the following file structure:
> 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"
And Launch.R is the script that launches code for all of the remaining scripts (code below).
Launch.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")
Is there any way to execute the Launch.R script from outside of Project 1? Because of the way Project 1's scripts are tied together, if I try to execute Launch.R from anywhere outside of the project, I get errors as soon as it tries to execute the source("assumptions.R")
command.
Any help would be much appreciated.
Upvotes: 2
Views: 1032
Reputation: 1
I had the same issue, and I could resolve it with
here::i_am("path_to_script")
source("path_to_script")
See here
package website for details. https://cran.r-project.org/web/packages/here/vignettes/here.html
Upvotes: 0
Reputation: 545995
To make box::file()
return the current script’s directory path rather than the current working directory, you’ll need to load the script as a module. At its most basic, this means replacing source
calls with calls to box::use
. The reason is that ‘box’ provides a module system rather than individual helper functions; hence, box::file
etc. assume that they are being called in the context of a module. The ‘box’ package vignette gives further information.
As an example of the usage, with ‘box’ modules your Launch.R
script would look as follows:
box::use(
./assumptions[...],
./project_env[...],
./assumptions[...],
./selected_assumptions[...],
./output[...],
./run_scenarios[...],
)
Where:
./…
signifies that this is a local, relative module name (rather than a package, or globally installed module which is searched differently)[...]
means: attach all names defined inside the module; by default, ‘box’ attaches no exports when loading a module. Attaching isn’t done by default because it’s not generally recommended.Please also note that each module has its own scope, just like R packages. Thus, the statement project_env$launch_mode = project_env$scenario_toggle$DEFAULT
will have no effect in the loaded modules. To make a module see variables in the calling code, you need to pass them explicitly into the module.
With these changes, a box::file()
call inside one of the modules will return the path to that module’s directory; and box::file('some_file')
will return the absolute path of some_file
nested inside the module (again, for more details see the vignette linked above).
Lastly, to execute Launch.R
outside your project, with the above changes, you can simply run e.g. Rscript path/to/Launch.R
and this will work. Alternatively, you can also treat Launch.R
as a module and load it via box::use
. To do this from outside the project, you’ll need to configure ‘box’ search path via the box.path
option. Afterwards, you can use the module via an absolute import directive (in contrast to the previous local, relative import directives):
box::use(projectname/Launch)
projectname
here would be the folder name of the folder that contains your Launch.R
script, and the box.path
option needs to include the path to its parent directory.Upvotes: 0