diff --git a/.Rbuildignore b/.Rbuildignore index ab2f169e..893b8fef 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -14,3 +14,4 @@ ^CRAN-RELEASE$ ^customSettings$ ^\.github$ +^LICENSE\.md$ diff --git a/DESCRIPTION b/DESCRIPTION index 934c89c8..d15e10ff 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,13 +2,12 @@ Package: safetyGraphics Title: Create Interactive Graphics Related to Clinical Trial Safety Version: 2.0.0 Authors@R: c( - person("Jeremy", "Wildfire", email = "jeremy_wildfire@rhoworld.com", role = c("cre","aut")), + person("Jeremy", "Wildfire", email = "jwildfire@gmail.com", role = c("cre","aut")), person("Becca", "Krouse", role="aut"), person("Preston","Burns", role="aut"), person("Xiao","Ni", role = "aut"), person("James","Buchanan", role="aut"), - person("Susan","Duke", role="aut"), - person("Interactive Safety Graphics Working Group", role = "aut")) + person("Susan","Duke", role="aut")) Maintainer: Jeremy Wildfire Description: A framework for evaluation of clinical trial safety. Users can interactively explore their data using the 'Shiny' application or create standalone 'htmlwidget' charts. Interactive charts are built using 'd3.js' and 'webcharts.js' 'JavaScript' libraries. URL: https://github.com/SafetyGraphics/safetyGraphics diff --git a/LICENSE b/LICENSE index f7b8a19e..f02ff01c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,2 +1,2 @@ -YEAR: 2018 -COPYRIGHT HOLDER: Rho Inc. +YEAR: 2021 +COPYRIGHT HOLDER: safetyGraphics authors diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..db5cbda1 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2021 safetyGraphics authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/NAMESPACE b/NAMESPACE index 432ddc30..ba3befaa 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -84,5 +84,3 @@ importFrom(stringr,str_to_upper) importFrom(utils,hasName) importFrom(utils,zip) importFrom(yaml,as.yaml) -importFrom(yaml,write_yaml) - diff --git a/R/meta.R b/R/meta.R index 503e52a4..8df6856a 100644 --- a/R/meta.R +++ b/R/meta.R @@ -1,5 +1,3 @@ -#' meta -#' #' Metadata data frame containing information about the data mapping used to configure safetyGraphics charts. One record per unique data mapping #' #' @format A data frame with 31 rows and 7 columns diff --git a/R/mod_chartsNav.R b/R/mod_chartsNav.R index 6a5762bb..6904a81e 100644 --- a/R/mod_chartsNav.R +++ b/R/mod_chartsNav.R @@ -1,4 +1,4 @@ -#' Add a navbar tab that initializes the Chart Module UI +#' Adds a navbar tab that initializes the Chart Module UI #' #' @param chart chart metadata #' @param ns namespace diff --git a/R/mod_chartsTab.R b/R/mod_chartsTab.R index 8883b315..7b274b5f 100644 --- a/R/mod_chartsTab.R +++ b/R/mod_chartsTab.R @@ -1,8 +1,7 @@ -#' @title Charts Tab -#' @description Charting module +#' @title UI for chart module, designed to be re-used for each chart generated. #' #' @param id module id -#' @param chart list containing chart specifications +#' @param chart list containing chart specifications like those returned by \link{makeChartConfig}. #' #' @importFrom stringr str_to_title #' @importFrom purrr map2 @@ -17,13 +16,12 @@ chartsTabUI <- function(id, chart){ return(list(header, chartWrap)) } -#' @title home tab - server -#' @description server for the display of the chart tab +#' @title Server for chart module, designed to be re-used for each chart generated. #' #' @param input Input objects from module namespace #' @param output Output objects from module namespace #' @param session An environment that can be used to access information and functionality relating to the session -#' @param chart list containing a safetyGraphics chart object. see custom chart vignette for details. +#' @param chart list containing a safetyGraphics chart object like those returned by \link{makeChartConfig}. #' @param data named list of current data sets (Reactive). #' @param mapping tibble capturing the current data mappings (Reactive). #' diff --git a/R/mod_filterTab.R b/R/mod_filterTab.R index dfd8cf43..aa31ad70 100644 --- a/R/mod_filterTab.R +++ b/R/mod_filterTab.R @@ -1,5 +1,4 @@ -#' @title filterTabUI -#' @description UI that facilitates the filtering data with datamods::filter_data_ui +#' @title UI for the filter module in datamods::filter_data_ui #' #' @param id module id #' @@ -39,8 +38,7 @@ filterTabUI <- function(id){ } -#' @title filter module server -#' @description server function that facilitates the data filtering with the datamods::filter_data_server module +#' @title Server for the filter module in datamods::filter_data_ui #' #' @param input Shiny input object #' @param output Shiny output object diff --git a/R/mod_filterTabChecks.R b/R/mod_filterTabChecks.R index 9da0dea3..5d93abbc 100644 --- a/R/mod_filterTabChecks.R +++ b/R/mod_filterTabChecks.R @@ -1,5 +1,4 @@ -#' @title filter module checks -#' @description function that checks whether the current data and settings are appropriate for the filter tab +#' @title Checks for whether the current data and settings support a filter tab #' #' @param domainData list of data files for each domain #' @param filterDomain domain to use for filtering (typically "dm") diff --git a/R/mod_homeTab.R b/R/mod_homeTab.R index edcdb9fa..cea29776 100644 --- a/R/mod_homeTab.R +++ b/R/mod_homeTab.R @@ -1,5 +1,4 @@ -#' @title Home Tab -#' @description Home Tab - sub-module showing details for the data loaded in the app - UI +#' @title UI for the home module #' #' @param id module id #' @@ -13,8 +12,7 @@ homeTabUI <- function(id){ ) } -#' @title home tab - server -#' @description server for the display of the home tab +#' @title Server for the filter module in datamods::filter_data_ui #' #' @param input mod input #' @param output mod output diff --git a/R/mod_loadCharts.R b/R/mod_loadCharts.R index 7de657c5..858095a0 100644 --- a/R/mod_loadCharts.R +++ b/R/mod_loadCharts.R @@ -1,8 +1,7 @@ -#' @title loadChartsUI -#' @description UI that helps users pick charts +#' @title UI for the chart loading module used in safetyGraphicsInit() #' #' @param id module id -#' @param charts list of charts +#' @param charts list containing chart specifications like those returned by \link{makeChartConfig}. #' #' @importFrom purrr keep #' @importFrom sortable bucket_list add_rank_list @@ -21,15 +20,15 @@ loadChartsUI <- function(id, charts=makeChartConfig()){ ) } -#' @title loadCharts -#' @description server that facilitates selection of charts for safetyGraphicsApp +#' @title Server for the chart loading module used in safetyGraphicsInit() #' #' @param input Shiny input object #' @param output Shiny output object #' @param session Shiny session object -#' @param charts Initial list of charts - +#' @param charts list containing chart specifications like those returned by \link{makeChartConfig}. +#' #' @export + loadCharts <- function(input, output, session, charts=makeChartConfig()) { ns<-session$ns labels<-charts%>%map(~makeChartSummary(.x,showLinks=FALSE,class="chart-sortable")) diff --git a/R/mod_loadData.R b/R/mod_loadData.R index 8f76429e..9673952e 100644 --- a/R/mod_loadData.R +++ b/R/mod_loadData.R @@ -1,5 +1,4 @@ -#' @title loadDataUI -#' @description UI that facilitates the mapping of a column data domain +#' @title UI for the data loading module used in safetyGraphicsInit() #' #' @param id module id #' @param domain character vector with domains to be loaded @@ -19,8 +18,7 @@ loadDataUI <- function(id, domain=NULL){ ) } -#' @title loadDataServer -#' @description UI that facilitates the mapping of a column data domain +#' @title Server for the data loading module used in safetyGraphicsInit() #' #' @param domain data domain to be loaded #' @param input Shiny input object diff --git a/R/mod_mappingColumn.R b/R/mod_mappingColumn.R index a991d446..a08d2f29 100644 --- a/R/mod_mappingColumn.R +++ b/R/mod_mappingColumn.R @@ -1,5 +1,4 @@ -#' @title mappingColumnUI -#' @description UI that facilitates the mapping of a column data domain +#' @title UI that facilitates the mapping of a column data (and any associated fields) #' #' @param id module id #' @param meta metadata for the column (and related fields) @@ -66,8 +65,7 @@ mappingColumnUI <- function(id, meta, data, mapping=NULL){ col_ui } -#' @title mappingColumn -#' @description server function that facilitates the mapping of a single data element (column of field) with a simple select UI +#' @title Server that facilitates the mapping of a column data (and any associated fields) #' #' @param input Shiny input object #' @param output Shiny output object diff --git a/R/mod_mappingDomain.R b/R/mod_mappingDomain.R index be814e27..38871694 100644 --- a/R/mod_mappingDomain.R +++ b/R/mod_mappingDomain.R @@ -1,5 +1,4 @@ -#' @title mappingDomainUI -#' @description UI that facilitates the mapping of a full data domain +#' @title UI that facilitates the mapping of a full data domain #' #' @param id module id #' @param meta metadata for the domain @@ -37,8 +36,7 @@ mappingDomainUI <- function(id, meta, data, mapping=NULL){ } -#' @title mappingDomain -#' @description server function that facilitates the mapping of a single data domain +#' @title Server that facilitates the mapping of a full data domain #' #' @param input Shiny input object #' @param output Shiny output object diff --git a/R/mod_mappingSelect.R b/R/mod_mappingSelect.R index 43c3d7ba..38eb1ef4 100644 --- a/R/mod_mappingSelect.R +++ b/R/mod_mappingSelect.R @@ -1,7 +1,5 @@ -#' Mapping Select UI +#' @title UI that facilitates the mapping of a single data element (column or field) with a simple select UI #' -#' UI that facilitates the mapping of a single data element (column or field) with a simple select UI -#' #' @param id unique id for the UI #' @param label label associated with the control #' @param choices a list of options for the control @@ -33,8 +31,7 @@ mappingSelectUI <- function(id, label, choices=NULL, default=NULL){ ) } -#' @title mappingSelect -#' @description server function that facilitates the mapping of a single data element (column of field) with a simple select UI +#' @title Server that facilitates the mapping of a single data element (column or field) with a simple select UI #' #' @param input Shiny input object #' @param output Shiny output object diff --git a/R/mod_mappingTab.R b/R/mod_mappingTab.R index 21e7bc35..d41bdf52 100644 --- a/R/mod_mappingTab.R +++ b/R/mod_mappingTab.R @@ -1,5 +1,4 @@ -#' @title mappingTabUI -#' @description UI that facilitates the mapping of all data domain +#' @title UI for mapping tab covering of all data domains #' #' @param id module id #' @param meta metadata for all domains @@ -68,8 +67,7 @@ mappingTabUI <- function(id, meta, domainData, mappings=NULL, standards=NULL){ } -#' @title mapping module server -#' @description server function that facilitates the mapping of a single data domain +#' @title Server for mapping tab covering of all data domains #' #' @param input Shiny input object #' @param output Shiny output object diff --git a/R/mod_safetyGraphicsServer.R b/R/mod_safetyGraphicsServer.R index cfa78086..89126bde 100644 --- a/R/mod_safetyGraphicsServer.R +++ b/R/mod_safetyGraphicsServer.R @@ -1,4 +1,4 @@ -#' Server for the default safetyGraphics shiny app +#' Server for core safetyGraphics app including Home, Mapping, Filter, Charts and Settings modules. #' #' This function returns a server function suitable for use in shiny::runApp() #' diff --git a/R/mod_safetyGraphicsUI.R b/R/mod_safetyGraphicsUI.R index 62be772a..db044db5 100644 --- a/R/mod_safetyGraphicsUI.R +++ b/R/mod_safetyGraphicsUI.R @@ -1,4 +1,5 @@ -#' UI for the default safetyGraphics shiny app +#' UI for the core safetyGraphics app including Home, Mapping, Filter, Charts and Settings modules. +#' #' #' @param id module ID #' @param meta data frame containing the metadata for use in the app. See the preloaded file (\code{?safetyGraphics::meta}) for more data specifications and details. Defaults to \code{safetyGraphics::meta}. diff --git a/R/mod_settingsCharts.R b/R/mod_settingsCharts.R index 25ad6e32..2d69976d 100644 --- a/R/mod_settingsCharts.R +++ b/R/mod_settingsCharts.R @@ -1,5 +1,4 @@ -#' @title Settings Module - chart details -#' @description Settings Module - sub-module showing details for the charts loaded in the app - UI +#' @title UI for settings tab showing details for the charts loaded in the app #' #' @param id module id #' @@ -23,8 +22,7 @@ settingsChartsUI <- function(id){ ) } -#' @title Settings Module - charts details - server -#' @description server for the display of the charts +#' @title Server for settings tab showing details for the charts loaded in the app #' #' @param input Shiny input object #' @param output Shiny output object diff --git a/R/mod_settingsCode.R b/R/mod_settingsCode.R index a55c14a4..a778bfc0 100644 --- a/R/mod_settingsCode.R +++ b/R/mod_settingsCode.R @@ -1,5 +1,5 @@ -#' UI for the settings page -#' +#' @title UI for settings tab providing code to re-start the app with current data/settings +#' #' @param id module ID #' #' @export @@ -92,8 +92,8 @@ settingsCodeUI <- function(id){ } -#' @title Server for the setting code page -#' +#' @title Server for settings tab providing code to re-start the app with current data/settings +#' #' @param input Shiny input object #' @param output Shiny output object #' @param session Shiny session object diff --git a/R/mod_settingsData.R b/R/mod_settingsData.R index 45e85175..8d15aae3 100644 --- a/R/mod_settingsData.R +++ b/R/mod_settingsData.R @@ -1,5 +1,4 @@ -#' @title Settings Module - data details -#' @description Settings Module - sub-module showing details for the data loaded in the app - UI +#' @title UI for settings tab showing current data #' #' @param id module id #' @@ -20,8 +19,7 @@ settingsDataUI <- function(id){ ) } -#' @title Settings Module - data details - server -#' @description server for the display of the loaded data +#' @title Server for settings tab showing current data #' #' @param input Shiny input object #' @param output Shiny output object diff --git a/R/mod_settingsMapping.R b/R/mod_settingsMapping.R index d114fe30..9b1b353e 100644 --- a/R/mod_settingsMapping.R +++ b/R/mod_settingsMapping.R @@ -1,6 +1,5 @@ -#' @title Settings view of Metadata/Mapping - UI -#' @description UI that displays the data mapping metadata. -#' +#' @title UI for settings tab showing current mapping +#' #' @param id module id #' #' @import rclipboard @@ -19,8 +18,7 @@ settingsMappingUI <- function(id){ ) } -#' @title Settings view of Metadata/Mapping - server -#' @description server for the display of the data mapping metadata. +#' @title Server for settings tab showing current mapping #' #' @param input Shiny input object #' @param output Shiny output object diff --git a/R/mod_settingsTab.R b/R/mod_settingsTab.R index b16ecf0a..380cd13b 100644 --- a/R/mod_settingsTab.R +++ b/R/mod_settingsTab.R @@ -1,4 +1,4 @@ -#' UI for the settings page +#' @title UI for the settings tab #' #' @param id module ID #' @@ -16,7 +16,7 @@ settingsTabUI <- function(id){ } -#' @title Server for the setting page +#' @title Server for the setting page #' #' @param input Shiny input object #' @param output Shiny output object diff --git a/R/safetyGraphicsApp.R b/R/safetyGraphicsApp.R index 8902c97a..1b90206c 100644 --- a/R/safetyGraphicsApp.R +++ b/R/safetyGraphicsApp.R @@ -1,4 +1,4 @@ -#' Run the interactive safety graphics app +#' Run the core safetyGraphics App #' #' @param domainData named list of data.frames to be loaded in to the app. Sample AdAM data from the safetyData package used by default #' @param meta data frame containing the metadata for use in the app. See the preloaded file (\code{?safetyGraphics::meta}) for more data specifications and details. Defaults to \code{safetyGraphics::meta}. diff --git a/R/safetyGraphicsInit.R b/R/safetyGraphicsInit.R index 81bde317..7c136424 100644 --- a/R/safetyGraphicsInit.R +++ b/R/safetyGraphicsInit.R @@ -1,4 +1,4 @@ -#' Run the interactive safety graphics app +#' App to select charts, load data and then initialize the core safetyGraphics app #' #' @param charts chart object #' @param delayTime time (in ms) between drawing app UI and starting server. Default set to 1000 (1 second), but could need to be higher on slow machine. diff --git a/README.md b/README.md index 171012f0..a62df0da 100644 --- a/README.md +++ b/README.md @@ -2,24 +2,15 @@ [![R build status](https://github.com/ASA-DIA-InteractiveSafetyGraphics/safetyGraphics/workflows/R-CMD-check/badge.svg)](https://github.com/ASA-DIA-InteractiveSafetyGraphics/safetyGraphics/actions) -# safetyGraphics: Clinical Trial Safety Graphics with R +# safetyGraphics: Clinical Trial Monitoring with R -The **safetyGraphics** package provides a framework for evaluation of clinical trial safety in R. It includes several safety-focused visualizations to empower clinical data monitoring. Chief among these is the Hepatic Explorer, based on the [Evaluation of the Drug-Induced Serious Hepatotoxicity (eDish)](https://www.ncbi.nlm.nih.gov/pubmed/21332248) visualization. A demo of the Hepatic Explorer interactive graphic is available [here](https://safetygraphics.github.io/hep-explorer/test-page/example1/) and is shown below. - -This package is being built in conjunction with the [hep-explorer](https://github.com/SafetyGraphics/hep-explorer) javascript library. +The {safetyGraphics} package provides a framework for the evaluation of clinical trial safety data in R using a flexible data pipeline. The package includes a shiny application that allows users to explore safety data using a series of interactive graphics, including the hepatic safety explorer shown below. The package has been developed as part of the Interactive Safety Graphics (ISG) workstream of the ASA Biopharm-DIA Safety Working Group. ![edishgif](https://user-images.githubusercontent.com/3680095/45834450-02b3a000-bcbc-11e8-8172-324c2fe43521.gif) -## Usage - -Users can interactively explore their data with a shiny application or create standalone interactive charts. +## Using the app -### Shiny application - -The Shiny app provides a simple interface for: -- Loading data -- Customizing settings and data mappings -- Viewing and exporting the interactive graphics +A demo of the app using sample data is available [here](https://jwildfire.shinyapps.io/safetyGraphics/) or can be initialized as follows: ```r devtools::install_github("SafetyGraphics/safetyGraphics") @@ -27,29 +18,10 @@ library("safetyGraphics") safetyGraphicsApp() #open the shiny application ``` -### Standalone charts +The most common workflow is for a user to initialize the app with their data, adjust settings as needed, and view the interactive charts. Finally, the user can share any chart by exporting its source code or by generating a self-contained, fully reproducible report that can be shared with others. -Users can also initialize customized standalone charts with a few lines of code. +Instructions for loading study data are provided in the introductory vignette and more complex customizations are provided in the cookbook vignette. -```r -devtools::install_github("safetyGraphics/safetyGraphics") -library("safetyGraphics") - -settings <- list( - id_col = "USUBJID", - value_col = "AVAL", - measure_col = "PARAM", - visit_col = "VISIT", - visitn_col = "VISITNUM", - studyday_col = "ADY", - normal_col_low = "A1LO", - normal_col_high = "A1HI", - measure_values = list(ALT = "Alanine Aminotransferase (U/L)", - AST = "Aspartate Aminotransferase (U/L)", - TB = "Bilirubin (umol/L)", - ALP = "Alkaline Phosphatase (U/L)") - ) - -chartRenderer(data=adlbc, settings=settings, chart="hepexplorer") +# Charts +The app is built to support a wide variety of chart types including static plots (e.g. from {ggplot2}), shiny modules, {htmlwidgets} and even static outputs like RTFs. Several pre-configured charts are included in the companion {safetyCharts} R Package, and are available by default in the app. Other charts can be added using the process descibed in this vignette. -``` diff --git a/_pkgdown.yml b/_pkgdown.yml index fce6b351..7539e8eb 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -5,6 +5,24 @@ template: bootswatch: cerulean navbar: + title: safetyGraphics + left: + - icon: fa-home fa-lg + href: index.html + - text: Vignettes + menu: + - text: Intro to Shiny App + href: articles/intro.html + - text: Chart Configuration + href: articles/chartConfiguration.html + - text: Examples Cookbook + href: articles/cookbook.html + - text: Technical FAQ + href: articles/technicalFAQ.html + - text: Functions + href: reference/index.html + - text: News + href: news/index.html right: - icon: fa-github href: https://github.com/SafetyGraphics/safetyGraphics @@ -12,27 +30,60 @@ navbar: development: mode: release - reference: - - title: Main Functions + - title: Main Shiny App Functions contents: - safetyGraphicsApp + - safetyGraphicsInit + - title: Shiny Modules + desc: Reusable Shiny Modules + contents: + - safetyGraphicsServer + - safetyGraphicsUI + - chartsTab + - chartsTabUI + - filterTab + - filterTabUI + - homeTab + - homeTabUI + - loadCharts + - loadChartsUI + - loadData + - loadDataUI + - mappingTab + - mappingTabUI + - mappingDomain + - mappingDomainUI + - mappingColumn + - mappingColumnUI + - mappingSelect + - mappingSelectUI + - settingsTab + - settingsTabUI + - settingsCharts + - settingsChartsUI + - settingsData + - settingsDataUI + - settingsMapping + - settingsMappingUI + - settingsCode + - settingsCodeUI + - title: Data + desc: Data sets used in the apps + contents: + - meta - title: Helper Functions - desc: these functions are used by the main app + desc: Utility functions used in the apps contents: - - addChart - - addSetting - - adlbc - - chartRenderer-shiny - - chartRenderer - - chartsMetadata + - app_startup + - chartsNav - detectStandard - - generateSettings - - getRequiredSettings - - getSettingsMetadata - - removeCharts - - removeSettings - - settingsMetadata - - standardsMetadata - - trimSettings - - validateSettings + - evaluateStandard + - filterTabChecks + - generateMappingList + - makeChartConfig + - makeChartExport + - makeChartParams + - makeChartSummary + - makeMapping + - prepareChart diff --git a/docs/404.html b/docs/404.html index 0eaf4b23..1013dc52 100644 --- a/docs/404.html +++ b/docs/404.html @@ -8,23 +8,29 @@ Page not found (404) • safetyGraphics + - + - + + - + + + + + - - + + - + - - + + @@ -32,10 +38,12 @@ + + @@ -49,7 +57,7 @@ - +
@@ -71,33 +79,38 @@ -
+ + diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index 83016c8b..b5b04273 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -8,23 +8,29 @@ License • safetyGraphics + - + - + + - + + + + + - - + + - + - - + + @@ -32,10 +38,12 @@ + + @@ -49,7 +57,7 @@ - +
@@ -71,33 +79,38 @@ -
-
YEAR: 2018
-COPYRIGHT HOLDER: Rho Inc.
+
YEAR: 2021
+COPYRIGHT HOLDER: safetyGraphics authors
 
