diff --git a/DESCRIPTION b/DESCRIPTION index 8174ef1..dc61c5b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: Ulysses Title: Automate OHDSI Study Setup -Version: 0.0.3 +Version: 0.0.4 Authors@R: person("Martin", "Lavallee", , "martin.lavallee@odysseusinc.com", role = c("aut", "cre")) Description: Automates setup of OHDSI study and provides functions to assist on improving organization diff --git a/NAMESPACE b/NAMESPACE index 45135b2..62ae95e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,37 +2,54 @@ export("%>%") export(addConfig) +export(addDataSources) +export(addLinks) +export(addStudyMember) +export(addTags) export(buildStudyHub) export(checkConfig) export(checkDatabaseCredential) export(cohortManifest) export(defaultCredentials) +export(importCredentialsToConfig) +export(importImages) +export(initConfig) export(isOhdsiStudy) export(makeAnalysisPlan) export(makeAnalysisScript) export(makeCaprScript) export(makeCohortDetails) -export(makeConfig) export(makeContributionGuidelines) export(makeHowToRun) export(makeInternals) export(makeKeyringSetup) -export(makeMeetingMinutes) +export(makeMigrationScript) export(makeNews) -export(makeOhdsiProtocol) export(makeReadMe) export(makeResultsReport) -export(makeStudySettings) -export(makeTechSpecs) export(makeWebApiScript) export(moduleTable) export(newOhdsiStudy) export(previewStudyHub) export(publishStudyToRepository) -export(requestStudyRepository) +export(retrieveStudySettings) export(setCredential) export(setMultipleCredentials) +export(setStudyAuthors) +export(setStudyDescription) +export(setStudyInfo) export(setStudyKeyring) +export(setStudyLinks) +export(setStudyTags) +export(setStudyTimeline) +export(updateDeveloperInfo) +export(updateLeadInfo) +export(updateStudyDescription) +export(updateStudyEndDate) +export(updateStudyStatus) +export(updateStudyTitle) +export(updateStudyVersion) +export(updateTherapeuticArea) export(zipResults) import(fs) import(rlang) diff --git a/NEWS.md b/NEWS.md index 78af011..36f0c71 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,15 @@ +Ulysses 0.0.4 +============= +* Finalize Directory +* Finalize meta fields for _study.yml +* Reconfigure `newOhdsiStudy()` with better meta inputs +* Add functions to interface with _study.yml +* Reroute makeFiles to directory and meta fields +* Add `makeMigrationsScript()` template +* Update study hub website format +* Update vignette + + Ulysses 0.0.3 ============= diff --git a/R/config.R b/R/config.R index d2e766b..46948c6 100644 --- a/R/config.R +++ b/R/config.R @@ -31,7 +31,7 @@ checkConfig <- function() { bullet = "warning", bullet_col = "yellow") txt <- glue::glue( - "`Ulysses::makeConfig(block = '[block_name]', database = '[database_name]')` " + "`Ulysses::initConfig()` " ) cli::cat_line("To create config.yml edit and run function:\n\n ", crayon::red(txt), "\n") cli::cat_line() @@ -40,6 +40,148 @@ checkConfig <- function() { } +#TODO keep this list up to date +knownDataSourceTable <- function() { + + dt <- tibble::tibble( + databaseName = c("Optum Clinformatics", "Optum Market Clarity", "Merative MarketScan", + "German DA", "CPRD Gold", "CPRD Aurum", "THIN Belgium", "JMDC", "MDV"), + blockId = c("optumClaims", "optumEHR", "mktscan", "da", "gold", "aurum", "thin", "jmdc", "mdv") + ) + return(dt) +} + + + +config_block_text <- function(block, database, title, dbms, user, + password, connectionString, cdmDatabaseSchema, resultsDatabaseSchema, + workDatabaseSchema, tempEmulationSchema, cohortTable) { + + txt <- glue::glue( + "\n\n# {title} Credentials\n +{block}: + databaseName: {database} + dbms: {dbms} + user: {user} + password: {password} + connectionString: {connectionString} + cdmDatabaseSchema: {cdmDatabaseSchema} + resultsDatabaseSchema: {resultsDatabaseSchema} + vocabDatabaseSchema: {cdmDatabaseSchema} + workDatabaseSchema: {workDatabaseSchema} + tempEmulationSchema: {tempEmulationSchema} + cohortTable: {cohortTable} + \n\n") + return(txt) +} +#' Function to import credentials in stored csv to study config.yml +#' @param credFile a credential.csv file stored in a secure location +#' @param projectPath the path to the project +#' @param open toggle on whether the file should be opened +#' @export +importCredentialsToConfig <- function(credFile, projectPath = here::here(), open = TRUE) { + + # import credentials + creds <- readr::read_csv(file = credFile, show_col_types = FALSE) + + # check _study.yml for loaded databases + studyMeta <- retrieveStudySettings(projectPath)$study + dataSources <- studyMeta$about$`data-sources` + + # subset creds with loaded Data Sources + dt <- creds %>% + dplyr::filter( + db_title %in% dataSources + ) + # make cred text for config file + config_txt <- purrr::pmap_chr( + dt, + ~config_block_text( + block = ..1, + database = ..2, + title = ..3, + dbms = ..4, + user = ..9, + password = ..10, + connectionString = ..5, + cdmDatabaseSchema = ..6, + resultsDatabaseSchema = ..8, + workDatabaseSchema = ..7, + tempEmulationSchema = ..7, + cohortTable = paste0("cohort_", ..1) + ) + ) + + header <- glue::glue(" # Config File for {studyMeta$title}\n +default: + projectName: {studyMeta$id} + ") + + full_txt <- c(header, config_txt) + readr::write_lines(full_txt, file = fs::path(projectPath, "config.yml")) + + cli::cat_bullet("Initializing config.yml using imported credentials", + bullet = "tick", bullet_col = "green") + + + if (open) { + + cli::cat_bullet("Check config.yml", + bullet = "bullet", bullet_col = "red") + + rstudioapi::navigateToFile(file = fs::path(projectPath, "config.yml")) + } + + invisible(full_txt) + +} + + +#' Function to create a config.yml file +#' @param block the name of the config block, defaults to BlockName +#' @param database the name of the database for the block, default to DatabaseName +#' @param withKeyring should the config file use keyring, default FALSE +#' @param projectPath the path to the project +#' @param open toggle on whether the file should be opened +#' @export +initConfig <- function(block = "BlockName", + database = "DatabaseName", + withKeyring = FALSE, + projectPath = here::here(), + open = TRUE) { + + # retrieve study meta + studyMeta <- retrieveStudySettings(projectPath = projectPath)$study + + + data <- rlang::list2( + 'Title' = studyMeta$title, + 'ID' = studyMeta$id, + 'Cohort' = paste(studyMeta$id, database, sep = "_"), + 'Block' = block, + 'Database' = database + ) + + if (withKeyring) { + template_file <- "config_keyring.yml" + } else { + template_file <- "config_raw.yml" + } + + usethis::use_template( + template = template_file, + save_as = fs::path("config.yml"), + data = data, + open = open, + package = "Ulysses") + + usethis::use_git_ignore(ignores = "config.yml") + + invisible(data) +} + + + #' Add a line to the config file #' @param block the name of the config block #' @param database the name of the database for the block, default to block name diff --git a/R/makeFiles.R b/R/makeFiles.R index 8a9b0cc..3b9ecd1 100644 --- a/R/makeFiles.R +++ b/R/makeFiles.R @@ -8,23 +8,30 @@ makeReadMe <- function(projectPath = here::here(), open = TRUE) { # retrieve study meta - studyMeta <- retrieveStudySettings(projectPath = projectPath) + studyMeta <- retrieveStudySettings(projectPath = projectPath)$study + + #prep author info as single line name(email) + leadAuthor <- glue::glue("{studyMeta$authors$lead$name} ({studyMeta$authors$lead$email})") + developerAuthor <- glue::glue("{studyMeta$authors$developer$name} ({studyMeta$authors$developer$email})") + + # prep data sources + dataSources <- paste(studyMeta$about$`data-sources`, collapse = ", ") + + # prep tags + tags <- paste(studyMeta$tags, collapse = ", ") - #create template vars data <- rlang::list2( - 'Project' = studyMeta$Title, - 'StudyType' = studyMeta$Description$StudyType, - 'Contact' = studyMeta$Contact$Name, - 'ContactEmail' = studyMeta$Contact$Email, - 'CdmVersion' = studyMeta$CDM$CdmVersion, - 'VocabVersion' = studyMeta$CDM$VocabVersion, - 'VocabRelease' = studyMeta$CDM$VocabRelease, - 'StudyStatus' = studyMeta$Milestones$Status, - 'ForumPost' = studyMeta$Links$Forum, - 'Protocol' = studyMeta$Links$Protocol, - 'Hub' = studyMeta$Links$StudyHub, - 'Dashboard' = studyMeta$Links$ResultsDashboard, - 'Report' = studyMeta$Links$Report + 'Title' = studyMeta$title, + 'ID' = studyMeta$id, + 'Type' = studyMeta$type, + 'Start' = studyMeta$timeline$`start-date`, + 'End' = studyMeta$timeline$`end-date`, + 'Lead' = leadAuthor, + 'Developer' = developerAuthor, + 'Tags' = tags, + 'TA' = studyMeta$about$`therapeutic-area`, + 'Description' = studyMeta$about$description, + 'DS' = dataSources ) #load template with vars @@ -45,10 +52,11 @@ makeReadMe <- function(projectPath = here::here(), open = TRUE) { makeNews <- function(projectPath = here::here(), open = TRUE) { # retrieve study meta - studyMeta <- retrieveStudySettings(projectPath = projectPath) + studyMeta <- retrieveStudySettings(projectPath = projectPath)$study data <- rlang::list2( - 'Project' = studyMeta$Title + 'ID' = studyMeta$id, + 'Version' = studyMeta$version ) usethis::use_template( @@ -61,40 +69,15 @@ makeNews <- function(projectPath = here::here(), open = TRUE) { } -#' Function to create a config.yml file -#' @param block the name of the config block -#' @param database the name of the database for the block, default to block name -#' @param projectPath the path to the project -#' @param open toggle on whether the file should be opened -#' @export -makeConfig <- function(block, database = block, projectPath = here::here(), open = TRUE) { - - projFile <- list.files(projectPath, pattern = ".Rproj", full.names = TRUE) - projName <- basename(tools::file_path_sans_ext(projFile)) - - data <- rlang::list2( - 'Project' = projName, - 'Cohort' = paste(projName, database, sep = "_"), - 'Block' = block, - 'Database' = database - ) - usethis::use_template( - template = "config.yml", - data = data, - open = open, - package = "Ulysses") - usethis::use_git_ignore(ignores = "config.yml") +# Documentation Files ----------------------- - invisible(data) +replaceTitleColon <- function(title){ + gsub("\\:", "-", title) } - - -# Documentation Files ----------------------- - #' Function to create a SAP #' @param projectPath the path to the project #' @param open toggle on whether the file should be opened @@ -103,17 +86,18 @@ makeAnalysisPlan <- function(projectPath = here::here(), open = TRUE) { # retrieve study meta - studyMeta <- retrieveStudySettings(projectPath = projectPath) + studyMeta <- retrieveStudySettings(projectPath = projectPath)$study # make list of vars for template data <- rlang::list2( - 'Study' = studyMeta$Title + 'Title' = replaceTitleColon(studyMeta$title), + 'Developer' = studyMeta$authors$developer$name ) #create templated output usethis::use_template( template = "AnalysisPlan.qmd", - save_as = fs::path("documentation", "AnalysisPlan.qmd"), + save_as = fs::path("documentation/hub", "AnalysisPlan.qmd"), data = data, open = open, package = "Ulysses") @@ -131,16 +115,16 @@ makeContributionGuidelines <- function(projectPath = here::here(), open = TRUE) { # retrieve study meta - studyMeta <- retrieveStudySettings(projectPath = projectPath) + studyMeta <- retrieveStudySettings(projectPath = projectPath)$study # make list of vars for template data <- rlang::list2( - 'Study' = studyMeta$Title + 'Title' = replaceTitleColon(studyMeta$title) ) usethis::use_template( template = "ContributionGuidelines.qmd", - save_as = fs::path("documentation", "ContributionGuidelines.qmd"), + save_as = fs::path("documentation/hub", "ContributionGuidelines.qmd"), data = data, open = open, package = "Ulysses") @@ -157,16 +141,17 @@ makeResultsReport <- function(projectPath = here::here(), open = TRUE) { # retrieve study meta - studyMeta <- retrieveStudySettings(projectPath = projectPath) + studyMeta <- retrieveStudySettings(projectPath = projectPath)$study # make list of vars for template data <- rlang::list2( - 'Study' = studyMeta$Title + 'Title' = replaceTitleColon(studyMeta$title), + 'Developer' = studyMeta$authors$developer$name ) usethis::use_template( template = "ResultsReport.qmd", - save_as = fs::path("documentation", "ResultsReport.qmd"), + save_as = fs::path("documentation/hub", "ResultsReport.qmd"), data = data, open = open, package = "Ulysses") @@ -185,17 +170,18 @@ makeHowToRun <- function(projectPath = here::here(), open = TRUE) { # retrieve study meta - studyMeta <- retrieveStudySettings(projectPath = projectPath) + studyMeta <- retrieveStudySettings(projectPath = projectPath)$study # make list of vars for template data <- rlang::list2( - 'Study' = studyMeta$Title + 'Title' = replaceTitleColon(studyMeta$title), + 'Developer' = studyMeta$authors$developer$name ) usethis::use_template( template = "HowToRun.qmd", - save_as = fs::path("documentation", "HowToRun.qmd"), + save_as = fs::path("documentation/hub", "HowToRun.qmd"), data = data, open = open, package = "Ulysses") @@ -204,67 +190,38 @@ makeHowToRun <- function(projectPath = here::here(), } -#' Function to create a HowToRun file -#' @param projectPath the path to the project -#' @param open toggle on whether the file should be opened -#' @export -makeTechSpecs <- function( - projectPath = here::here(), - open = TRUE) { - - # retrieve study meta - studyMeta <- retrieveStudySettings(projectPath = projectPath) - - # make list of vars for template - data <- rlang::list2( - 'Study' = studyMeta$Title - ) - - - usethis::use_template( - template = "TechSpecs.qmd", - save_as = fs::path("documentation", "TechSpecs.qmd"), - data = data, - open = open, - package = "Ulysses") - - invisible(data) -} # TODO update this to quarto -#' R Markdown file to make the ohdsi protocol -#' @param projectPath the path to the project -#' @param open toggle on whether the file should be opened -#' @export -makeOhdsiProtocol <- function(projectPath = here::here(), - open = TRUE) { - data <- rlang::list2( - 'Study' = getStudyDetails(item = "StudyTitle", projectPath = projectPath), - 'Date' = lubridate::today() - ) - - fileName <- snakecase::to_upper_camel_case(getStudyDetails(item = "StudyTitle", projectPath = projectPath)) %>% - paste0("Protocol") - - dir_path <- fs::path("documentation", "Protocol") %>% - fs::dir_create() - - usethis::use_template( - template = "OhdsiProtocol.Rmd", - save_as = fs::path(dir_path, fileName, ext = "Rmd"), - data = data, - open = open, - package = "Ulysses") - - #get Protocol Components and move to folder - fs::path_package("Ulysses", "templates/Protocol-Components") %>% - fs::dir_copy(new_path = dir_path, overwrite = TRUE) - - - invisible(data) -} +# makeOhdsiProtocol <- function(projectPath = here::here(), +# open = TRUE) { +# +# data <- rlang::list2( +# 'Study' = getStudyDetails(item = "StudyTitle", projectPath = projectPath), +# 'Date' = lubridate::today() +# ) +# +# fileName <- snakecase::to_upper_camel_case(getStudyDetails(item = "StudyTitle", projectPath = projectPath)) %>% +# paste0("Protocol") +# +# dir_path <- fs::path("documentation", "Protocol") %>% +# fs::dir_create() +# +# usethis::use_template( +# template = "OhdsiProtocol.Rmd", +# save_as = fs::path(dir_path, fileName, ext = "Rmd"), +# data = data, +# open = open, +# package = "Ulysses") +# +# #get Protocol Components and move to folder +# fs::path_package("Ulysses", "templates/Protocol-Components") %>% +# fs::dir_copy(new_path = dir_path, overwrite = TRUE) +# +# +# invisible(data) +# } @@ -320,97 +277,94 @@ makeKeyringSetup <- function(database = NULL, } -#' Email asking to initialize an ohdsi-studies repo -#' -#' @param senderName your name as the person sending the email -#' @param senderEmail your email address -#' @param githubUserName your github username. -#' @param recipientName the recipients name, defaults to Admin -#' @param recipientEmail the recipients email, defaults to a dummy email -#' @param projectPath the path to the Ulysses project -#' @param open toggle on whether the file should be opened -#' -#' @details -#' This function works best if you have properly setup a Github PAT. To configure the PAT -#' follow the \href{https://gh.r-lib.org/articles/managing-personal-access-tokens.html}{instructions} -#' from the gh package. -#' -#' -#' @export -requestStudyRepository <- function(senderName, - senderEmail, - githubUserName = NULL, - recipientName = NULL, - recipientEmail = NULL, - projectPath = here::here(), - open = TRUE) { - #get repo name - repoName <- basename(projectPath) %>% - snakecase::to_upper_camel_case() - - - if (is.null(recipientName)) { - recipientName <- "Admin" - } - - if (is.null(recipientEmail)) { - recipientEmail <- "adminEmail@ohdsi.org" - } - - - if (is.null(githubUserName)) { - githubUser <- getGithubUser() - } - - data <- rlang::list2( - 'RepoName' = repoName, - 'GithubUser' = githubUser, - 'SenderName' = senderName, - 'SenderEmail' = senderEmail, - 'RecipientName' = recipientName, - 'RecipientEmail' = recipientEmail - ) - - usethis::use_template( - template = "RequestRepositoryEmail.R", - save_as = fs::path("extras", "RequestRepositoryEmail.R"), - data = data, - open = open, - package = "Ulysses") - - - usethis::use_git_ignore(ignores = "extras/RequestRepositoryEmail.R") - - invisible(data) - -} - - -#' Function to create a meeting minutes file -#' @param projectPath the path to the project -#' @param open toggle on whether the file should be opened -#' @export -makeMeetingMinutes <- function(projectPath = here::here(), open = TRUE) { - - data <- rlang::list2( - 'Study' = getStudyDetails("StudyTitle", projectPath = projectPath), - 'Author' = getStudyDetails("StudyLead", projectPath = projectPath), - 'Date' = lubridate::today() - ) - - saveName <- glue::glue("minutes_{lubridate::today()}") %>% - snakecase::to_snake_case() - - usethis::use_template( - template = "MeetingMinutes.qmd", - save_as = fs::path("extras/minutes", saveName, ext = "qmd"), - data = data, - open = open, - package = "Ulysses") - - invisible(data) - -} +# Email asking to initialize an ohdsi-studies repo +# +# senderName your name as the person sending the email +# senderEmail your email address +# githubUserName your github username. +# recipientName the recipients name, defaults to Admin +# recipientEmail the recipients email, defaults to a dummy email +# projectPath the path to the Ulysses project +# open toggle on whether the file should be opened +# +# +# This function works best if you have properly setup a Github PAT. To configure the PAT +# follow the \href{https://gh.r-lib.org/articles/managing-personal-access-tokens.html}{instructions} +# from the gh package. +# + + +# requestStudyRepository <- function(senderName, +# senderEmail, +# githubUserName = NULL, +# recipientName = NULL, +# recipientEmail = NULL, +# projectPath = here::here(), +# open = TRUE) { +# #get repo name +# repoName <- basename(projectPath) %>% +# snakecase::to_upper_camel_case() +# +# +# if (is.null(recipientName)) { +# recipientName <- "Admin" +# } +# +# if (is.null(recipientEmail)) { +# recipientEmail <- "adminEmail@ohdsi.org" +# } +# +# +# if (is.null(githubUserName)) { +# githubUser <- getGithubUser() +# } +# +# data <- rlang::list2( +# 'RepoName' = repoName, +# 'GithubUser' = githubUser, +# 'SenderName' = senderName, +# 'SenderEmail' = senderEmail, +# 'RecipientName' = recipientName, +# 'RecipientEmail' = recipientEmail +# ) +# +# usethis::use_template( +# template = "RequestRepositoryEmail.R", +# save_as = fs::path("extras", "RequestRepositoryEmail.R"), +# data = data, +# open = open, +# package = "Ulysses") +# +# +# usethis::use_git_ignore(ignores = "extras/RequestRepositoryEmail.R") +# +# invisible(data) +# +# } + + + +# makeMeetingMinutes <- function(projectPath = here::here(), open = TRUE) { +# +# data <- rlang::list2( +# 'Study' = getStudyDetails("StudyTitle", projectPath = projectPath), +# 'Author' = getStudyDetails("StudyLead", projectPath = projectPath), +# 'Date' = lubridate::today() +# ) +# +# saveName <- glue::glue("minutes_{lubridate::today()}") %>% +# snakecase::to_snake_case() +# +# usethis::use_template( +# template = "MeetingMinutes.qmd", +# save_as = fs::path("extras/minutes", saveName, ext = "qmd"), +# data = data, +# open = open, +# package = "Ulysses") +# +# invisible(data) +# +# } # Analysis Files --------------------- @@ -418,12 +372,12 @@ makeMeetingMinutes <- function(projectPath = here::here(), open = TRUE) { #' Function to create a pipeline task as an R file #' @param scriptName The name of the capr file that is being created #' @param configBlock the name of the config block to use for the script +#' @param date the date the script was built, default to today's date #' @param projectPath the path to the project #' @param open toggle on whether the file should be opened #' @export makeCaprScript <- function(scriptName, configBlock = NULL, - author = NULL, date = lubridate::today(), projectPath = here::here(), open = TRUE) { @@ -435,20 +389,12 @@ makeCaprScript <- function(scriptName, } # retrieve study meta - studyMeta <- Ulysses:::retrieveStudySettings(projectPath = projectPath) - - # specify author - if (is.null(author)) { - authorName <- studyMeta$Authors %>% - dplyr::slice(1) %>% - dplyr::pull(name) - } else{ - authorName <- author - } + studyMeta <- Ulysses:::retrieveStudySettings(projectPath = projectPath)$study + data <- rlang::list2( - 'Study' = studyMeta$Title, - 'Author' = authorName, + 'Title' = replaceTitleColon(studyMeta$title), + 'Author' = studyMeta$authors$developer$name, 'Date' = date, 'FileName' = intFileName ) @@ -457,7 +403,7 @@ makeCaprScript <- function(scriptName, usethis::use_template( template = "Capr.R", - save_as = fs::path("analysis/R", intFileName, ext = "R"), + save_as = fs::path("analysis/src", intFileName, ext = "R"), data = data, open = open, package = "Ulysses") @@ -510,12 +456,12 @@ makeWebApiScript <- function(keyringName = NULL, #' Function to create a pipeline task as a Rmd file #' @param scriptName The name of the analysis script #' @param configBlock the name of the config block to use for the script +#' @param date the date the script was built, default to today's date #' @param projectPath the path to the project #' @param open toggle on whether the file should be opened #' @export makeAnalysisScript <- function(scriptName, configBlock = NULL, - author = NULL, date = lubridate::today(), projectPath = here::here(), open = TRUE) { @@ -527,20 +473,12 @@ makeAnalysisScript <- function(scriptName, # retrieve study meta - studyMeta <- retrieveStudySettings(projectPath = projectPath) - - # specify author - if (is.null(author)) { - authorName <- studyMeta$Authors %>% - dplyr::slice(1) %>% - dplyr::pull(name) - } else{ - authorName <- author - } + studyMeta <- retrieveStudySettings(projectPath = projectPath)$study + data <- rlang::list2( - 'Study' = studyMeta$Title, - 'Author' = authorName, + 'Title' = replaceTitleColon(studyMeta$title), + 'Author' = studyMeta$authors$developer$name, 'Date' = date, 'FileName' = scriptName, 'Block' = configBlock @@ -559,36 +497,65 @@ makeAnalysisScript <- function(scriptName, } + + +#' Function to create a migration script +#' @param scriptName The name of the analysis script +#' @param date the date the script was built, default to today's date +#' @param projectPath the path to the project +#' @param open toggle on whether the file should be opened +#' @export +makeMigrationScript <- function(scriptName, + date = lubridate::today(), + projectPath = here::here(), + open = TRUE) { + + + + # retrieve study meta + studyMeta <- retrieveStudySettings(projectPath = projectPath)$study + migrationScriptName <- glue::glue("migrate_{scriptName}") + + + data <- rlang::list2( + 'Title' = replaceTitleColon(studyMeta$title), + 'Author' = studyMeta$authors$developer$name, + 'Date' = date, + 'FileName' = migrationScriptName + ) + + usethis::use_template( + template = "MigrationScript.R", + save_as = fs::path("analysis/migration", migrationScriptName, ext = "R"), + data = data, + open = open, + package = "Ulysses") + + invisible(data) + + +} + + #' Function to create a pipeline task as an R file #' @param internalsName The name of the internals file that is being created +#' @param date the date the script was built, default to today's date #' @param projectPath the path to the project -#' @param author the author of the R file, defaults to first author in _study.yml -#' @param date the date the file was initialized, defaults to today #' @param open toggle on whether the file should be opened #' @export makeInternals <- function(internalsName, - projectPath = here::here(), - author = NULL, date = lubridate::today(), + projectPath = here::here(), open = TRUE) { intFileName <- paste0("_", internalsName) # retrieve study meta - studyMeta <- retrieveStudySettings(projectPath = projectPath) - - # specify author - if (is.null(author)) { - authorName <- studyMeta$Authors %>% - dplyr::slice(1) %>% - dplyr::pull(name) - } else{ - authorName <- author - } + studyMeta <- retrieveStudySettings(projectPath = projectPath)$study + data <- rlang::list2( - 'Study' = studyMeta$Title, - 'Author' = authorName, + 'Author' = studyMeta$authors$developer$name, 'Date' = date, 'FileName' = intFileName ) @@ -596,7 +563,7 @@ makeInternals <- function(internalsName, usethis::use_template( template = "Internals.R", - save_as = fs::path("analysis/R", intFileName, ext = "R"), + save_as = fs::path("analysis/src", intFileName, ext = "R"), data = data, open = open, package = "Ulysses") diff --git a/R/ohdsiStudy.R b/R/ohdsiStudy.R index 6443af2..4855f35 100644 --- a/R/ohdsiStudy.R +++ b/R/ohdsiStudy.R @@ -1,17 +1,46 @@ #' Function that initializes a new ohdsi study project environment #' @param path the path where the project sits #' @param projectName the name of the project -#' @param studySettings a list of study settings +#' @param studyInfo a list object identifying the title, type and study version, +#' defaults to `setStudyInfo`, see documentation +#' @param authors a list object identifying the lead and developer authors names and emails, +#' defaults to `setStudyAuthors`, see documentation. +#' @param timeline a list object identifying the study status, start and end date, +#' defaults to `setStudyTimeline`, see documentation +#' @param about a list object identifying the study description, therapeutic area and databases, +#' defaults to `setStudyDescription`, see documentation +#' @param links a list object identifying the linked resources of the study, +#' defaults to `setStudyLinks`, see documentation +#' @param tags a list object identifying tags to the study, +#' defauls to `setStudyTags`, see documentation #' @param verbose whether the function should provide steps, default TRUE #' @param openProject should the project be opened if created #' @import rlang usethis fs #' @export newOhdsiStudy <- function(path, projectName = basename(path), - studySettings = makeStudySettings(title = basename(path)), + studyInfo = setStudyInfo(id = basename(path)), + authors = setStudyAuthors(), + timeline = setStudyTimeline(), + about = setStudyDescription(), + links = setStudyLinks(), + tags = setStudyTags(), verbose = TRUE, openProject = TRUE) { + + # Step 0: Bind study meta + studyMeta <- studyInfo %>% + append(authors) %>% + append(timeline) %>% + append(about) %>% + append(links) %>% + append(tags) + + studyMeta2 <- list( + 'study' = studyMeta + ) + # Step 1: create project directory if (verbose) { cli::cat_bullet("Step 1: Creating R Project", @@ -33,12 +62,7 @@ newOhdsiStudy <- function(path, addDefaultFolders(projectPath = dir_path, verbose = verbose) # Step 3: create _study.yml file - convert_to_yml(studySettings = studySettings, savePath = dir_path) - # addStudyMeta(projectName = projectName, - # author = author, - # type = type, - # projectPath = dir_path, - # verbose = verbose) + convert_to_yml(studySettings = studyMeta2, savePath = dir_path) # Step 4: create gitignore @@ -70,7 +94,7 @@ isOhdsiStudy <- function(basePath) { check1 <- fs::file_exists("_study.yml") %>% unname() #check if has subfolders - folders <- c("analysis", "cohortsToCreate", "exec", "extras", "documentation") + folders <- c("analysis", "cohorts", "exec", "extras", "documentation") ff <- fs::dir_ls(basePath, type = "directory") %>% basename() @@ -100,14 +124,17 @@ addDefaultFolders <- function(projectPath, verbose = TRUE) { bullet_col = "yellow", bullet = "info") } - analysisFolders <- c("R", "tasks", "migrations") + analysisFolders <- c("src", "tasks", "migrations") execFolders <- c('logs', 'results', "export") + cohortFolders <- c("json", "sql") + documentationFolders <- c("hub", "misc") + folders <- c( - 'cohorts/json', + paste('cohorts', cohortFolders, sep = "/"), paste('analysis', analysisFolders, sep = "/"), paste('exec', execFolders, sep = "/"), - 'extras', - 'documentation' + paste('documentation', documentationFolders, sep = "/"), + 'extras' ) pp <- fs::path("./", folders) %>% @@ -118,36 +145,3 @@ addDefaultFolders <- function(projectPath, verbose = TRUE) { - -# addStudyMeta <- function(projectName, -# author, -# type = c("Characterization", "Population-Level Estimation", "Patient-Level Prediction"), -# projectPath, -# verbose = TRUE){ -# -# if (verbose) { -# cli::cat_bullet("Step 3: Adding _study.yml file", -# bullet_col = "yellow", bullet = "info") -# } -# -# -# -# # projName <- basename(projectPath) %>% -# # snakecase::to_title_case() -# date <- lubridate::today() -# -# data <- rlang::list2( -# 'Title' = projectName, -# 'Author' = author, -# 'Type' = type, -# 'Date' = date -# ) -# -# template_contents <- render_template("_study.yml", data = data) -# save_as <- fs::path(projectPath, "_study.yml") -# new <- write_utf8(save_as, template_contents) -# invisible(new) -# -# -# } - diff --git a/R/studySettings.R b/R/studySettings.R index cc805a1..de0b345 100644 --- a/R/studySettings.R +++ b/R/studySettings.R @@ -1,160 +1,125 @@ # Meta info ------------ -## Authors ----------- -setAuthors <- function(name, organization, role) { - tibble::tibble( - name = name, - organization = organization, - role = role +#' Function to set study info +#' @param id specify the study id +#' @param title specify the study title +#' @param type specify the type of study +#' @param version specify the study version +#' @return a list containing study info +#' @export +setStudyInfo <- function(id, + title = id, + type = c("Characterization"), + version = "0.0.0.999") { + ll <- list( + id = id, + title = title, + type = type, + version = version ) -} -defaultAuthors <- function() { - setAuthors( - name = c("Ulysses", "Eurylochus"), - organization = c("OHDSI", "OHDSI"), - role = c("Lead", "Developer") - ) -} + return(ll) -## Milestones ----------- -setMilestones <- function(status, startDate, endDate) { - list( - 'Status' = status, - 'StartDate' = startDate, - 'EndDate' = endDate - ) } -defaultMilestones <- function() { - setMilestones( - status = "Started", - startDate = "01-01-1960", - endDate = "31-12-2099" - ) -} +#' Function to set study authors +#' @param developer specify the study developer, default to system variable +#' @param developerEmail the email of the developer +#' @param lead specify the lead of the study +#' @param leadEmail specify the lead of the study email +#' @return a list containing study authors +#' @export +setStudyAuthors <- function(developer = Sys.getenv("USERNAME"), + developerEmail = glue::glue("{developer}@ohdsi.org"), + lead = "Ulysses", + leadEmail = "Ulysses@ohdsi.org") { -## Descriptions ----------- -setDescription <- function(studyType, tags) { - list( - 'StudyType' = studyType, - 'Tags' = as.list(tags) + ll <- list( + 'authors' = list( + 'developer' = list( + 'name' = developer, + 'email' = developerEmail + ), + 'lead' = list( + 'name' = lead, + 'email' = leadEmail + ) + ) ) -} -defaultDesc <- function() { - setDescription(studyType = "Characterization", - tags = c("Observational Study", "OMOP", "OHDSI")) -} + return(ll) -## Links ----------- -setLinks <- function(forumPostLink, - protocolLink, - studyHubLink, - resultsDashboardLink, - reportLink) { - list( - 'Forum' = forumPostLink, - 'Protocol' = protocolLink, - 'StudyHub' = studyHubLink, - 'ResultsDashboard' = resultsDashboardLink, - 'Report' = reportLink - ) } -defaultLinks <- function() { - setLinks( - forumPostLink = "TBA", - protocolLink = "TBA", - studyHubLink = "TBA", - resultsDashboardLink = "TBA", - reportLink = "TBA" +#' Function to set study timeline +#' @param status the study status, default is started +#' @param startDate the start of the study, defaults to todays date +#' @param endDate the date specifying the end (or expected end) of the study +#' @return a list containing study timeline +#' @export +setStudyTimeline <- function(status = "Started", + startDate = as.character(lubridate::today()), + endDate = as.character(lubridate::today() + (365 * 2))) { + + ll <- list( + 'timeline' = list( + 'status' = status, + 'start-date' = startDate, + 'end-date' = endDate + ) ) + + return(ll) + } -## Contact ----------- -setContact <- function(name, email) { - list( - 'Name' = name, - 'Email' = email +#' Function to set study description +#' @param desc a brief description of the study +#' @param ta a character string of the therapeutic area +#' @param dataSources a list of data sources +#' @return a list containing study description info +#' @export +setStudyDescription <- function(desc = "Provide a 1 to 2 sentence description of your study. Be concise.", + ta = "Specify the therapeutic area of the study", + dataSources = list("Truven MarketScan", "Optum Market Clarity")) { + + ll <- list( + 'about' = list( + 'description' = desc, + 'therapeutic-area' = ta, + 'data-sources' = dataSources + ) ) -} -defaultContact <- function() { - setContact(name = "Ulysses", email = "ulysses@ohdsi.org") + + return(ll) + } +#' Function to set study links +#' @param ... a series of resource links for the study +#' @return a list containing links to resources +#' @export +setStudyLinks <- function(...) { -## Cdm ----------- -setCdmDetails <- function(cdmVersion, vocabVersion, vocabRelease) { - list( - 'CdmVersion' = cdmVersion, - 'VocabVersion' = vocabVersion, - 'VocabRelease' = vocabRelease + ll <- list( + 'links' = rlang::list2(...) ) + + return(ll) + } -defaultCdmDetails <- function() { - setCdmDetails( - cdmVersion = "v5.3", - vocabVersion = "v5.0", - vocabRelease = "22-06-2022") -} - - -## Data ----------- -# setDataSources <- function(databaseName, location, type, persons, timeFrame) { -# tibble::tibble( -# databaseName = databaseName, -# location = location, -# type = type, -# persons = persons, -# timeFrame -# ) -# } -# -# defaultDataSources <- function() { -# setDataSources( -# databaseName = c("CMS Synpuf"), -# location = c("US"), -# type = c("Claims"), -# persons = c("110K"), -# timeFrame = c("2008-2010") -# ) -# } - -#' Function to initialize study settings -#' @param title the title of the study -#' @param authors the author list for the study -#' @param milestones list of milestone information including study status and timeframe for study -#' @param cdm list of info about the cdm -#' @param desc a list of attributes describing the study including the study type and tages -#' @param contact a list of contact information for study -#' @param links a list of links to files used in study -#' @return a list containing study settings -#' @export -makeStudySettings <- function(title, - authors = defaultAuthors(), - milestones = defaultMilestones(), - cdm = defaultCdmDetails(), - strategus = getLatestModules(), - desc = defaultDesc(), - contact = defaultContact(), - links = defaultLinks()) { - - - - - studySettings <- list( - 'Title' = snakecase::to_title_case(title), - 'Authors' = authors, - 'Description' = desc, - 'Milestones' = milestones, - 'CDM' = cdm, - 'Strategus' = strategus, - 'Links' = links, - 'Contact' = contact + +#' Function to set study tags +#' @param ... a series of tags for the study +#' @return a list containing study tags +#' @export +setStudyTags <- function(...) { + + ll <- list( + 'tags' = rlang::list2(...) ) - return(studySettings) + return(ll) } @@ -179,11 +144,308 @@ convert_to_yml <- function(studySettings, savePath) { } -#Function to convert yml into a specified list format +#' Function to convert yml into a specified list format +#' @param projectPath the path to the project +#' @return the study yml as an R object (list) +#' @export retrieveStudySettings <- function(projectPath){ ymlPath <- fs::path(projectPath, "_study.yml") studyYml <- yaml::read_yaml(ymlPath) - studyYml$Authors <- purrr::map_dfr(studyYml$Authors, ~.x) return(studyYml) } +getStudySettings <- function(projectPath, field) { + + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyElement <- studyYml$study[[field]] + + return(studyElement) +} + +pushStudyUpdate <- function(newStudyYml, projectPath, update, value) { + + cli::cat_bullet( + "Updated _study.yml", + bullet = "tick", bullet_col = "green" + ) + + cli::cat_bullet( + glue::glue("Changed {update} to {crayon::green(value)}"), + bullet = "info", bullet_col = "blue" + ) + + #write _study.yml file + ymlPath <- fs::path(projectPath, "_study", ext = "yml") + yaml::write_yaml( + x = newStudyYml, + file = ymlPath, + column.major = FALSE) + + invisible(ymlPath) + +} + +pushStudyAdd <- function(newStudyYml, projectPath, update, value) { + + cli::cat_bullet( + "Updated _study.yml", + bullet = "tick", bullet_col = "green" + ) + + cli::cat_bullet( + glue::glue("Added {update}: {crayon::green(value)}"), + bullet = "info", bullet_col = "blue" + ) + + #write _study.yml file + ymlPath <- fs::path(projectPath, "_study", ext = "yml") + yaml::write_yaml( + x = newStudyYml, + file = ymlPath, + column.major = FALSE) + + invisible(ymlPath) + +} + +# Update Study settings functions ------------------------ + +#' Function to update study end date +#' @param newEndDate the new end date of the study, suggest format YYYY-MM-DD +#' @param projectPath the path to the project +#' @return invisible studyYml, prints specifying what changes happened +#' @export +updateStudyEndDate <- function(newEndDate, + projectPath = here::here()){ + + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$timeline$`end-date` <- as.character(newEndDate) + + pushStudyUpdate(studyYml, projectPath, update = "Study End Date", value = newEndDate) + + invisible(studyYml) + +} + +#' Function to update study status +#' @param newStudyStatus the new status of the study, accepts Started, In-Progress, Stopped, Completed +#' @param projectPath the path to the project +#' @return invisible studyYml, prints specifying what changes happened +#' @export +updateStudyStatus <- function(newStudyStatus = c("Started", "In-Progress", "Stopped", "Completed"), + projectPath = here::here()) { + + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$timeline$status <- newStudyStatus + + pushStudyUpdate(studyYml, projectPath, update = "Study Status", value = newStudyStatus) + + invisible(studyYml) + +} + +#' Function to update study title +#' @param newStudyTitle the new study title +#' @param projectPath the path to the project +#' @return invisible studyYml, prints specifying what changes happened +#' @export +updateStudyTitle <- function(newStudyTitle, + projectPath = here::here()) { + + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$title <- newStudyTitle + + pushStudyUpdate(studyYml, projectPath, update = "Study Title", value = newStudyTitle) + + invisible(studyYml) + +} + +#' Function to update study version +#' @param newStudyVersion the new study version +#' @param projectPath the path to the project +#' @return invisible studyYml, prints specifying what changes happened +#' @export +updateStudyVersion <- function(newStudyVersion, + projectPath = here::here()) { + + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$version <- newStudyVersion + + pushStudyUpdate(studyYml, projectPath, update = "Study Version", value = newStudyVersion) + + #TODO add cascade to add line to NEWS + + invisible(studyYml) + +} + +#' Function to update study description +#' @param newStudyVersion the new study description +#' @param projectPath the path to the project +#' @return invisible studyYml, prints specifying what changes happened +#' @export +updateStudyDescription <- function(newStudyDescription, + projectPath = here::here()) { + + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$about$description <- newStudyDescription + + pushStudyUpdate(studyYml, projectPath, update = "Study Description", value = newStudyDescription) + + invisible(studyYml) + +} + + +#' Function to update study therapeutic area +#' @param newTA the new study therapeutic area +#' @param projectPath the path to the project +#' @return invisible studyYml, prints specifying what changes happened +#' @export +updateTherapeuticArea <- function(newTA, + projectPath = here::here()) { + + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$about$`therapeutic-area` <- newTA + + pushStudyUpdate(studyYml, projectPath, update = "Therapeutic Area", value = newTA) + + invisible(studyYml) + +} + + +#' Function to update developer Infor +#' @param newName change the developer name +#' @param newEmail change the developer email +#' @return invisible studyYml, prints specifying what changes happened +#' @export +updateDeveloperInfo <- function(newName, + newEmail, + projectPath = here::here()) { + + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$authors$developer$name <- newName + studyYml$study$authors$developer$email <- newEmail + + + memberText <- glue::glue("name: {newName}, email: {newEmail}") %>% + paste(collapse = ", ") + + pushStudyUpdate(studyYml, projectPath, update = "Developer", value = memberText) + + invisible(studyYml) + +} + + +#' Function to update lead Infor +#' @param newName change the lead name +#' @param newEmail change the lead email +#' @return invisible studyYml, prints specifying what changes happened +#' @export +updateLeadInfo <- function(newName, + newEmail, + projectPath = here::here()) { + + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$authors$lead$name <- newName + studyYml$study$authors$lead$email <- newEmail + + + memberText <- glue::glue("name: {newName}, email: {newEmail}") %>% + paste(collapse = ", ") + + pushStudyUpdate(studyYml, projectPath, update = "Lead", value = memberText) + + invisible(studyYml) + +} + + +# Add to study settings Options ----------------------- +#' Function to add a study member +#' @param name the name of the study member +#' @param email the study member's email +#' @param projectPath the path to the project +#' @return invisible studyYml, prints specifying what changes happened +#' @export +addStudyMember <- function(name, email = NULL, + projectPath = here::here()) { + + + if (is.null(email)) { + email <- "author@email.com" + } + + + studyMember <- list( + 'member' = list( + name = name, + email = email + ) + ) + + + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$authors <- append(studyYml$study$authors, studyMember) + + memberText <- glue::glue("{names(studyMember[[1]])}: {studyMember[[1]]}") %>% + paste(collapse = ", ") + + pushStudyAdd(studyYml, projectPath, update = "Study Author", value = memberText) + invisible(studyYml) +} + +#' Function to add study tags +#' @param ... a list of study tags to add +#' @param projectPath the path to the project +#' @return invisible studyYml, prints specifying what changes happened +#' @export +addTags <- function(..., projectPath = here::here()) { + + tags <- list(...) + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$tags <- append(studyYml$study$tags, tags) + + tagsText <- paste(tags, collapse = ", ") + + pushStudyAdd(studyYml, projectPath, update = "Study Tags", value = tagsText) + invisible(studyYml) +} + +#' Function to add study data sources +#' @param ... a list of data sources to add +#' @param projectPath the path to the project +#' @return invisible studyYml, prints specifying what changes happened +#' @export +addDataSources <- function(..., projectPath = here::here()) { + + dataSources <- list(...) + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$about$`data-sources` <- append(studyYml$study$about$`data-sources`, dataSources) + + sdText <- paste(dataSources, collapse = ", ") + + pushStudyAdd(studyYml, projectPath, update = "Data Sources", value = sdText) + invisible(studyYml) +} + +#' Function to add study links +#' @param ... a list of links to add +#' @param projectPath the path to the project +#' @return invisible studyYml, prints specifying what changes happened +#' @export +addLinks <- function(..., projectPath = here::here()) { + + links <- rlang::list2(...) + studyYml <- retrieveStudySettings(projectPath = projectPath) + studyYml$study$links <- append(studyYml$study$links, links) + + linkText <- glue::glue("{names(links)}: {links}") %>% + paste(collapse = ", ") + + pushStudyAdd(studyYml, projectPath, update = "Links", value = linkText) + invisible(studyYml) +} diff --git a/R/website.R b/R/website.R index 974d568..a084969 100644 --- a/R/website.R +++ b/R/website.R @@ -2,7 +2,7 @@ checkWebsiteYml <- function(projectPath = here::here()) { #create yml path - ymlPath <- fs::path(projectPath, "documentation/_quarto.yml") + ymlPath <- fs::path(projectPath, "documentation/hub/_quarto.yml") check <- fs::file_exists(ymlPath) if (check) { cli::cat_bullet("_quarto.yml already exists for study hub", bullet = "pointer", bullet_col = "yellow") @@ -13,14 +13,35 @@ checkWebsiteYml <- function(projectPath = here::here()) { # Function to create quarto yml -makeWebsiteYaml <- function(projectPath = here::here()) { +makeWebsiteYaml <- function(footer = NULL, + logoPath = NULL, + backgroundColor = "#336B91", #OHDSI Blue + projectPath = here::here()) { # retrieve study meta - studyMeta <- retrieveStudySettings(projectPath = projectPath) + studyMeta <- retrieveStudySettings(projectPath = projectPath)$study + + if (is.null(footer)) { + footer <- "Produced using Ulysses Package" + } + + if (is.null(logoPath)) { + + logoPath <- fs::path_package("Ulysses", "images") + + importImages(imageFolder = logoPath, projectPath = here::here()) + + logo <- "images/ohdsi_logo.png" + + } + # make list of vars for template data <- rlang::list2( - 'Study' = studyMeta$Title + 'Title' = replaceTitleColon(studyMeta$title), + 'Footer' = footer, + 'Color' = backgroundColor, + 'Logo' = logo ) check <- checkWebsiteYml(projectPath = projectPath) @@ -28,7 +49,7 @@ makeWebsiteYaml <- function(projectPath = here::here()) { #build template usethis::use_template( template = "quartoWebsite.yml", - save_as = fs::path("documentation", "_quarto.yml"), + save_as = fs::path("documentation/hub", "_quarto.yml"), data = data, open = FALSE, package = "Ulysses") @@ -54,14 +75,14 @@ makeIndexQuarto <- function(projectPath = here::here()) { newReadMe <- lines[keepLines] #set path to documentation - docPath <- fs::path(projectPath, "documentation/index.qmd") + docPath <- fs::path(projectPath, "documentation/hub/index.qmd") #write new readme to index.qmd cli::cat_bullet("Convert README.md to index.qmd", bullet = "tick", bullet_col = "green") readr::write_lines(newReadMe, file = docPath) #ignore index.qmd as it is redundant to README.md - usethis::use_git_ignore(ignores = "documentation/index.qmd") + usethis::use_git_ignore(ignores = "documentation/hub/index.qmd") invisible(docPath) } @@ -74,14 +95,14 @@ makeNewsQuarto <- function(projectPath = here::here()) { lines <- readr::read_lines(readMePath) #set path to documentation - docPath <- fs::path(projectPath, "documentation/news.qmd") + docPath <- fs::path(projectPath, "documentation/hub/news.qmd") #write new readme to index.qmd cli::cat_bullet("Convert NEWS to news.qmd", bullet = "tick", bullet_col = "green") readr::write_lines(lines, file = docPath) #ignore index.qmd as it is redundant to README.md - usethis::use_git_ignore(ignores = "documentation/news.qmd") + usethis::use_git_ignore(ignores = "documentation/hub/news.qmd") invisible(docPath) } @@ -89,15 +110,14 @@ makeNewsQuarto <- function(projectPath = here::here()) { missingStandardDocs <- function(projectPath = here::here()) { # make path to documentation folder - docsPath <- fs::path(projectPath, "documentation") + docsPath <- fs::path(projectPath, "documentation/hub") # look up all qmd files resourceFiles <- fs::dir_ls(docsPath, glob = "*.qmd") %>% basename() %>% tools::file_path_sans_ext() - expectedFiles <- c("AnalysisPlan", "ContributionGuidelines", "HowToRun", - "ResultsReport", "TechSpecs") + expectedFiles <- c("AnalysisPlan", "ResultsReport") `%notin%` <- Negate("%in%") @@ -124,7 +144,7 @@ makeMissingDocs <- function(missingDocs, projectPath = here::here()) { previewStudyHub <- function(projectPath = here::here()) { # make index path and check that it exists - indexFilePath <- fs::path(projectPath, "documentation/_site/index.html") + indexFilePath <- fs::path(projectPath, "documentation/hub/_site/index.html") check <- fs::file_exists(indexFilePath) if (check ) { @@ -142,12 +162,25 @@ previewStudyHub <- function(projectPath = here::here()) { #' Function to build study hub #' @param projectPath path to ohdsi study +#' @param logoPath a path to a logo png to use in the quarto website, defaults to +#' ohdsi logo from Ulysses inst. +#' @param footer add a footer to the study Hub +#' @param backgroundColor change background color, defaults to OHDSI blue #336B91 #' @return builds a _site folder in documenation that holds the html website #' @export -buildStudyHub <- function(projectPath = here::here()) { +buildStudyHub <- function(projectPath = here::here(), + logoPath = NULL, + footer = NULL, + backgroundColor = "#336B91" #OHDSI Blue + ) { # Step 1: Make yml - makeWebsiteYaml(projectPath = projectPath) + makeWebsiteYaml( + footer = footer, + logoPath = logoPath, + backgroundColor = backgroundColor, + projectPath = projectPath + ) # step 2: check standard files for website missingDocs <- missingStandardDocs(projectPath = projectPath) @@ -162,7 +195,7 @@ buildStudyHub <- function(projectPath = here::here()) { makeNewsQuarto(projectPath = projectPath) # make doc path - docsPath <- fs::path(projectPath, "documentation") + docsPath <- fs::path(projectPath, "documentation/hub") # step 6: build study hub cli::cat_bullet("Build Study Hub", bullet = "tick", bullet_col = "green") @@ -175,3 +208,22 @@ buildStudyHub <- function(projectPath = here::here()) { invisible(docsPath) } + +#' Function to import a folder of images for a study hub +#' @param imageFolder the file path for an image folder +#' @param projectPath path to ohdsi study +#' @return invisible return of the image file folder +#' @export +importImages <- function(imageFolder, projectPath = here::here()) { + + newImageFolder <- fs::path(projectPath, "documentation/hub/images") %>% + fs::dir_create() + + + imageFiles <- fs::dir_copy( + path = imageFolder, + new_path = newImageFolder + ) + + invisible(imageFiles) +} diff --git a/README.md b/README.md index 3ce23be..ae16fa2 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Requires R (version 4.1 or higher) install.packages("remotes") remotes::install_github("ohdsi/Ulysses") ``` - +3. Install [quarto](https://quarto.org/docs/get-started/index.html) # User Documentation @@ -36,7 +36,6 @@ Documentation can be found on the [package website](https://ohdsi.github.io/Ulys PDF versions of the documentation are available: - Vignette: [Ulysses Intro](https://raw.githubusercontent.com/OHDSI/Ulysses/main/extras/pdf_vignette/start_study.pdf) -- Vignette: [Ulysses Directory](https://raw.githubusercontent.com/OHDSI/Ulysses/main/extras/pdf_vignette/ulysses_directory.pdf) - [Package manual](https://raw.githubusercontent.com/OHDSI/Ulysses/main/extras/Ulysses.pdf) # Support diff --git a/docs/404.html b/docs/404.html index 82c535a..b3f206d 100644 --- a/docs/404.html +++ b/docs/404.html @@ -39,7 +39,7 @@
@@ -58,9 +58,6 @@To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets []
replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
-2.0 (the "License");
- Licensed under the Apache License, Version in compliance with the License.
- you may not use this file except
- You may obtain a copy of the License at
-://www.apache.org/licenses/LICENSE-2.0
- http
-in writing, software
- Unless required by applicable law or agreed to "AS IS" BASIS,
- distributed under the License is distributed on an
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.for the specific language governing permissions and
- See the License limitations under the License.
Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
-Ulysses::newOhdsiStudy(
+newOhdsiStudy(
path = here::here("my_ohdsi_study"),
- author = "Ulysses S. Grant",
- type = "Characterization",
- directory = "[my_directory]",
- open = TRUE
+ studyInfo = setStudyInfo(id = basename(here::here("my_ohdsi_study")),
+ title = "My OHDSI Study"),
+ authors = setStudyAuthors(
+ developer = "John Smith",
+ developerEmail = "john.smith@ohdsi.org"
+ ),
+ about = setStudyDescription(
+ desc = "This is an OHDSI study for characterizing a population. This is an example.",
+ ta = "Cardiovascular",
+ dataSources = list("Synthea", "Synpuf")
+ ),
+ tags = setStudyTags("OHDSI", "OMOP")
)
This function will print some information to your console about start-up tasks and open an R project in a new session, for details on Rstudio projects see link.
-In the new R session, we are directed to a clean R studio session. In -the files pane you will see a directory structure as depicted in the -image below. For more details about the directory structure refer to the -Introduction to Ulysses Directory vignette in this package. -Congratulations! You have started an OHDSI study!
-The additional inputs of the newOhdsiStudy
function
+build meta data for the study repository that will be stored in a
+_study.yml
file. This meta data serves two purposes: 1)
+provides human-readable information about the study and 2) serves as a
+source of information to populate fields for templated files generated
+using Ulysses
. For example, if we were to generate a
+README
file using Ulysses
it would be built
+using this meta information.
With your new OHDSI study created, you need to begin adding
-documentation for the repository. The first file we usually create is
-the repository README. For those unfamiliar with code development, the
-README file is a standard file used to introduce a describe the the
-project. Think of the README as your cover page. It is the first file
-users see when they navigate to the github page. All OHDSI projects
-require a README file, thus Ulysses
provides a function
-(makeReadMe
) that initializes it.
-Ulysses::makeReadMe()
The readme file is initailized using information found in the
-_study.yml
file. A typical OHDSI study readme has a section
-of meta information as seen below:
In a new R session, users will notice a pre-populated directory +structure in their project folder. This directory structure contains +specific folders and files that are important for a study to be +self-contained within the new R project.
+Ulysses
builds the following folders:
analysis
+The analysis folder contains files that correspond to study analysis. +There are three main folders created.
src
- contains the underlying functions that execute
+the analysis. These files can be R scripts, sql files or python scripts,
+for example. With Ulysses
, users can generate templated
+internal R files using the command makeInternals
.
tasks
- hold the executing scripts that generate the
+results of the study. With Ulysses
, we think of studies as
+a series of tasks implemented in a specific order, like a pipeline. The
+tasks
folder organizes these individual tasks. With
+Ulysses
, users can generate templated internal R files
+using the command makeAnalysisScript
.
migrations
- contain post-processing scripts to move
+and prepare data from a series of results to a format that is
+“presentation ready”. When conducting studies in OMOP, it is common to
+run the same analysis on different databases. Migration scripts help
+bind the results of all databases run in the study and format tables to
+present in a quarto report or shiny app. With Ulysses
,
+users can generate templated internal R files using the command
+makeMigrationScript
.
+cohorts
+The cohorts folder is meant to organize files that are used to
+generate cohort definitions in the database. In an OHDSI study, cohort
+definitions are specified in a json
file format following
+the specifications of circe-be
. We
+suggest placing cohorts used in the analysis in the cohort folder in
+order for the study to be self-contained, meaning it does not rely on
+ATLAS to execute. However, we highly recommend that
+users maintain the organization of their cohorts in ATLAS as a source of
+truth for both cohort definition and generation. The sql
+folder is created to store sql files used to build cohort definitions.
+This is a good location for cohort definitions that do not follow the
+circe-be
structure.
Keeping track of cohorts can be a bit tricky. Ulysses
+provides a helper function to track json files in the cohorts folder
+called cohortManifest
. This function will list the name of
+the json file and its corresponding id. By default, the cohort Id
+assigned to the cohort json is in alphabetical order starting with 1.
+Ulysses
also creates a file called the
+CohortDetails.qmd
which prints the human-readable rendering
+of the json expression using CirceR
.
+These functions are still in development as of
+v0.0.4.
documentation
+Study repositories should not only contain code, they should also
+contain documentation about the design of the study and how to run the
+study. Study repo’s should be self-contained, meaning we can go to one
+location to get all code and human-readable documentation about the
+study. Ulysses
builds this into its repository structure
+with a hub
folder and a misc
folder. The
+hub
folder contains files that are specific to the study
+hub, an html website that provides all information about the study. The
+misc
folder is a place-holder to store word documents,
+excel files, slide decks or other important documentation needed for the
+study.
The study hub is a website that a user can generate through
+Ulysses
that provides information about the design of a
+study and its results. The study hub is generated using
+quarto
. The study hub can be generated using the function
+buildStudyHub
. The study hub relies on the generation and
+maintenance of 4 files: README.md, NEWS.md, AnalysisPlan.qmd and
+ResultsReport.qmd.
Ulysses
has functions to initialize some suggested files
+for a study:
AnalysisPlan.qmd
: the statistical analysis plan for the
+study, which specifies the study design and analytical methods. This
+file can be templated in Ulysses
using the command
+makeAnalysisPlan
.
ResultsReport.qmd
: the report summarizing results from
+the study following its execution. This file can be templated in
+Ulysses
using the command
+makeResultsReport
.
ContributionGuidelines.qmd
: if the study is a network
+studies, maintainers should provide resources on how others can
+contribute to the study. Topics ranges from how to file issues, how to
+send results to the study host, and how to collaborate in a positive
+environment. This file can be templated in Ulysses
using
+the command makeContributionGuidelines
.
HowToRun.qmd
: a document that explains how to execute
+the study code to study nodes or interested parties. Should describe
+technical requirements needed prior to running the study, local setup,
+and execution. This file can be templated in Ulysses
using
+the command makeHowToRun
.
Following the Meta section, the user will need to provide a
-description of the study and information on the databases used in the
-study. Finally, the README provides links to important study information
-including the protocol, how to run and contributions files. Users can
-add as much as they please to the README file, Ulysses
-offers suggested guidance for starting it.
exec
+The exec
folder is a location to store output files that
+result from the study execution. This includes results and logs from the
+study run and a folder to store post-processed data called
+export
. The exec
folder is always ignored in
+git.
extras
+Sometimes studies have files that don’t have a natural location from
+those specified above. The extras
folder is a location to
+store any additional files needed to run or support the execution of the
+study. This is also a good location to store internal setup scripts, but
+remember to ignore them in git.
In addition to the pre-generated folders in the new study repository,
+Ulysses
also helps generate additional files that should be
+in the repository. Some of these key files are described below.
_study.yml
+A file unique to directories initialized using Ulysses
+is a metadata file called _study.yml
. Using the inputs
+specified in the newOhdsiStudy
function, a metadata file is
+populated. As mentioned this file store information about the study
+directory and also uses it as inputs to templated files generated in
+Ulysses
. It is important to maintain this file during the
+development of a study, whether that is to update default fields in the
+yaml file or add information. Below is a snapshot of a
+_study.yml
file with the essential metadata fields.
Below we describe the key fields in this file.
+Ulysses
provides functions to maintain the
+_study.yml
file.
updateStudyEndDate()
updateSutdyStatus()
updateStudyTitle()
updatStudyVersion()
updateStudyDescription()
updateTherapeuticArea()
updateDeveloperInfo()
updateLeadInfo()
README.md
+For those unfamiliar with code development, the
+README file is a standard file used to introduce the
+contents of a repository, like a cover-page. It is the first file users
+see when they navigate to the repository page in your repository hosting
+service (i.e. BitBucket or Github). Therefore a strong README file is
+essential for a study. Ulysses
provides the function
+makeReadMe()
which initializes the README using inputs from
+the metadata stored in the _study.yml
.
Another feature offered by Ulysses
is support for svg
badges. These simple badges appear at the top of the README and provide
useful information about the study. Badges seen in OHDSI studies include
@@ -215,9 +422,10 @@
NEWS.md
+Another common file in software repositories is the NEWS file. The purpose of the NEWS file is to track changes to the software over time. Of course, version control software such as github keeps a record of the @@ -227,19 +435,18 @@
-Ulysses::makeNews()
makeNews()
.
config.yml
+An important aspect of running an OHDSI study is handling credentials
to connect to the Database Management System (DBMS) that hosts the OMOP
data. Security of these credentials is very important.
-Ulysses
offers support on handling these credentials.
-Credentials needed to run a study are as follows:
Ulysses
offers support on handling these credentials
+through the config.yml
file. Credentials needed to run a
+study are as follows:
-Ulysses::makeConfig(block = "example", database = "synpuf_110k")
+Ulysses::makeConfig(block = "example", database = "synpuf_110k")
When a user creates a new config.yml
file it is added to
.gitignore
to ensure it is not committed to a github
repository. The config file shows each credential connected to the block
@@ -329,98 +536,9 @@
+Ulysses::makeKeyringSetup(configBlock = "example", database = "synpuf_110k")
One way we can add analytical scripts to Ulysses
is by
-using the line below
-Ulysses::makeAnalysisScript(scriptName = "buildCohorts")
This function will create a new R script written to the folder
-analysis/studyTasks
. The R script will have a prefix of a
-number indicating the order in which the script should be executed. The
-first script for example will follow the syntax
-01_Ulysses
will automatically
-open this file to begin editing.
Each analytical task is formatted with the following sections:
-To complement the analysis scripts, we can also create internal
-files. These are R files that contain functions or other code that needs
-to be sourced in the analysis. These files are saved in the
-analysis/private
folder. Making an internal function can be
-done by the following:
-Ulysses::makeInternals(internalsName = "buildCohorts")
The R package Strategus
-helps execute OHDSI analytics. Analytical modules are executed via
-Strategus
. This paradigm to OHDSI studies can also be
-handled by Ulysses
. More support for using
-Strategus
with Ulysses
will be explored in
-future releases.
An important part of a study repository is communicating its contents
-to study nodes. A study node in a network study must understand the
-scientific components of the study, how to run the study locally and how
-to contribute towards the study. Ulysses
provides functions
-to help develop documentation to communicate the study to participants
-in the OHDSI network.
A study requires a protocol or a study analysis plan (SAP),
-specifying the scientific components of the study. These documents
-specify the study design, definition of the target, exposure and outcome
-cohorts and how the data analysis is conducted. This documentation is
-important because it provides guidance and rationale for the study. Many
-study nodes also require submission of documentation to an institutional
-review board to justify execution of the study. Ulysses
-provides templates for an OHDSI protocol, PASS protocols and a suggested
-format for a SAP. Below are examples of building these templates:
-Ulysses::makeOhdsiProtocol()
-Ulysses::makePassProtocol()
-Ulysses::makeStudySAP()
Next, a repository needs to communicate how to run the study. This
-document informs study nodes on technical requirements needed to run the
-study, provides instructions on installations, and the process of
-running the study. OHDSI studies are designed in several different ways,
-so it is important that the developer explains how this study should be
-run. Below is an example of how to create the howToRun.md
-file:
-Ulysses::makeHowToRun(org = "Ohdsi", repo = "my_ohdsi_study")
Finally, the repository needs to communicate how study nodes can -contribute to the study. This include information on posting results, -asking for help and code of conduct. Contribution guidelines are -standard documentation of software and would be helpful additions to -OHDSI studies. To create a template contribution guideline follow the -example below:
-
-Ulysses::makeContributionGuidelines()
Lavallee M (2023). +
Lavallee M (2024). Ulysses: Automate OHDSI Study Setup. -R package version 0.0.2. +R package version 0.0.4.
@Manual{, title = {Ulysses: Automate OHDSI Study Setup}, author = {Martin Lavallee}, - year = {2023}, - note = {R package version 0.0.2}, + year = {2024}, + note = {R package version 0.0.4}, }diff --git a/docs/index.html b/docs/index.html index 2123b1f..7c90b42 100644 --- a/docs/index.html +++ b/docs/index.html @@ -41,7 +41,7 @@ @@ -60,9 +60,6 @@
install.packages("remotes")
remotes::install_github("ohdsi/Ulysses")
+newOhdsiStudy()
with better meta inputsmakeMigrationsScript()
templatecohortManifest
lists cohorts used in studymakeCohortDetails
renders human-readable file to convey cohort definitionsaddDataSources.Rd
Function to add study data sources
+addDataSources(..., projectPath = here::here())
a list of data sources to add
the path to the project
invisible studyYml, prints specifying what changes happened
+addLinks.Rd
Function to add study links
+addLinks(..., projectPath = here::here())
a list of links to add
the path to the project
invisible studyYml, prints specifying what changes happened
+addStudyMember.Rd
Function to add a study member
+addStudyMember(name, email = NULL, projectPath = here::here())
the name of the study member
the study member's email
the path to the project
invisible studyYml, prints specifying what changes happened
+addTags.Rd
Function to add study tags
+addTags(..., projectPath = here::here())
a list of study tags to add
the path to the project
invisible studyYml, prints specifying what changes happened
+buildStudyHub.Rd
Function to build study hub
+buildStudyHub(
+ projectPath = here::here(),
+ logoPath = NULL,
+ footer = NULL,
+ backgroundColor = "#336B91"
+)
path to ohdsi study
a path to a logo png to use in the quarto website, defaults to +ohdsi logo from Ulysses inst.
add a footer to the study Hub
change background color, defaults to OHDSI blue #336B91
builds a _site folder in documenation that holds the html website
+cohortManifest.Rd
Function that lists all cohort definitions loaded into the study
+cohortManifest(projectPath = here::here())
the path to the project
tibble of the cohorts in the project
+importCredentialsToConfig.Rd
Function to import credentials in stored csv to study config.yml
+importCredentialsToConfig(credFile, projectPath = here::here(), open = TRUE)
a credential.csv file stored in a secure location
the path to the project
toggle on whether the file should be opened
importImages.Rd
Function to import a folder of images for a study hub
+importImages(imageFolder, projectPath = here::here())
the file path for an image folder
path to ohdsi study
invisible return of the image file folder
+Function to create a cohort folder in input/cohortsToCreate
Add a line to the config file
Function to add study data sources
Function to add study links
Function to add a study member
Function to create a scratch folder
Function to add study tags
Function to build study hub
checkDatabaseCredential()
Function to check the database credential
Function that lists all cohort definitions loaded into the study
Function to list default credentials
Function to import credentials in stored csv to study config.yml
Function to import a folder of images for a study hub
Function to create a config.yml file
Function to check if the directory is a picard project
Function to check if the directory is an ohdsi project
Function to create a SAP
Function to create a cohort details file
Function to create a config.yml file
Function to create the cohort details for the study
R Markdown file to make the contribution guidelines
Function to create an example OHDSI script
Function to create a Synopsis file
Function to create a HowToRun file
Function to create a config.yml file
Function to create a meeting minutes file
Function to create a migration script
Function to create a NEWS file
R Markdown file to make the ohdsi protocol
R Markdown file to make the pass protocol
makeResultsReport()
Quarto file to make a results report
Function to create a SAP
Function to create a pipeline task as an R file
Function to retrieve table of modules
Function that initializes a new ohdsi study project environment
Function to preview study hub
Publish Study to Repo
Email asking to initialize an ohdsi-studies repo
Function to convert yml into a specified list format
setMultipleCredentials()
Function to set multi credentials
Function to set study authors
Function to set study description
Function to set study info
Function to set study keyring
Function to set study links
Function to set study tags
Function to set study timeline
Function to update developer Infor
Function to update lead Infor
Function to update study description
Function to update study end date
Function to update study status
Function to update study title
Function to update study version
Function to update study therapeutic area
Funciton to compress results into a zip file
isOhdsiStudy.Rd
Function to check if the directory is a picard project
+Function to check if the directory is an ohdsi project
makeAnalysisPlan.Rd
Function to create a SAP
+makeAnalysisPlan(projectPath = here::here(), open = TRUE)
the path to the project
toggle on whether the file should be opened
makeAnalysisScript(
scriptName,
configBlock = NULL,
+ date = lubridate::today(),
projectPath = here::here(),
open = TRUE
)
the name of the config block to use for the script
the date the script was built, default to today's date
the path to the project
makeCaprScript(
scriptName,
configBlock = NULL,
+ date = lubridate::today(),
projectPath = here::here(),
open = TRUE
)
the name of the config block to use for the script
the date the script was built, default to today's date
the path to the project
makeCohortDetails.Rd
Function to create a cohort details file
+The cohort details file is a document that provides a human-readable version +of the circe cohort definitions used in the study. This function targets +the cohortsToCreate folder and makes a quarto of the cohort details.
toggle on whether the file should be opened
writes a CohortDetails.qmd file to the documentation folder
+makeHowToRun.Rd
Function to create a Synopsis file
+Function to create a HowToRun file
makeHowToRun(org = NULL, repo = NULL, projectPath = here::here(), open = TRUE)
makeHowToRun(projectPath = here::here(), open = TRUE)
the name of the organization hosting the repo, for example 'ohdsi-studies'. -If null defaults to a dummy text
the name of the study repository on github, defaults to the study title
the path to the project
makeInternals(internalsName, projectPath = here::here(), open = TRUE)
The name of the internals file that is being created
the date the script was built, default to today's date
the path to the project
makeMigrationScript.Rd
Function to create a migration script
+The name of the analysis script
the date the script was built, default to today's date
the path to the project
toggle on whether the file should be opened
moduleTable.Rd
Function to retrieve table of modules
+moduleTable(projectPath = here::here())
the path to the project
newOhdsiStudy(
path,
projectName = basename(path),
- author,
- type,
+ studyInfo = setStudyInfo(id = basename(path)),
+ authors = setStudyAuthors(),
+ timeline = setStudyTimeline(),
+ about = setStudyDescription(),
+ links = setStudyLinks(),
+ tags = setStudyTags(),
verbose = TRUE,
openProject = TRUE
)
the name of the project
the name of the study lead
a list object identifying the title, type and study version,
+defaults to setStudyInfo
, see documentation
a list object identifying the lead and developer authors names and emails,
+defaults to setStudyAuthors
, see documentation.
a list object identifying the study status, start and end date,
+defaults to setStudyTimeline
, see documentation
a list object identifying the study description, therapeutic area and databases,
+defaults to setStudyDescription
, see documentation
a list object identifying the linked resources of the study,
+defaults to setStudyLinks
, see documentation
the type of study either Characterization, PLP or PLE
a list object identifying tags to the study,
+defauls to setStudyTags
, see documentation
previewStudyHub.Rd
Function to preview study hub
+previewStudyHub(projectPath = here::here())
path to ohdsi study
previews study hub in browser
+retrieveStudySettings.Rd
Function to convert yml into a specified list format
+retrieveStudySettings(projectPath)
the path to the project
the study yml as an R object (list)
+setStudyAuthors.Rd
Function to set study authors
+setStudyAuthors(
+ developer = Sys.getenv("USERNAME"),
+ developerEmail = glue::glue("{developer}@ohdsi.org"),
+ lead = "Ulysses",
+ leadEmail = "Ulysses@ohdsi.org"
+)
specify the study developer, default to system variable
the email of the developer
specify the lead of the study
specify the lead of the study email
a list containing study authors
+setStudyDescription.Rd
Function to set study description
+setStudyDescription(
+ desc = "Provide a 1 to 2 sentence description of your study. Be concise.",
+ ta = "Specify the therapeutic area of the study",
+ dataSources = list("Truven MarketScan", "Optum Market Clarity")
+)
a brief description of the study
a character string of the therapeutic area
a list of data sources
a list containing study description info
+setStudyInfo.Rd
Function to set study info
+setStudyInfo(
+ id,
+ title = id,
+ type = c("Characterization"),
+ version = "0.0.0.999"
+)
specify the study id
specify the study title
specify the type of study
specify the study version
a list containing study info
+setStudyLinks.Rd
Function to set study links
+setStudyLinks(...)
a series of resource links for the study
a list containing links to resources
+setStudyTags.Rd
Function to set study tags
+setStudyTags(...)
a series of tags for the study
a list containing study tags
+setStudyTimeline.Rd
Function to set study timeline
+setStudyTimeline(
+ status = "Started",
+ startDate = as.character(lubridate::today()),
+ endDate = as.character(lubridate::today() + (365 * 2))
+)
the study status, default is started
the start of the study, defaults to todays date
the date specifying the end (or expected end) of the study
a list containing study timeline
+updateDeveloperInfo.Rd
Function to update developer Infor
+updateDeveloperInfo(newName, newEmail, projectPath = here::here())
change the developer name
change the developer email
invisible studyYml, prints specifying what changes happened
+updateLeadInfo.Rd
Function to update lead Infor
+updateLeadInfo(newName, newEmail, projectPath = here::here())
change the lead name
change the lead email
invisible studyYml, prints specifying what changes happened
+updateStudyDescription.Rd
Function to update study description
+updateStudyDescription(newStudyDescription, projectPath = here::here())
the path to the project
the new study description
invisible studyYml, prints specifying what changes happened
+updateStudyEndDate.Rd
Function to update study end date
+updateStudyEndDate(newEndDate, projectPath = here::here())
the new end date of the study, suggest format YYYY-MM-DD
the path to the project
invisible studyYml, prints specifying what changes happened
+updateStudyStatus.Rd
Function to update study status
+the new status of the study, accepts Started, In-Progress, Stopped, Completed
the path to the project
invisible studyYml, prints specifying what changes happened
+updateStudyTitle.Rd
Function to update study title
+updateStudyTitle(newStudyTitle, projectPath = here::here())
the new study title
the path to the project
invisible studyYml, prints specifying what changes happened
+updateStudyVersion.Rd
Function to update study version
+updateStudyVersion(newStudyVersion, projectPath = here::here())
the new study version
the path to the project
invisible studyYml, prints specifying what changes happened
+updateTherapeuticArea.Rd
Function to update study therapeutic area
+updateTherapeuticArea(newTA, projectPath = here::here())
the new study therapeutic area
the path to the project
invisible studyYml, prints specifying what changes happened
+zipResults.Rd
Funciton to compress results into a zip file
+zipResults(databaseName, projectPath = here::here())
the name of the database folder to compress
the path to the project