Title: | Support the Setup of the R Environment for Clinical Trial Programming Workflows |
---|---|
Description: | The purpose of this package is to support the setup the R environment. The two main features are 'autos', to automatically source files and/or directories into your environment, and 'paths' to consistently set path objects across projects for input and output. Both are implemented using a configuration file to allow easy, custom configurations that can be used for multiple or all projects. |
Authors: | Nicholas Masel [aut, cre], Mike Stackhouse [aut] , Aidan Ceney [aut], Janssen R&D [cph, fnd], Atorus Research LLC [cph] |
Maintainer: | Nicholas Masel <[email protected]> |
License: | Apache License 2.0 |
Version: | 0.2.0 |
Built: | 2024-12-16 03:29:22 UTC |
Source: | https://github.com/pharmaverse/envsetup |
Build directory structure from a configuration file
build_from_config(config, root = NULL)
build_from_config(config, root = NULL)
config |
configuration object from config::get() containing paths#' |
root |
root directory to build from. Leave as NULL if using absolute paths. Set to working directory if using relative paths. |
Called for its side-effects. The directories build print as a tree-like format from fs::dir_tree()
.
tmpdir <- tempdir() hierarchy <- "default: paths: data: !expr list(DEV = '/demo/DEV/username/project1/data', PROD = '/demo/PROD/project1/data') output: !expr list(DEV = '/demo/DEV/username/project1/output', PROD = '/demo/PROD/project1/output') programs: !expr list(DEV = '/demo/DEV/username/project1/programs', PROD = '/demo/PROD/project1/programs') docs: !expr list(DEV = 'docs', PROD = 'docs')" writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) config <- config::get(file = file.path(tmpdir, "hierarchy.yml")) build_from_config(config, tmpdir)
tmpdir <- tempdir() hierarchy <- "default: paths: data: !expr list(DEV = '/demo/DEV/username/project1/data', PROD = '/demo/PROD/project1/data') output: !expr list(DEV = '/demo/DEV/username/project1/output', PROD = '/demo/PROD/project1/output') programs: !expr list(DEV = '/demo/DEV/username/project1/programs', PROD = '/demo/PROD/project1/programs') docs: !expr list(DEV = 'docs', PROD = 'docs')" writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) config <- config::get(file = file.path(tmpdir, "hierarchy.yml")) build_from_config(config, tmpdir)
This function will remove any autos that have been set from the search path
detach_autos()
detach_autos()
Called for its side-effects.
tmpdir <- tempdir() print(tmpdir) # account for windows if (Sys.info()['sysname'] == "Windows") { tmpdir <- gsub("\\", "\\\\", tmpdir, fixed = TRUE) } # Create an example config file\ hierarchy <- paste0("default: paths: functions: !expr list(DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'functions'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'functions')) autos: my_functions: !expr list(DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'functions'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'functions'))") # write config writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) config <- config::get(file = file.path(tmpdir, "hierarchy.yml")) build_from_config(config) # write function to DEV writeLines("dev_function <- function() {print(environment(dev_function))}", file.path(tmpdir, 'demo', 'DEV', 'username', 'project1', 'functions', 'dev_function.r')) # write function to PROD writeLines("prod_function <- function() {print(environment(prod_function))}", file.path(tmpdir, 'demo', 'PROD', 'project1', 'functions', 'prod_function.r')) # setup the environment Sys.setenv(ENVSETUP_ENVIRON = "DEV") rprofile(config::get(file = file.path(tmpdir, "hierarchy.yml"))) # show dev_function() and prod_function() are available and print their location dev_function() prod_function() # remove autos from search detach_autos()
tmpdir <- tempdir() print(tmpdir) # account for windows if (Sys.info()['sysname'] == "Windows") { tmpdir <- gsub("\\", "\\\\", tmpdir, fixed = TRUE) } # Create an example config file\ hierarchy <- paste0("default: paths: functions: !expr list(DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'functions'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'functions')) autos: my_functions: !expr list(DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'functions'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'functions'))") # write config writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) config <- config::get(file = file.path(tmpdir, "hierarchy.yml")) build_from_config(config) # write function to DEV writeLines("dev_function <- function() {print(environment(dev_function))}", file.path(tmpdir, 'demo', 'DEV', 'username', 'project1', 'functions', 'dev_function.r')) # write function to PROD writeLines("prod_function <- function() {print(environment(prod_function))}", file.path(tmpdir, 'demo', 'PROD', 'project1', 'functions', 'prod_function.r')) # setup the environment Sys.setenv(ENVSETUP_ENVIRON = "DEV") rprofile(config::get(file = file.path(tmpdir, "hierarchy.yml"))) # show dev_function() and prod_function() are available and print their location dev_function() prod_function() # remove autos from search detach_autos()
Initialize the R environment with envsetup
init(project, config_path = NULL, create_paths = NULL)
init(project, config_path = NULL, create_paths = NULL)
project |
Character. The path to the project directory. |
config_path |
Character. The path of the config file. Defaults to NULL. |
create_paths |
Logical indicating if missing paths should be created. Defaults to NULL. |
Called for its side-effects.
tmpdir <- tempdir() print(tmpdir) # account for windows if (Sys.info()['sysname'] == "Windows") { tmpdir <- gsub("\\", "\\\\", tmpdir, fixed = TRUE) } # Create an example config file\ hierarchy <- paste0("default: paths: data: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'data'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'data')) output: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'output'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'output')) programs: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'programs'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'programs'))") writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) init(project = tmpdir, config_path = file.path(tmpdir, "hierarchy.yml"), create_paths = TRUE)
tmpdir <- tempdir() print(tmpdir) # account for windows if (Sys.info()['sysname'] == "Windows") { tmpdir <- gsub("\\", "\\\\", tmpdir, fixed = TRUE) } # Create an example config file\ hierarchy <- paste0("default: paths: data: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'data'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'data')) output: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'output'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'output')) programs: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'programs'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'programs'))") writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) init(project = tmpdir, config_path = file.path(tmpdir, "hierarchy.yml"), create_paths = TRUE)
Autos need to immediately follow the global environment.
This wrapper around base::library()
will position any
attached packages in the earliest position on the
search path currently occupied by a package environment,
guaranteeing newly loaded packages appear before previously
loaded packages but after any currently attached non-packages.
... |
pass directly through to base::library |
pos |
see base::library. NULL (the default) is taken to mean the earliest position of a package environment within the current search path. If non-null, underlying behavior of base::library is respected. |
returns (invisibly) the list of attached packages
# Simple example library(purrr) # Illustrative example to show that autos will always remain above attached libraries tmpdir <- tempdir() print(tmpdir) # account for windows if (Sys.info()['sysname'] == "Windows") { tmpdir <- gsub("\\", "\\\\", tmpdir, fixed = TRUE) } # Create an example config file hierarchy <- paste0("default: paths: functions: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'functions'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'functions')) autos: my_functions: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'functions'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'functions'))") # write config writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) config <- config::get(file = file.path(tmpdir, "hierarchy.yml")) build_from_config(config) # write function to DEV writeLines("dev_function <- function() {print(environment(dev_function))}", file.path(tmpdir, 'demo/DEV/username/project1/functions/dev_function.r')) # write function to PROD writeLines("prod_function <- function() {print(environment(prod_function))}", file.path(tmpdir, 'demo/PROD/project1/functions/prod_function.r')) # setup the environment Sys.setenv(ENVSETUP_ENVIRON = "DEV") rprofile(config::get(file = file.path(tmpdir, "hierarchy.yml"))) # show search search() # now attach purrr library(purrr) # see autos are still above purrr in the search path search()
# Simple example library(purrr) # Illustrative example to show that autos will always remain above attached libraries tmpdir <- tempdir() print(tmpdir) # account for windows if (Sys.info()['sysname'] == "Windows") { tmpdir <- gsub("\\", "\\\\", tmpdir, fixed = TRUE) } # Create an example config file hierarchy <- paste0("default: paths: functions: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'functions'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'functions')) autos: my_functions: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'functions'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'functions'))") # write config writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) config <- config::get(file = file.path(tmpdir, "hierarchy.yml")) build_from_config(config) # write function to DEV writeLines("dev_function <- function() {print(environment(dev_function))}", file.path(tmpdir, 'demo/DEV/username/project1/functions/dev_function.r')) # write function to PROD writeLines("prod_function <- function() {print(environment(prod_function))}", file.path(tmpdir, 'demo/PROD/project1/functions/prod_function.r')) # setup the environment Sys.setenv(ENVSETUP_ENVIRON = "DEV") rprofile(config::get(file = file.path(tmpdir, "hierarchy.yml"))) # show search search() # now attach purrr library(purrr) # see autos are still above purrr in the search path search()
Check each environment for the file and return the path to the first.
read_path( lib, filename, full.path = TRUE, envsetup_environ = Sys.getenv("ENVSETUP_ENVIRON") )
read_path( lib, filename, full.path = TRUE, envsetup_environ = Sys.getenv("ENVSETUP_ENVIRON") )
lib |
object containing the paths for all environments of a directory |
filename |
name of the file you would like to read |
full.path |
logical to return the path including the file name |
envsetup_environ |
name of the environment you would like to read the file from; default values comes from the value in the system variable ENVSETUP_ENVIRON which can be set by Sys.setenv(ENVSETUP_ENVIRON = "environment name") |
The environments searched depends on the current environment. For example, if your workflow contains a development (dev) area and production area (prod), and the code is executing in the dev environment, we search dev and prod. If in prod, we only search prod.
string containing the path of the first directory the file is found
tmpdir <- tempdir() # account for windows if (Sys.info()['sysname'] == "Windows") { tmpdir <- gsub("\\", "\\\\", tmpdir, fixed = TRUE) } # add config for just the data location hierarchy <- paste0("default: paths: data: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'data'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'data'))") # write config file to temp directory writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) config <- config::get(file = file.path(tmpdir, "hierarchy.yml")) # build folder structure from config build_from_config(config) # setup environment based on config rprofile(config::get(file = file.path(tmpdir, "hierarchy.yml"))) # place data in prod data folder saveRDS(mtcars, file.path(tmpdir, "demo/PROD/project1/data/mtcars.rds")) # find the location of mtcars.rds read_path(data, "mtcars.rds")
tmpdir <- tempdir() # account for windows if (Sys.info()['sysname'] == "Windows") { tmpdir <- gsub("\\", "\\\\", tmpdir, fixed = TRUE) } # add config for just the data location hierarchy <- paste0("default: paths: data: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'data'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'data'))") # write config file to temp directory writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) config <- config::get(file = file.path(tmpdir, "hierarchy.yml")) # build folder structure from config build_from_config(config) # setup environment based on config rprofile(config::get(file = file.path(tmpdir, "hierarchy.yml"))) # place data in prod data folder saveRDS(mtcars, file.path(tmpdir, "demo/PROD/project1/data/mtcars.rds")) # find the location of mtcars.rds read_path(data, "mtcars.rds")
Function used to pass through code to the .Rprofile
rprofile(config)
rprofile(config)
config |
configuration object from config::get() |
Called for its side effects. Directory paths and autos are added to the search path based on your config.
# temp location to store configuration files tmpdir <- tempdir() print(tmpdir) # Create an example config file hierarchy <- "default: paths: data: !expr list(DEV = '/demo/DEV/username/project1/data', PROD = '/demo/PROD/project1/data') output: !expr list(DEV = '/demo/DEV/username/project1/output', PROD = '/demo/PROD/project1/output') programs: !expr list(DEV = '/demo/DEV/username/project1/programs', PROD = '/demo/PROD/project1/programs')" writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) rprofile(config::get(file = file.path(tmpdir, "hierarchy.yml")))
# temp location to store configuration files tmpdir <- tempdir() print(tmpdir) # Create an example config file hierarchy <- "default: paths: data: !expr list(DEV = '/demo/DEV/username/project1/data', PROD = '/demo/PROD/project1/data') output: !expr list(DEV = '/demo/DEV/username/project1/output', PROD = '/demo/PROD/project1/output') programs: !expr list(DEV = '/demo/DEV/username/project1/programs', PROD = '/demo/PROD/project1/programs')" writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) rprofile(config::get(file = file.path(tmpdir, "hierarchy.yml")))
A helper function to help troubleshoot common problems that can occur when building your configuration file.
validate_config(config)
validate_config(config)
config |
configuration object from config::get() |
Called for its side-effects. Prints findings from validation checks.
# temp location to store configuration files tmpdir <- tempdir() print(tmpdir) # Each path only points to one location, i.e. there is no hierarchy for a path no_hierarchy <- 'default: paths: data: "/demo/DEV/username/project1/data" output: "/demo/DEV/username/project1/output" programs: "/demo/DEV/username/project1/programs"' writeLines(no_hierarchy, file.path(tmpdir, "no_hierarchy.yml")) validate_config(config::get(file = file.path(tmpdir, "no_hierarchy.yml"))) # A path can point to multiple locations, i.e. there is a hierarchy hierarchy <- "default: paths: data: !expr list(DEV = '/demo/DEV/username/project1/data', PROD = '/demo/PROD/project1/data') output: !expr list(DEV = '/demo/DEV/username/project1/output', PROD = '/demo/PROD/project1/output') programs: !expr list(DEV = '/demo/DEV/username/project1/programs', PROD = '/demo/PROD/project1/programs') envsetup_environ: !expr Sys.setenv(ENVSETUP_ENVIRON = 'DEV'); 'DEV'" writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) validate_config(config::get(file = file.path(tmpdir, "hierarchy.yml"))) # A hierarchy is present for paths, but they are not named hierarchy_no_names <- "default: paths: data: !expr list('/demo/DEV/username/project1/data', '/demo/PROD/project1/data') output: !expr list('/demo/DEV/username/project1/output', '/demo/PROD/project1/output') programs: !expr list('/demo/DEV/username/project1/programs', '/demo/PROD/project1/programs') envsetup_environ: !expr Sys.setenv(ENVSETUP_ENVIRON = 'DEV'); 'DEV'" writeLines(hierarchy_no_names, file.path(tmpdir, "hierarchy_no_names.yml")) validate_config(config::get(file = file.path(tmpdir, "hierarchy_no_names.yml"))) # No paths are specified no_paths <- "default: autos: my_functions: '/demo/PROD/project1/R'" writeLines(no_paths, file.path(tmpdir, "no_paths.yml")) validate_config(config::get(file = file.path(tmpdir, "no_paths.yml")))
# temp location to store configuration files tmpdir <- tempdir() print(tmpdir) # Each path only points to one location, i.e. there is no hierarchy for a path no_hierarchy <- 'default: paths: data: "/demo/DEV/username/project1/data" output: "/demo/DEV/username/project1/output" programs: "/demo/DEV/username/project1/programs"' writeLines(no_hierarchy, file.path(tmpdir, "no_hierarchy.yml")) validate_config(config::get(file = file.path(tmpdir, "no_hierarchy.yml"))) # A path can point to multiple locations, i.e. there is a hierarchy hierarchy <- "default: paths: data: !expr list(DEV = '/demo/DEV/username/project1/data', PROD = '/demo/PROD/project1/data') output: !expr list(DEV = '/demo/DEV/username/project1/output', PROD = '/demo/PROD/project1/output') programs: !expr list(DEV = '/demo/DEV/username/project1/programs', PROD = '/demo/PROD/project1/programs') envsetup_environ: !expr Sys.setenv(ENVSETUP_ENVIRON = 'DEV'); 'DEV'" writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) validate_config(config::get(file = file.path(tmpdir, "hierarchy.yml"))) # A hierarchy is present for paths, but they are not named hierarchy_no_names <- "default: paths: data: !expr list('/demo/DEV/username/project1/data', '/demo/PROD/project1/data') output: !expr list('/demo/DEV/username/project1/output', '/demo/PROD/project1/output') programs: !expr list('/demo/DEV/username/project1/programs', '/demo/PROD/project1/programs') envsetup_environ: !expr Sys.setenv(ENVSETUP_ENVIRON = 'DEV'); 'DEV'" writeLines(hierarchy_no_names, file.path(tmpdir, "hierarchy_no_names.yml")) validate_config(config::get(file = file.path(tmpdir, "hierarchy_no_names.yml"))) # No paths are specified no_paths <- "default: autos: my_functions: '/demo/PROD/project1/R'" writeLines(no_paths, file.path(tmpdir, "no_paths.yml")) validate_config(config::get(file = file.path(tmpdir, "no_paths.yml")))
Paths will be filtered to produce the lowest available level from a hierarchy of paths based on envsetup_environ
write_path( lib, filename = NULL, envsetup_environ = Sys.getenv("ENVSETUP_ENVIRON") )
write_path( lib, filename = NULL, envsetup_environ = Sys.getenv("ENVSETUP_ENVIRON") )
lib |
Object containing the paths for all environments of a directory |
filename |
Name of the file you would like to write |
envsetup_environ |
Name of the environment to which you would like to write. Defaults to the ENVSETUP_ENVIRON environment variable |
path to write
tmpdir <- tempdir() # account for windows if (Sys.info()['sysname'] == "Windows") { tmpdir <- gsub("\\", "\\\\", tmpdir, fixed = TRUE) } # add config for just the data location hierarchy <- paste0("default: paths: data: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'data'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'data'))") # write config file to temp directory writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) config <- config::get(file = file.path(tmpdir, "hierarchy.yml")) # build folder structure from config build_from_config(config) # setup environment based on config rprofile(config::get(file = file.path(tmpdir, "hierarchy.yml"))) # find location to write mtcars.rds write_path(data, "mtcars.rds") # save data in data folder using write_path saveRDS(mtcars, write_path(data, "mtcars.rds"))
tmpdir <- tempdir() # account for windows if (Sys.info()['sysname'] == "Windows") { tmpdir <- gsub("\\", "\\\\", tmpdir, fixed = TRUE) } # add config for just the data location hierarchy <- paste0("default: paths: data: !expr list( DEV = file.path('",tmpdir,"', 'demo', 'DEV', 'username', 'project1', 'data'), PROD = file.path('",tmpdir,"', 'demo', 'PROD', 'project1', 'data'))") # write config file to temp directory writeLines(hierarchy, file.path(tmpdir, "hierarchy.yml")) config <- config::get(file = file.path(tmpdir, "hierarchy.yml")) # build folder structure from config build_from_config(config) # setup environment based on config rprofile(config::get(file = file.path(tmpdir, "hierarchy.yml"))) # find location to write mtcars.rds write_path(data, "mtcars.rds") # save data in data folder using write_path saveRDS(mtcars, write_path(data, "mtcars.rds"))