+ +
diff --git a/docs/LICENSE.html b/docs/LICENSE.html new file mode 100644 index 00000000..96f3686c --- /dev/null +++ b/docs/LICENSE.html @@ -0,0 +1,175 @@ + + + + + + + + +MIT License • safetyGraphics + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+
+ + +
+ +

Copyright (c) 2021 safetyGraphics authors

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

+

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
+ +
+ + + +
+ + + +
+ + +
+

Site built with pkgdown 1.6.1.

+
+ +
+
+ + + + + + + + diff --git a/docs/articles/Cookbook.html b/docs/articles/Cookbook.html new file mode 100644 index 00000000..24121fd4 --- /dev/null +++ b/docs/articles/Cookbook.html @@ -0,0 +1,238 @@ + + + + + + + +Cookbook • safetyGraphics + + + + + + + + + + +
+
+ + + + +
+
+ + + + +
+

+Cookbook Vignette

+

This vignette contains a series of examples showing how to initialize the safetyGraphics Shiny app in different scenarios. For a general overview of the app see this vignette. For more details about adding custom charts, see this vignette.

+
+

+Setup and installation

+

safetyGraphics requires R v4 or higher. These examples have been tested using RStudio v1.4, but should work on other platforms with proper configuration.

+

You can install safetyGraphics from CRAN like any other R package:

