setupProject | R Documentation |
setupProject
calls a sequence of functions in this order:
setupOptions
(first time), setupPaths
, setupRestart
,
setupFunctions
, setupModules
, setupPackages
, setupSideEffects
,
setupOptions
(second time), setupParams
, and setupGitIgnore
.
This sequence will create folder structures, install missing packages from those
listed in either the packages
, require
arguments or in the modules reqdPkgs
fields,
load packages (only those in the require
argument), set options, download or
confirm the existence of modules. It will also return elements that can be passed
directly to simInit
or simInitAndSpades
, specifically, modules
, params
,
paths
, times
, and any named elements passed to ...
. This function will also
, if desired, change the .Rprofile file for this project so that every time
the project is opened, it has a specific .libPaths()
.
There are a number of convenience elements described in the section below. See Details.
Because of this sequence, users can take advantage of settings (i.e., objects)
that happen (are created) before others. For example, users can set paths
then use the paths
list to set options
that will can update/change paths
,
or set times
and use the times
list for certain entries in params
.
setupProject(
name,
paths,
modules,
packages,
times,
options,
params,
sideEffects,
functions,
config,
require = NULL,
studyArea = NULL,
Restart = getOption("SpaDES.project.Restart", FALSE),
useGit = getOption("SpaDES.project.useGit", FALSE),
setLinuxBinaryRepo = getOption("SpaDES.project.setLinuxBinaryRepo", TRUE),
standAlone = getOption("SpaDES.project.standAlone", TRUE),
libPaths = NULL,
updateRprofile = getOption("SpaDES.project.updateRprofile", TRUE),
overwrite = getOption("SpaDES.project.overwrite", FALSE),
verbose = getOption("Require.verbose", 1L),
defaultDots,
envir = parent.frame(),
dots,
...
)
name |
Optional. If supplied, the name of the project. If not supplied, an
attempt will be made to extract the name from the |
paths |
a list with named elements, specifically, |
modules |
a character string of modules to pass to |
packages |
Optional. A vector of packages that must exist in the |
times |
Optional. This will be returned if supplied; if supplied, the values
can be used in e.g., |
options |
Optional. Either a named list to be passed to |
params |
Optional. Similar to |
sideEffects |
Optional. This can be an expression or one or more file names or
a code chunk surrounded by |
functions |
A set of function definitions to be used within |
config |
Still experimental linkage to the |
require |
Optional. A character vector of packages to install and attach
(with |
studyArea |
Optional. If a list, it will be passed to
|
Restart |
Logical or character. If either |
useGit |
(if not FALSE, then experimental still). There are two levels at which a project
can use GitHub, either the |
setLinuxBinaryRepo |
Logical. Should the binary RStudio Package Manager be used on Linux (ignored if Windows) |
standAlone |
A logical. Passed to |
libPaths |
Deprecated. Use |
updateRprofile |
Logical. Should the |
overwrite |
Logical vector or character vector, however, only |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
defaultDots |
A named list of any arbitrary R objects.
These can be supplied to give default values to objects that
are otherwise passed in with the |
envir |
The environment where |
dots |
Any other named objects passed as a list a user might want for other elements. |
... |
further named arguments that acts like |
setupProject
will return a named list with elements modules
, paths
, params
, and times
.
The goal of this list is to contain list elements that can be passed directly
to simInit
.
It will also append all elements passed by the user in the ...
.
This list can be passed directly to SpaDES.core::simInit()
or
SpaDES.core::simInitAndSpades()
using a do.call()
. See example.
NOTE: both projectPath
and packagePath
will be omitted in the paths
list
as they are used to set current directory (found with getwd()
) and .libPaths()[1]
,
but are not accepted by simInit
. setupPaths
will still return these two paths as its
outputs are not expected to be passed directly to simInit
(unlike setupProject
outputs).
There are a number of checks that occur during setupProject
. These take time, particularly
after an R restart (there is some caching in RAM that occurs, but this will only speed
things up if there is no restart of R). To get the "fastest", these options or settings
will speed things up, at the expense of not being completely re-runnable.
You can add one or more of these to the arguments. These will only be useful after a project
is set up, i.e., setupProject
and SpaDES.core::simInit
has/have been run at least once
to completion (so packages are installed).
options = c( reproducible.useMemoise = TRUE, # For caching, use memory objects Require.cloneFrom = Sys.getenv("R_LIBS_USER"),# Use personal library as possible source of packages spades.useRequire = FALSE, # Won't install packages/update versions spades.moduleCodeChecks = FALSE, # moduleCodeChecks checks for metadata mismatches reproducible.inputPaths = "~/allData"), # For sharing data files across projects packages = NULL, # Prevents any packages installs with setupProject useGit = FALSE # Prevents checks using git
These will be set early in setupProject
, so will affect the running of setupProject
.
If the user manually sets one of these in addition to setting these, the user options will
override these.
The remining causes of setupProject
being "slow" will be loading the required packages.
These options/arguments can now be set all at once
(with caution as these changes will affect how your
script will be run) with options(SpaDES.project.fast = TRUE)
or in the options
argument.
The overarching objectives for these functions are:
To prepare what is needed for simInit
.
To help a user eliminate virtually all assignments to the .GlobalEnv
,
as these create and encourage spaghetti code that becomes unreproducible
as the project increases in complexity.
Be very simple for beginners, but powerful enough to expand to almost any needs of arbitrarily complex projects, using the same structure
Deal with the complexities of R package installation and loading when working with modules that may have been created by many users
Create a common SpaDES project structure, allowing easy transition from one project to another, regardless of complexity.
Throughout these functions, efforts have been made to implement sequential evaluation,
within files and within lists. This means that a user can use the values from an
upstream element in the list. For example, the following where projectPath
is
part of the list that will be assigned to the paths
argument and it is then
used in the subsequent list element is valid:
setupPaths(paths = list(projectPath = "here", modulePath = file.path(paths[["projectPath"]], "modules")))
Because of such sequential evaluation, paths
, options
, and params
files
can be sequential lists that have impose a hierarchy specified
by the order. For example, a user can first create a list of default options,
then several lists of user-desired options behind an if (user("emcintir"))
block that add new or override existing elements, followed by machine
specific
values, such as paths.
setupOptions( maxMemory <- 5e+9 # if (grepl("LandWeb", runName)) 5e+12 else 5e+9 # Example -- Use any arbitrary object that can be passed in the `...` of `setupOptions` # or `setupProject` if (.mode == "development") { list(test = 2) } if (machine("A127")) { list(test = 3) } )
The arguments, paths
, options
, and params
, can all
understand lists of named values, character vectors, or a mixture by using a list where
named elements are values and unnamed elements are character strings/vectors. Any unnamed
character string/vector will be treated as a file path. If that file path has an @
symbol,
it will be assumed to be a file that exists on a GitHub repository in https://github.com
.
So a user can pass values, or pointers to remote and/or local paths that themselves have values.
The following will set an option as declared, plus read the local file (with relative path), plus download and read the cloud-hosted file.
setupProject( options = list(reproducible.useTerra = TRUE, "inst/options.R", "PredictiveEcology/SpaDES.project@transition/inst/options.R") ) )
This approach allows for an organic growth of complexity, e.g., a user begins with only named lists of values, but then as the number of values increases, it may be helpful to put some in an external file.
NOTE: if the GitHub repository is private the user must configure their GitHub
token by setting the GITHUB_PAT environment variable – unfortunately, the usethis
approach to setting the token will not work at this moment.
paths
, options
, params
If paths
, options
, and/or params
are a character string
or character vector (or part of an unnamed list element) the string(s)
will be interpreted as files to parse. These files should contain R code that
specifies named lists, where the names are one or more paths
, options
,
or are module names, each with a named list of parameters for that named module.
This last named list for params
follows the convention used for the params
argument in
simInit(..., params = )
.
These files can use paths
, times
, plus any previous list in the sequence of
params
or options
specified. Any functions that are used must be available,
e.g., prefixed Require::normPath
if the package has not been loaded (as recommended).
If passing a file to options
, it should not set options()
explicitly;
only create named lists. This enables options checking/validating
to occur within setupOptions
and setupParams
. A simplest case would be a file with this:
opts <- list(reproducible.destinationPath = "~/destPath")
.
All named lists will be parsed into their own environment, and then will be
sequentially evaluated (i.e., subsequent lists will have access to previous lists),
with each named elements setting or replacing the previously named element of the same name,
creating a single list. This final list will be assigned to, e.g., options()
inside setupOptions
.
Because each list is parsed separately, they to not need to be assigned objects;
if they are, the object name can be any name, even if similar to another object's name
used to built the same argument's (i.e. paths
, params
, options
) final list.
Hence, in an file to passed to options
, instead of incrementing the list as:
a <- list(optA = 1) b <- append(a, list(optB = 2)) c <- append(b, list(optC = 2.5)) d <- append(c, list(optD = 3))
one can do:
a <- list(optA = 1) a <- list(optB = 2) c <- list(optC = 2.5) list(optD = 3)
NOTE: only atomics (i.e., character, numeric, etc.), named lists, or either of these that are protected by 1 level of "if" are parsed. This will not work, therefore, for other side-effect elements, like authenticating with a cloud service.
Several helper functions exist within SpaDES.project
that may be useful, such
as user(...)
, machine(...)
To allow for batch submission, a user can specify code argument = value
even if value
is missing. This type of specification will not work in normal parsing of arguments,
but it is designed to work here. In the next example, .mode = .mode
can be specified,
but if R cannot find .mode
for the right hand side, it will just skip with no error.
Thus a user can source a script with the following line from batch script where .mode
is specified. When running this line without that batch script specification, then this
will assign no value to .mode
. We include .nodes
which shows an example of
passing a value that does exist. The non-existent .mode
will be returned in the out
,
but as an unevaluated, captured list element.
.nodes <- 2 out <- setupProject(.mode = .mode, .nodes = .nodes, options = "inst/options.R" )
setupPaths()
, setupOptions()
, setupPackages()
,
setupModules()
, setupGitIgnore()
. Also, helpful functions such as
user()
, machine()
, node()
vignette("i-getting-started", package = "SpaDES.project")
## For more examples:
vignette("i-getting-started", package = "SpaDES.project")
library(SpaDES.project)
## simplest case; just creates folders
out <- setupProject(
paths = list(projectPath = ".") #
)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.