+
install.packages("safetyGraphics")
+library("safetyGraphics")
+

Or to use the most recent development version from GitHub, call:

+
devtools::install_github("safetyGraphics/safetyCharts", ref="dev")
+library(safetyCharts)
+devtools::install_github("safetyGraphics/safetyGraphics", ref="dev")
+library(safetyGraphics)
+safetyGraphics::safetyGraphicsApp()
+
+
+

+Example 1 - Default App

+

To run the app with no customizations using sample AdAM data from the {safetyData} package, install the package and run:

+
safetyGraphics::safetyGraphicsApp()
+
+
+

+Example 2 - SDTM Data

+

The data passed in to the safetyGraphics app can be customized using the data parameter in safetyGraphicsApp(). For example, to run the app with SDTM data saved in {safetyData}, call:

+
sdtm <- list(
+    dm=safetyData::sdtm_dm,
+    aes=safetyData::sdtm_ae,
+    labs=safetyData::sdtm_lb
+)
+
+safetyGraphics::safetyGraphicsApp(domainData=sdtm)
+
+
+

+Example 3 - Single Data Domain

+

Running the app for a single data domain, is similar:

+
justLabs <- list(labs=safetyData::adam_adlbc)
+safetyGraphics::safetyGraphicsApp(domainData=justLabs)
+

Note that charts with missing data are automatically dropped and the filtering tab is not present since it requires demographics data by default.

+
+
+

+Example 4 - Drop Unwanted Charts

+

Users can also generate a list of charts and then drop charts that they don’t want to include. For example, if you wanted to drop charts with type of “htmlwidgets” you could run this code.

+
library(purrr)
+charts <- makeChartConfig() #gets charts from safetyCharts pacakge by default
+notWidgets <- charts %>% purrr::keep(~.x$type != "htmlwidget")
+safetyGraphicsApp(charts=notWidgets)
+
+
+

+Example 6 - Add a chart

+

The code below adds a new simple chart showing participants’ age distribution by sex.

+
ageDist <- function(data, settings){
+    p<-ggplot(data = data, aes_(x=as.name(settings$age_col))) +
+        geom_histogram() + 
+        facet_wrap(as.name(settings$sex_col))
+    return(p)
+}
+ageDist_chart<-list(
+    env="safetyGraphics",
+    name="ageDist",
+    label="Age Distribution",
+    type="plot",
+    domain="dm",
+    workflow=list(
+        main="ageDist"
+    )
+)
+charts <- makeChartConfig() 
+charts$ageDist<-ageDist_chart
+safetyGraphicsApp(charts=charts)
+

For extensive details on adding and customizing different types of charts, see this vignette.

+
+
+

+Example 7 - Non-standard data

+

Next, let’s initialize the the app with non-standard data. {safetyGraphics} automatically detects AdAM and SDTM data when possible, but for non-standard data, the user must provide a data mapping. This can be done in the app using the data/mapping tab, or can be done when the app is initialized by passing a mapping list to safetyGraphicsApp(). For example:

+
notAdAM <- list(labs=safetyData::adam_adlbc %>% rename(id = USUBJID))
+idMapping<- list(labs=list(id_col="id"))
+safetyGraphicsApp(domainData=notAdAM, mapping=idMapping)
+
+
+

+Example 8 - Non-standard data #2

+

For a more realistic example, consider this labs data set (csv). The data can be loaded in to safetyGraphics with the code below, but several items in the mapping page need to be filled in:

+
labs <- read.csv("https://raw.githubusercontent.com/SafetyGraphics/SafetyGraphics.github.io/master/pilot/SampleData_NoStandard.csv")
+safetyGraphics::safetyGraphicsApp(domainData=list(labs=labs))
+

drawing

+

Fortunately there is no need to re-enter this mapping information in every time you re-start the app. After filling in these values once, you can export code to restart the app with the specified settings pre-populated. First, click on the setting icon in the header and then on “code” to see this page:

+

+

The YAML code provided here captures the updates you’ve made on the mapping page. To re-start the app with those settings, just save these YAML code in a new file called customSettings.yaml in your working directory, and then call:

+
labs <- read.csv("https://raw.githubusercontent.com/SafetyGraphics/SafetyGraphics.github.io/master/pilot/SampleData_NoStandard.csv")
+customMapping <- read_yaml("customSettings.yaml")
+safetyGraphics::safetyGraphicsApp(
+    domainData=list(labs=labs),
+    mapping=customMapping   
+)
+

Note, that for more complex customizations, the setting page also provides a .zip file with a fully re-usable version of the app.

+
+
+
+ + + +
+ + + +
+ +
+

Site built with pkgdown 1.6.1.

+
+ +
+
+ + + + + + diff --git a/docs/articles/Cookbook_files/header-attrs-2.10/header-attrs.js b/docs/articles/Cookbook_files/header-attrs-2.10/header-attrs.js new file mode 100644 index 00000000..dd57d92e --- /dev/null +++ b/docs/articles/Cookbook_files/header-attrs-2.10/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/Cookbook_files/header-attrs-2.9/header-attrs.js b/docs/articles/Cookbook_files/header-attrs-2.9/header-attrs.js new file mode 100644 index 00000000..dd57d92e --- /dev/null +++ b/docs/articles/Cookbook_files/header-attrs-2.9/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/TechnicalFAQ.html b/docs/articles/TechnicalFAQ.html new file mode 100644 index 00000000..b1191736 --- /dev/null +++ b/docs/articles/TechnicalFAQ.html @@ -0,0 +1,236 @@ + + + + + + + +Technical FAQ • safetyGraphics + + + + + + + + + + +
+
+ + + + +
+
+ + + + +
+

+Technical FAQ Vignette

+

This vignette answers frequently asked technical questions about {safetyGraphics}. It addressees questions on a variety of technical topics including Qualification and Validation status, Common Data Pipelines and Security.

+

Whenever new questions come in, we’ll update the version of this FAQ in our wiki - so check there first if you have a question. We’ll update the vignette on CRAN whenever a new version of the package is released.

+
+
+

+Validation, Quality Control and Testing

+
+

+Q: Is the safetyGraphics package validated?

+

A: As of the version 2 release, the safetyGraphics package is intended for exploratory use only and is not validated or qualified per 21 CFR Part 11. No warranty or guarantees are included as part of the package. Further, any formal validation should be fit for purpose and follow your organization’s procedures. That said, extensive quality checks are built in to the package (see the question below for details) and in to many of charts that are included by default. We follow the work of R Validation hub closely, and may release validation guidance based on the approach described in their white paper at a future date.

+
+
+

+Q: Can I validate charts created by safetyGraphics?

+

A: Study-specific instances of most safetyGraphics charts can be exported either as an R script or as a standalone html report. It may be possible to treat those outputs as standard TLFs (Tables, Listings and Figures) and conduct QC/Validation on them using standard statistical SOPs. Consult with your companies procedures to confirm.

+
+
+

+Q: What testing/QC process for safetyGraphics?

+

A: Several layers of quality control are included in our standard development workflow including: - Over 200 automated unit tests with testthat that run automatically via Continuous integration with GitHub actions. - Automated unit tests for shiny modules run via a headless browser using shinytest. - Pass all standard R checks in R cmd check - Full code review of all new functionality documented in GitHub PR. - Issue tracking in GitHub - Formal Alpha/Beta user testing before major releases - Basic user tests conducted before minor release

+
+
+
+

+Use Cases, Data Sources and Deployment

+
+

+Q: What are some common use cases for safetyGraphics?

+

A: safetyGraphics graphics has been used in a variety of ways. Some of the most common use cases thus far are: - Analysts exploring safety data - Clinicians monitoring ongoing studies - Analysts and Clinicians evaluating safety signals in completed studies

+

As an open source tool with a flexible data pipeline, many other use cases have been discussed: - Data review by Data Safety Monitoring Boards (link) - Submissions to FDA (link) - Visualizing Analysis results data (link) - Risk based monitoring

+
+
+

+Q: Do I have to use a certain data standard with safetyGraphics?

+

A: No. Any standard (or non-standard) data can be loaded as long as it meets the minimum data requirements for the selected data domain. Metadata capturing default CDISC standards are included with the app (see ?safetyGraphics::meta) so that data mappings can be automatically populated when AdAM and SDTM data are loaded. Other data standards require the user to manually complete the data mapping in the mapping tab - see the cookbook vignette for examples.

+
+
+

+Q: What data sources does safetyGraphics support? How do I load custom data?

+

A: This topic is covered in detail in the Loading data section of the Introductory vignettesafetyGraphics is designed to support a flexible data pipeline that supports many data types. In short, data can be loaded using the the dataDomains parameter in the safetyGraphicsApp() function or via the safetyGraphicsInit() graphical user interface.

+

safetyGraphicsApp() - custom data can be loaded via the dataDomains parameter, which should be a list containing dataframes or tibbles for each clinical domain; that list can be populated by importing data from any number of sources including databases, sas files or any number of other sources. See the cookbook vignette for some basic examples of loading custom data.

+

safetyGraphicsInit() - allows users to load tabular data from a variety of sources using the point-and-click interface provided in the {datamods} package.

+

More detail is provided in the Loading data section of the Introductory vignette

+
+
+

+Q: How can the safetyGraphics app be shared?

+

A: The safetyGraphics app can be shared using standard shiny methodology. More details for a specific use cases are given in the next few questions. Charts created by safetyGraphics can also be exported and re-used. Charts created with htmlwidgets are especially flexible and can be used in many contexts - including in web applications outside of R.

+
+
+

+Q: Can I deploy safetyGraphics to shinyapps.io to explore trial data from my organization?

+

A: No, we advise against loading non-authorized, private, or non-deidentified patient data outside of your organization’s firewall. Consult with your IT and QA first. There is huge risk associated with confidentiality, IP, and patient privacy. Also refer to ShinyApps.io Chapter 8 Security and Compliance.

+
+ +
+
+

+Misc.

+
+

+Q: How do I avoid R not choking on the huge volume of lab data? (from @AlbrechtDurer)

+

A: This is a very good question @AlbrechtDurer, and in my experience the answer is complex and varies for different use cases. Focusing on specific toxicities helps, but probably isn’t enough in really big studies. In those cases, I think the most important thing is to design a good data pipeline that includes both a database backend (as opposed to loading all of your study data each time you initialize the app) and visualizations that summarize the data in a reasonable way (as opposed to just plotting every single data point in a scatter plot no matter what). Fortunately this is all doable in R, and improvements in this area are our radar for safetyGraphics after v2 goes live.

+
+
+
+ + + +
+ + + +
+ +
+

Site built with pkgdown 1.6.1.

+
+ +
+
+ + + + + + diff --git a/docs/articles/TechnicalFAQ_files/header-attrs-2.10/header-attrs.js b/docs/articles/TechnicalFAQ_files/header-attrs-2.10/header-attrs.js new file mode 100644 index 00000000..dd57d92e --- /dev/null +++ b/docs/articles/TechnicalFAQ_files/header-attrs-2.10/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/TechnicalFAQ_files/header-attrs-2.9/header-attrs.js b/docs/articles/TechnicalFAQ_files/header-attrs-2.9/header-attrs.js new file mode 100644 index 00000000..dd57d92e --- /dev/null +++ b/docs/articles/TechnicalFAQ_files/header-attrs-2.9/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/chartConfiguration.html b/docs/articles/chartConfiguration.html new file mode 100644 index 00000000..82c5b574 --- /dev/null +++ b/docs/articles/chartConfiguration.html @@ -0,0 +1,411 @@ + + + + + + + +Chart Configuration • safetyGraphics + + + + + + + + + + +
+
+ + + + +
+
+ + + + +
+

+Chart Configuration Vignette

+

The {safetyGraphics} shiny app can be used to display a wide variety of charts. This vignette provides details about the charting process including step-by-step instructions for adding new charts and technical specifications, but first we need to talk about a 2nd package …

+
+
+

+Introducing {safetyCharts}

+

While this is technically a vignette for {safetyGraphics}, the {safetyCharts} package is just as important here. The roles of the packages can be summarized in just a few words:

+

The {safetyGraphics} platform displays charts from {safetyCharts}.

+

This relationship is central to the technical framework for the safetyGraphics app. By itself, the safetyGraphics platform really doesn’t do much! In fact, none of the content on the Charts tab is actually found in the safetyGraphics package; it’s all imported from elsewhere! As you’ve probably guessed, the default charts live in the safetyCharts package. safetyCharts has over a dozen charts that are configured to work with {safetyGraphics}, but can also easily be used independently.

+

While {safetyGraphics} and {safetyCharts} are designed to work seamlessly together, users can also add charts from other packages. In fact, several charts in {safetyCharts} are just wrappers that load charts from other packages for use in {safetyGraphics}. The rest of this vignette provides a series of step-by-step examples detailing how this process works for different types of charts.

+
+
+

+{safetyGraphics} Chart Components

+

To add a chart to safetyGraphics, two components are required:

+
    +
  1. A Configuration Object
  2. +
  3. A Chart Function
  4. +
+

The configuration file captures metadata about the chart for use in the app and is typically saved as a YAML file. Several example configuration files are provided in the examples below, and YAML Configuration files for {safetyCharts} are saved here.

+

The chart function typically takes a list of settings and a list of data as inputs and returns a chart object ready to be displayed in the app. Details of charting functions vary somewhat for different chart types, as explained in the examples below.

+

A full technical specification of this chart configuration framework is provided in Appendix 1.

+
+
+

+Example 1 - Hello World

+

Once you’ve created the configuration and chart functions, the chart can be added to the app via the charts parameter in safetyGraphicsApp(). Consider this simple “Hello World” example:

+
# Chart Function
+helloWorld <- function(data, settings){
+    plot(-1:1, -1:1)
+    text(runif(20, -1,1),runif(20, -1,1),"Hello World")
+}
+
+# Chart Configuration
+helloworld_chart<-list(
+    env="safetyGraphics",
+    name="HelloWorld",
+    label="Hello World!",
+    type="plot",
+    domain="aes",
+    workflow=list(
+        main="helloWorld"
+    )
+)
+
+safetyGraphicsApp(charts=list(helloworld_chart))
+

It’s also easy to add a custom chart to the default charts provided in {safetyCharts} using the makeChartConfig() function:

+
charts <- makeChartConfig(packages="safetyCharts") # or just makeChartConfig() since safetyCharts is included by default
+charts$helloworld<-helloworld_chart
+safetyGraphicsApp(charts=charts)
+

Here’s our Hello World the chart running in the app:

+

+
+
+

+Example 2 - Static Outlier Explorer

+

Now let’s consider a more complex example that makes use of the data and settings provided in safetyGraphics. In this section, we use {ggplot2} to create a spaghetti plot for tracking outliers in lab data. First, consider the following code which creates a stand-alone plot for a single data set:

+
# Use sample clinical trial data sets from the {safetyData} package
+library(safetyData) 
+library(ggplot2)
+library(dplyr)
+
+# Define data mapping using a format similar to a reactive safetyGraphics mapping 
+settings <- list(
+    id_col="USUBJID",
+    value_col="LBSTRESN",
+    measure_col="LBTEST",
+    studyday_col="LBDY"
+)
+
+# Define a plotting function that takes data and settings as inputs 
+spaghettiPlot <- function( data, settings ){
+    # define plot aes - note use of standard evaluation! 
+    plot_aes <- aes_(
+        x=as.name(settings$studyday_col), 
+        y=as.name(settings$value_col), 
+        group=as.name(settings$id_col)
+    )
+
+    #create the plot
+    p<-ggplot(data = data, plot_aes) +
+        geom_path(alpha=0.15) + 
+        facet_wrap(
+            as.name(settings$measure_col),
+            scales="free_y"
+        )
+    return(p)
+}
+
+spaghettiPlot(
+    safetyData::sdtm_lb %>% 
+        filter(LBTEST %in% c("Albumin","Bilirubin","Calcium","Chloride")), 
+    settings
+)
+

Running the code above should create a plot with 4 panels:

+

+

With minor modifications, this chart can be added to the {safetyGraphics} shiny app, which allows us to create the chart with any mappings/data combination loaded in the app. The spaghettiPlot() function above is already written to work with safetyGraphics, so we just need to create the chart configuration object. This time we’ll capture the configuration in a YAML file.

+
env: safetyGraphics
+label: Spaghetti Plot
+type: plot
+domain: 
+  - labs
+workflow:
+  main: spaghettiPlot
+links:
+  safetyCharts: https://github.com/SafetyGraphics/safetycharts
+

With the charting function loaded in to our session and the configuration file saved in our working directory as spaghetti.yaml, we can add the chart to the app as follows:

+
library(yaml)
+charts <- makeChartConfig()
+charts$spaghetti<-prepareChart(read_yaml('spaghetti.yaml'))
+safetyGraphicsApp(charts=charts)
+

Under the charts tab, you’ll see:

+

+

If you look closely at the spaghettiPlot() code above, you’ll noticed some details that make the chart work in the app:

+
    +
  • The chart function is written as a function taking data and settings as inputs. This is the expected parameterization for most charts in {safetyGraphics}.
  • +
  • The references to settings use parameters that are defined on the mapping tab. Behind the scenes, these are defined in the safetyGraphics::meta.
  • +
  • The spaghettiPlot function is referenced in the main item the YAML workflow. This tells the app which function to use to draw the chart.
  • +
+

These details allow users to dynamically define data attributes for any labs data set, allowing the chart to be reused across many different types of data.

+

This example is inspired by safetyCharts::safety_outlier_explorer - the charting function and yaml configuration file on are GitHub.

+
+
+

+Example 3 - Shiny Module

+

{safetyGraphics} also supports defining charts as Shiny Modules. Once you’re familiar with modules, they are relatively straightforward to use with safetyGraphics.

+

Let’s take a look at a simple module that extends the functionality of the static chart from the example above. Once again, this example is based upon safetyCharts, and you can see the code and config on GitHub.

+

The config object for a module differs from a static chart is that the workflow section of the YAML file must specify ui and server functions instead of a main charting function. This example defines a simple UI function that allows users to select which lab measurements should be included in the spaghetti plot from example 1:

+
safetyOutlierExplorer_ui <- function(id) {
+    ns <- NS(id) 
+    sidebar<-sidebarPanel(
+        selectizeInput(
+            ns("measures"), 
+            "Select Measures", 
+            multiple=TRUE, 
+            choices=c("")
+        )
+    )
+    main<-mainPanel(plotOutput(ns("outlierExplorer")))
+    ui<-fluidPage(
+        sidebarLayout(
+            sidebar,
+            main,
+            position = c("right"),
+            fluid=TRUE
+        )
+    )
+    return(ui)
+}
+

Next we define a server function that populates the control for selecting measurements and then draws the plot using safetyCharts::safety_outlier_explorer() charting function - which is based on the spaghetti() function ! Note that the server function takes a single reactive params object containing the data (params$data) and settings (param$settings) as input.

+
safetyOutlierExplorer_server <- function(input, output, session, params) {
+
+    ns <- session$ns
+    # Populate control with measures and select all by default
+    observe({
+        measure_col <- params()$settings$measure_col
+        measures <- unique(params()$data[[measure_col]])
+        updateSelectizeInput(
+            session, 
+            "measures",
+            choices = measures,
+            selected = measures
+        )
+    })
+
+    # customize selected measures based on input
+    settingsR <- reactive({
+        settings <- params()$settings
+        settings$measure_values <- input$measures
+        return(settings)
+    })
+
+    #draw the chart
+    output$outlierExplorer <- renderPlot({safety_outlier_explorer(params()$data, settingsR())})
+}
+

Finally, the YAML configuration file looks like this - just the workflow and label changes from Example 1:

+
env: safetyGraphics
+label: Outlier Explorer - Module
+type: module
+package: safetyCharts
+domain: 
+  - labs
+workflow:
+  ui: safetyOutlierExplorer_ui
+  server: safetyOutlierExplorer_server
+links:
+  safetyCharts: https://github.com/SafetyGraphics/safetycharts
+

Initializing the app as usual by adding it to the chart list: charts$outlierMod<-prepareChart(read_yaml('outlierMod.yaml'))

+

Unselecting a few measures gives the following display:

+
+
+

+Example 4 - htmlwidgets and init functions

+

You can also add custom htmlwidgets to safetyGraphics. In fact, many of the default charts imported from safetyCharts are javascript libraries that are imported as htmlwidgets. Like shiny modules, htmlwidgets are relatively simple to use once you are familiar with the basics.

+

The biggest differences between widgets and other charts in safetyGraphics are:

+
    +
  1. The widget must be contained in a package, which must be specified in the YAML file.
  2. +
  3. The widget expects a widget item giving the name of the widget in the YAML workflow.
  4. +
  5. By default, the data and settings for a widget are passed in a list (list(data=data, settings=settings)) to the x parameter in htmlwidget::createWidget.
  6. +
+

Items 1 and 2 above are simple enough, but #3 is likely to create problems unless the widget is designed specifically for usage with safetyGraphics. That is, if the widget isn’t expecting x$settings to be a list that it uses to configure the chart, it probably isn’t going to work as expected.

+

Fortunately, there’s a workaround built in to safetyGraphics in the form of init workflow functions. Init functions run before the chart is drawn, and can be used to create custom parameterizations. The init function should take data and settings as inputs and return params which should be a list which is then provided to the chart (see the appendix for more details). The init function for the the interactive AE Explorer is a good example. It starts by merging demographics and adverse event data and then proceeds to create a customized settings object to match the configuration requirements of the javascript chart renderer. This init function is then saved under workflow$init in the chart config object.

+

The rest of the chart configuration YAML is similar to the examples above, and the chart is once again by passing the chart config object to safetyGraphicsApp()

+
+
+

+Appendix #1 - Chart Framework Technical Specifications

+
+

+Configuration Overview

+

+

The diagram above summarizes the various components of the safetyGraphics charting framework: - The safetyGraphicsApp() function allows users to specify which charts to include in the shiny app via the charts parameter, which expects a list of charts. - Each item in charts is itself defined as a list that provides configuration details for a single chart. These configuration lists have several required parameters, which are described in the technical specification below. - Configuration lists are typically saved as YAML files, but can be also be loaded directly as list objects as shown in the Hello World example above. - Needed functions are bound to the chart object via the prepareChart() function. See the documentation for chart$functions below for full details.

+
+
+

+Chart Specification

+

Each item in the charts list should be a list() with the following parameters: - env: Environment for the chart. Must be set to “safetyGraphics” or the chart is dropped. Type: character. Required - name: Name of the chart. Type: character. Required - type:: Type of chart. Valid options are: “plot”,“htmlwidget”,“html”,“table” and “module”. Type: character. Required - label: A short description of the chart. chart\(name is used if not provided. Type: *character*. *Optional* - `domain`: The data domain(s) used in the chart. Type: *character*. **Required** - `package`: The package where the {htmlwidget} is saved. Type: *character*. **Required** when `chart\)typeis "htmlwidget" -order: Order in which to display the chart. If order is a negative number, the chart is dropped. Defaults to 999999. Type: *Integer*. *Optional* -links: Named list of link names/urls to be shown in the chart header. Type: *list of character*. *Optional* -path: Full path of the YAML file. Auto-generated bymakeChartConfig()Type: *character* *optional* -workflow: Names of functions used to create the chart. Should be loaded in global environment or included inchart\(package` before calling `prepareChart()`. Supported parameters are listed below. Type: *list of character*. **Required** - `workflow\)main: name of the function to draw the chart. The function should takedataandsettingsparameters unless the input parameters are customized by aninitfunction. **Required**, unlesschart\(type` is "htmlwidget" or "module") - `workflow\)init: name of initialization function that runs before chart is drawn via the main function. Should take data and settings as input and return a list of parameters accepted by the main function. Optional - workflow$widget: name or widget saved in chart$package to be passed to htmlwidgets::createWidget Required when chart$type is “htmlwidget” - workflow$ui and workflow$server: names of functions to render shiny ui and server. Automatically generated in prepareChart() unless chart$type is “module”. Required when chart$type is ‘module’ - functions: a list of functions used to create the chart. Typically generated at runtime by prepareChart() using information in chart$workflow, chart$type and chart$package. Not recommended to generate manually. Type: list of functions. Required

+
+
+

+Default Technical workflow

+

This appendix describe the technical process used to render a chart when safetyGraphicsApp() is called with the default parameters.

+
    +
  1. +safetyGraphicsApp() is called with charts and chartSettingsPath as NULL (the default).
  2. +
  3. +app_startup is called, which then immediately calls makeChartConfig().
  4. +
  5. +makeChartConfig() looks for charts in the safetyCharts package (the default) since no path was specified. The function looks for the package in all current .libPaths() and then looks in the inst/config folder once the package is found.
  6. +
  7. +makeChartConfig loads YAML configuration files in the specified directories and saves them to a list. name and path parameters are added.
  8. +
  9. +makeChartConfig calls prepareChart for each chart configuration. prepareChart sets default values for order, name and export, and then binds relevant functions to a chart$functions list based on the chart’s type, workflow and package.
  10. +
  11. That list of charts is then returned to app_startup() which runs a few actions on each chart: +
      +
    • If chart$functions is missing, prepareChart is called (not relevant in the default workflow, but useful for adding custom charts)
    • +
    • If chart$order is negative, the chart is dropped with a message.
    • +
    • If chart$env is not “safetyGraphics”, the chart is dropped with a message.
    • +
    • If chart$domains has elements not found in the dataDomains passed to `app_startup(), the chart is dropped with a message.
    • +
    • +charts are re-ordered based on chart$order +
    • +
    +
  12. +
  13. +app_startup returns the list of charts to safetyGraphicsApp which then then passes them along to safetyGraphicsServer as the charts parameter.
  14. +
  15. +safetyGraphicsServer then creates modules for each chart. First, UIs are created via chartsNav() which then calls: +
      +
    • +makeChartSummary to create the chart header with links and metadata and …
    • +
    • +ChartsTabUI which then calls chart$functions$ui to create the proper UI element based on chart$type.
    • +
    +
  16. +
  17. Next, safetyGraphicsServer draws the charts using chartsTab() which: +
      +
    • Creates a reactive params object containing mappings and data using makeChartParams() which: +
        +
      • Subsets domainData based on chart$domain +
      • +
      • Calls charts$functions$init if provided
      • +
      • Does custom formatting for chart$type of “htmlwidget”
      • +
      +
    • +
    • Chart is drawn using chart$functions$server and chart$functions$main +
    • +
    • Button to download R script is added to header. Script is created by makeChartExport() +
    • +
    • Button to download html report is added to header unless type=“module”. Report template is at “inst/reports/safetyGraphicsReport.Rmd”
    • +
    +
  18. +
  19. Finally, safetyGraphicsServer passes the charts to settingsTab, which uses them to help populate the charts and code subtabs.
  20. +
+
+
+
+ + + +
+ + + +
+ +
+

Site built with pkgdown 1.6.1.

+
+ +
+
+ + + + + + diff --git a/docs/articles/chartConfiguration_files/header-attrs-2.10/header-attrs.js b/docs/articles/chartConfiguration_files/header-attrs-2.10/header-attrs.js new file mode 100644 index 00000000..dd57d92e --- /dev/null +++ b/docs/articles/chartConfiguration_files/header-attrs-2.10/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/chartConfiguration_files/header-attrs-2.9/header-attrs.js b/docs/articles/chartConfiguration_files/header-attrs-2.9/header-attrs.js new file mode 100644 index 00000000..dd57d92e --- /dev/null +++ b/docs/articles/chartConfiguration_files/header-attrs-2.9/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/index.html b/docs/articles/index.html index 2adb935d..ad545bd5 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -8,23 +8,29 @@ Articles • safetyGraphics + - + - + + - + + + + + - - + + - + - - + + @@ -32,10 +38,12 @@ + + @@ -49,7 +57,7 @@ - +
@@ -71,33 +79,38 @@ -
@@ -136,11 +155,11 @@

All vignettes

-

Site built with pkgdown 1.4.1.

+

Site built with pkgdown 1.6.1.

diff --git a/docs/articles/intro.html b/docs/articles/intro.html new file mode 100644 index 00000000..ee4c805d --- /dev/null +++ b/docs/articles/intro.html @@ -0,0 +1,245 @@ + + + + + + + +Intro to Shiny App • safetyGraphics + + + + + + + + + + +
+
+ + + + +
+
+ + + + +
+

+Intro Vignette

+

The safetyGraphics shiny app provides an easy-to-use shiny interface for creating shareable safety graphics for any study. This vignette provides an overview of the app’s functionality, shows how to initialize the app with your own study data, and provides links to technical resources explaining how to customize the app.

+
+
+

+safetyGraphics Demo

+

A demo of shiny application using data from the {safetyData} package is hosted here. The app can also be initialized with the safetyGraphicsApp() function in the R console - see Appendix 1 for details.

+

Let’s take a quick look at the various pages in the app.

+
+

+Home Tab

+

A home page has a basic overview of the app.

+

+
+
+

+Mapping Tab

+

The Mapping tab is used to tell charts which data columns and fields to use for various chart components.

+

+

This mapping process makes it easy to re-use charts across many different studies. You can see previews of the loaded data using the checkbox at the top of the page. The demo data has 3 data domains (labs, adverse events (aes) and demographics (dm)), but others can be added as well. The mapping tab is automatically filled in for common data standards, like the ADaM data shown here, but can also be filled in manually for non-standard data.

+
+
+

+Filtering Tab

+

The Filtering tab allows users to interactively select which participants to include in charts.

+

+

This tab is created using the filter functionality included in the {datamods} package. Whenever data is filtered in this tab, those filtered data are used in all charts (across all data domains). Note that the number of participants selected is always shown in the upper right hand corner of the app.

+
+
+

+Charts Tab

+

Clicking the Charts tab opens a dropdown menu containing a series of charts related to clinical trial safety. Clicking the Hepatic Safety Explorer opens this page:

+

+

safetyGraphics supports many different kinds of charts including web-based interactive graphics using {htmlwidgets} (like the chart shown above), static plots, plotly plots and custom shiny modules. Each chart has a header that provides details about the chart, links to chart-specific resources and buttons that allow users to download a stand-alone html report or a .R file that reproduces the chart. See the Chart Configuration Vignette for more detail about the safetyGraphics charting framework.

+
+
+

+⚙️ (Settings) Tab

+

Finally, the Settings tab - shown as a gear icon ⚙️ - contains technical details that can be used to customize/troubleshoot the app. Clicking on the “Code” sub-tab (shown below) allows you to download a zip file that can be used to re-open the app with with any customizations that have been made during your current session.

+

+
+
+
+

+Loading Study Data

+

There are 2 primary ways to load your study data in to the safetyGraphics shiny app:

+
    +
  1. Using safetyGraphicsInit() shiny interface
  2. +
  3. Passing data directly to safetyGraphicsApp() +
  4. +
+
+

+Loading data with safetyGraphicsInit() +

+

The safetyGraphicsInit() function starts a simple app that allows users to select charts and then load the data required via a point-and-click interface as shown below:

+

+

The app dynamically determines which data sets are required for the selected charts and updates the “Data Loader” UI when the charts selection changes. Below, we’ve selected 2 charts from the labs domain - so the other data domains are automatically hidden.

+

+

Once you’ve picked charts, click the “Load” buttons in the “Data Loader” section to select data files for each domain. Data is loaded using the import functionality from the {datamods} package which allows you to select data loaded in your R session or load data files directly from your file system. datamods supports any file format that {rio} can handle including text files, Excel, SAS and SPSS format.

+

Once you’ve loaded files for all of the active data domains, the “Run App” button will become active. Click it to initialize the app.

+
+
+

+Passing data to safetyGraphicsApp() +

+

You can also initialize the app with custom data directly from the R console. The basic workflow is as follows:

+
    +
  1. Load your data in to the R session
  2. +
  3. Save your data as a named list. The name of each list item should correspond to a safetyGraphics data domain.
  4. +
  5. Run safetyGraphicsApp() using the domainData to pass the list of data frames.
  6. +
+

Here is a simple example that starts the app with SDTM data from the safetyData library:

+
library(safetyData)
+sdtm <- list(
+    dm=safetyData::sdtm_dm,
+    aes=safetyData::sdtm_ae,
+    labs=safetyData::sdtm_lb
+)
+
+safetyGraphics::safetyGraphicsApp(domainData=sdtm)
+

This example and other use cases are described in the safetyGraphics Cookbook - Advanced Examples Vignette.

+
+
+
+

+Additional Resources

+

Several additional vignettes are available for more advanced topics: - Chart Configuration Vignette - details about the charting process including technical specifications and step-by-step instructions - Cookbook Vignette - a series of examples showing how to initialize the safetyGraphics Shiny app in different scenarios - Technical FAQ Vignette Vignette - vignette discussing security, validation and other technical issues

+

The {safetyGraphics} app is maintained by the Interactive Safety Graphics (ISG) subteam of the ASA Biopharm-DIA Safety Working Group. You can learn more about the team and find links to recent presentations and publications at our home page.

+
+
+

+Appendix 1 - Initialization code

+

We suggest running the app in RStudio with R version 4.0 or higher. The following code installs the {safetyGraphics} package and initializes the app demo:

+
install.packages('safetyGraphics')
+library(safetyGraphics)
+safetyGraphicsApp() 
+

Or to use the initialization workflow:

+
install.packages('safetyGraphics')
+library(safetyGraphics)
+safetyGraphicsInit() 
+

Or you can install the most recent development version of {safetyGraphics} and the companion package {safetyCharts} directly from GitHub:

+
install.packages("devtools")
+library(devtools)
+devtools::install_github("safetyGraphics/safetyGraphics") 
+library(safetyGraphics)
+devtools::install_github("safetyGraphics/safetyCharts") 
+library(safetyCharts)
+safetyGraphicsApp() #or safetyGraphicsInit()
+
+
+ + + +
+ + + +
+ +
+

Site built with pkgdown 1.6.1.

+
+ +
+
+ + + + + + diff --git a/docs/articles/intro_files/header-attrs-2.10/header-attrs.js b/docs/articles/intro_files/header-attrs-2.10/header-attrs.js new file mode 100644 index 00000000..dd57d92e --- /dev/null +++ b/docs/articles/intro_files/header-attrs-2.10/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/intro_files/header-attrs-2.9/header-attrs.js b/docs/articles/intro_files/header-attrs-2.9/header-attrs.js new file mode 100644 index 00000000..dd57d92e --- /dev/null +++ b/docs/articles/intro_files/header-attrs-2.9/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/authors.html b/docs/authors.html index 231c124c..06c9745f 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -8,23 +8,29 @@ Authors • safetyGraphics + - + - + + + + - + + + - - + + - + - - + + @@ -32,10 +38,12 @@ + + @@ -49,7 +57,7 @@ - + @@ -164,11 +169,11 @@

Authors

diff --git a/docs/bootstrap-toc.css b/docs/bootstrap-toc.css new file mode 100644 index 00000000..5a859415 --- /dev/null +++ b/docs/bootstrap-toc.css @@ -0,0 +1,60 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ + +/* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ + +/* All levels of nav */ +nav[data-toggle='toc'] .nav > li > a { + display: block; + padding: 4px 20px; + font-size: 13px; + font-weight: 500; + color: #767676; +} +nav[data-toggle='toc'] .nav > li > a:hover, +nav[data-toggle='toc'] .nav > li > a:focus { + padding-left: 19px; + color: #563d7c; + text-decoration: none; + background-color: transparent; + border-left: 1px solid #563d7c; +} +nav[data-toggle='toc'] .nav > .active > a, +nav[data-toggle='toc'] .nav > .active:hover > a, +nav[data-toggle='toc'] .nav > .active:focus > a { + padding-left: 18px; + font-weight: bold; + color: #563d7c; + background-color: transparent; + border-left: 2px solid #563d7c; +} + +/* Nav: second level (shown on .active) */ +nav[data-toggle='toc'] .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; +} +nav[data-toggle='toc'] .nav .nav > li > a { + padding-top: 1px; + padding-bottom: 1px; + padding-left: 30px; + font-size: 12px; + font-weight: normal; +} +nav[data-toggle='toc'] .nav .nav > li > a:hover, +nav[data-toggle='toc'] .nav .nav > li > a:focus { + padding-left: 29px; +} +nav[data-toggle='toc'] .nav .nav > .active > a, +nav[data-toggle='toc'] .nav .nav > .active:hover > a, +nav[data-toggle='toc'] .nav .nav > .active:focus > a { + padding-left: 28px; + font-weight: 500; +} + +/* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ +nav[data-toggle='toc'] .nav > .active > ul { + display: block; +} diff --git a/docs/bootstrap-toc.js b/docs/bootstrap-toc.js new file mode 100644 index 00000000..1cdd573b --- /dev/null +++ b/docs/bootstrap-toc.js @@ -0,0 +1,159 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ +(function() { + 'use strict'; + + window.Toc = { + helpers: { + // return all matching elements in the set, or their descendants + findOrFilter: function($el, selector) { + // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ + // http://stackoverflow.com/a/12731439/358804 + var $descendants = $el.find(selector); + return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); + }, + + generateUniqueIdBase: function(el) { + var text = $(el).text(); + var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); + return anchor || el.tagName.toLowerCase(); + }, + + generateUniqueId: function(el) { + var anchorBase = this.generateUniqueIdBase(el); + for (var i = 0; ; i++) { + var anchor = anchorBase; + if (i > 0) { + // add suffix + anchor += '-' + i; + } + // check if ID already exists + if (!document.getElementById(anchor)) { + return anchor; + } + } + }, + + generateAnchor: function(el) { + if (el.id) { + return el.id; + } else { + var anchor = this.generateUniqueId(el); + el.id = anchor; + return anchor; + } + }, + + createNavList: function() { + return $(''); + }, + + createChildNavList: function($parent) { + var $childList = this.createNavList(); + $parent.append($childList); + return $childList; + }, + + generateNavEl: function(anchor, text) { + var $a = $(''); + $a.attr('href', '#' + anchor); + $a.text(text); + var $li = $('
  • '); + $li.append($a); + return $li; + }, + + generateNavItem: function(headingEl) { + var anchor = this.generateAnchor(headingEl); + var $heading = $(headingEl); + var text = $heading.data('toc-text') || $heading.text(); + return this.generateNavEl(anchor, text); + }, + + // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). + getTopLevel: function($scope) { + for (var i = 1; i <= 6; i++) { + var $headings = this.findOrFilter($scope, 'h' + i); + if ($headings.length > 1) { + return i; + } + } + + return 1; + }, + + // returns the elements for the top level, and the next below it + getHeadings: function($scope, topLevel) { + var topSelector = 'h' + topLevel; + + var secondaryLevel = topLevel + 1; + var secondarySelector = 'h' + secondaryLevel; + + return this.findOrFilter($scope, topSelector + ',' + secondarySelector); + }, + + getNavLevel: function(el) { + return parseInt(el.tagName.charAt(1), 10); + }, + + populateNav: function($topContext, topLevel, $headings) { + var $context = $topContext; + var $prevNav; + + var helpers = this; + $headings.each(function(i, el) { + var $newNav = helpers.generateNavItem(el); + var navLevel = helpers.getNavLevel(el); + + // determine the proper $context + if (navLevel === topLevel) { + // use top level + $context = $topContext; + } else if ($prevNav && $context === $topContext) { + // create a new level of the tree and switch to it + $context = helpers.createChildNavList($prevNav); + } // else use the current $context + + $context.append($newNav); + + $prevNav = $newNav; + }); + }, + + parseOps: function(arg) { + var opts; + if (arg.jquery) { + opts = { + $nav: arg + }; + } else { + opts = arg; + } + opts.$scope = opts.$scope || $(document.body); + return opts; + } + }, + + // accepts a jQuery object, or an options object + init: function(opts) { + opts = this.helpers.parseOps(opts); + + // ensure that the data attribute is in place for styling + opts.$nav.attr('data-toggle', 'toc'); + + var $topContext = this.helpers.createChildNavList(opts.$nav); + var topLevel = this.helpers.getTopLevel(opts.$scope); + var $headings = this.helpers.getHeadings(opts.$scope, topLevel); + this.helpers.populateNav($topContext, topLevel, $headings); + } + }; + + $(function() { + $('nav[data-toggle="toc"]').each(function(i, el) { + var $nav = $(el); + Toc.init($nav); + }); + }); +})(); diff --git a/docs/index.html b/docs/index.html index 763ab389..0426f362 100644 --- a/docs/index.html +++ b/docs/index.html @@ -6,19 +6,19 @@ Create Interactive Graphics Related to Clinical Trial Safety • safetyGraphics - - - - + + + + + - - +
    - -
    +

    R build status

    +
    -

    The safetyGraphics package provides a framework for evaluation of clinical trial safety in R. It includes several safety-focused visualizations to empower clinical data monitoring. Chief among these is the Hepatic Explorer, based on the Evaluation of the Drug-Induced Serious Hepatotoxicity (eDish) visualization. A demo of the Hepatic Explorer interactive graphic is available here and is shown below.

    -

    This package is being built in conjunction with the hep-explorer javascript library.

    +

    The {safetyGraphics} package provides a framework for the evaluation of clinical trial safety data in R using a flexible data pipeline. The package includes a shiny application that allows users to explore safety data using a series of interactive graphics, including the hepatic safety explorer shown below. The package has been developed as part of the Interactive Safety Graphics (ISG) workstream of the ASA Biopharm-DIA Safety Working Group.

    edishgif

    -
    +

    -Usage

    -

    Users can interactively explore their data with a shiny application or create standalone interactive charts.

    -
    -

    -Shiny application

    -

    The Shiny app provides a simple interface for:

    -
      -
    • Loading data
    • -
    • Customizing settings and data mappings
    • -
    • Viewing and exporting the interactive graphics
    • -
    -
    devtools::install_github("SafetyGraphics/safetyGraphics")
    -library("safetyGraphics")
    -safetyGraphicsApp() #open the shiny application
    -
    -
    -

    -Standalone charts

    -

    Users can also initialize customized standalone charts with a few lines of code.

    -
    devtools::install_github("safetyGraphics/safetyGraphics")
    -library("safetyGraphics")
    -
    -settings <- list(
    -  id_col = "USUBJID",
    -  value_col = "AVAL",
    -  measure_col = "PARAM",
    -  visit_col = "VISIT",
    -  visitn_col = "VISITNUM",
    -  studyday_col = "ADY",
    -  normal_col_low = "A1LO",
    -  normal_col_high = "A1HI",
    -  measure_values = list(ALT = "Alanine Aminotransferase (U/L)",
    -                        AST = "Aspartate Aminotransferase (U/L)",
    -                        TB = "Bilirubin (umol/L)",
    -                        ALP = "Alkaline Phosphatase (U/L)")
    -  )
    -
    -chartRenderer(data=adlbc, settings=settings, chart="hepexplorer")
    +Using the app

    +

    A demo of the app using sample data is available here or can be initialized as follows:

    +
    +devtools::install_github("SafetyGraphics/safetyGraphics")
    +library("safetyGraphics")
    +safetyGraphicsApp() #open the shiny application
    +

    The most common workflow is for a user to initialize the app with their data, adjust settings as needed, and view the interactive charts. Finally, the user can share any chart by exporting its source code or by generating a self-contained, fully reproducible report that can be shared with others.

    +

    Instructions for loading study data are provided in the introductory vignette and more complex customizations are provided in the cookbook vignette.

    +
    +

    +Charts

    +

    The app is built to support a wide variety of chart types including static plots (e.g. from {ggplot2}), shiny modules, {htmlwidgets} and even static outputs like RTFs. Several pre-configured charts are included in the companion {safetyCharts} R Package, and are available by default in the app. Other charts can be added using the process descibed in this vignette.

    -
    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/news/index.html b/docs/news/index.html index ce95a77e..5868715f 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -8,23 +8,29 @@ Changelog • safetyGraphics + - + - + + - + + + + + - - + + - + - - + + @@ -32,10 +38,12 @@ + + @@ -49,7 +57,7 @@ - +
    @@ -71,33 +79,38 @@ -