--- title: "Cookbook" author: "Jeremy Wildfire" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Cookbook} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- # Cookbook Vignette This vignette contains a series of examples showing how to initialize the safetyGraphics Shiny app in different scenarios. # Overview Most of the customization shown here is done by changing 4 key parameters in the `safetyGraphicsApp()` function: - `domainData` – Domain-level Study Data - `mapping` – List identifying the key columns/fields in your data - `charts` – Define the charts used in the app. - `meta` – Metadata table with info about required columns and fields `domainData` and `mapping` generally change for every study, while `charts` and `meta` can generally be re-used across many studies. The examples here are generally provided with minimal explanation. For a more detailed discussion of the logic behind these examples see the [Chart Configuration Vignette](ChartConfiguration.html) or our [2021 R/Pharma Workshop](https://github.com/SafetyGraphics/RPharma2021-Workshop) # 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() ``` # Loading Custom Data The next several examples focus on study-specific customizations for loading and mapping data. ## Example 2 - SDTM Data The data passed in to the safetyGraphics app can be customized using the `domainData` 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 - Loading other data formats Users can also import data from a wide-variety of data formats using standard R workflows and then initialize the app. The example below initializes the app using lab data saved as a sas transport file (.xpt) ``` xptLabs <- haven::read_xpt('https://github.com/phuse-org/phuse-scripts/blob/master/data/adam/cdiscpilot01/adlbc.xpt?raw=true') safetyGraphics::safetyGraphicsApp(domainData=list(labs=xptLabs)) ``` ## Example 5 - 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 6 - Non-standard data #2 For a more realistic example, consider [this labs data set (csv)](https://raw.githubusercontent.com/SafetyGraphics/SafetyGraphics.github.io/master/pilot/SampleData_NoStandard.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. # Custom Charts The remaining examples focus on creating charts that are reusable across many studies. For extensive details on adding and customizing different types of charts, see this [vignette](ChartConfiguration.html). ## Example 7 - 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 8 - Edit Default Charts Users can also make modifications to the default charts by editing the list of charts directly. ``` charts <- makeChartConfig() #gets charts from safetyCharts pacakge by default charts$aeTimelines$label <- "An AMAZING timeline" safetyGraphicsApp(charts=charts) ``` ## Example 9 - Add Hello World Custom Chart This example creates a simple "hello world" chart that is not linked to the data or mapping loaded in the app. ``` 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)) ``` ## Example 10 - Add a custom chart using data and settings The code below adds a new simple chart showing participants' age distribution by sex. ``` ageDist <- function(data, settings){ p<-ggplot(data = data, aes(x=.data[[settings$age_col]])) + geom_histogram() + facet_wrap(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) ``` ## Example 11 - Create a Hello World Data Domain and Chart Here we extend example 9 to include the creating of a new data domain with custom metadata, which is bound to the chart object as `chart$meta`. See `?makeMeta` for more detail about the creation of custom metadata. ``` helloMeta <- tribble( ~text_key, ~domain, ~label, ~standard_hello, ~description, "x_col", "hello", "x position", "x", "x position for points in hello world chart", "y_col", "hello", "y position", "y", "y position for points in hello world chart" ) %>% mutate( col_key = text_key, type="column" ) helloData<-data.frame(x=runif(50, -1,1), y=runif(50, -1,1)) helloWorld <- function(data, settings){ plot(-1:1, -1:1) text(data[[settings$x_col]], data[[settings$y_col]], "Custom Hello Domain!") } helloChart<-prepareChart( list( env="safetyGraphics", name="HelloWorld", label="Hello World!", type="plot", domain="hello", workflow=list( main="helloWorld" ), meta=helloMeta ) ) charts <- makeChartConfig() charts$hello <- helloChart #Easy to combine default and custom charts data<-list( labs=safetyData::adam_adlbc, aes=safetyData::adam_adae, dm=safetyData::adam_adsl, hello=helloData ) #no need to specify meta since safetyGraphics::makeMeta() will generate the correct list by default. safetyGraphicsApp( domainData=data, charts=charts ) ``` ## Example 13 - Create an ECG Data Domain & Chart This example defines a custom ECG data domain and adapts an existing chart for usage there. See [this PR](https://github.com/SafetyGraphics/safetyCharts/pull/90) for a full implementation of the ECG domain in safetyCharts. ``` adeg <- readr::read_csv("https://physionet.org/files/ecgcipa/1.0.0/adeg.csv?download") ecg_meta <-tibble::tribble( ~text_key, ~domain, ~label, ~description, ~standard_adam, ~standard_sdtm, "id_col", "custom_ecg", "ID column", "Unique subject identifier variable name.", "USUBJID", "USUBJID", "value_col", "custom_ecg", "Value column", "QT result variable name.", "AVAL", "EGSTRESN", "measure_col", "custom_ecg", "Measure column", "QT measure variable name", "PARAM", "EGTEST", "studyday_col", "custom_ecg", "Study Day column", "Visit day variable name", "ADY", "EGDY", "visit_col", "custom_ecg", "Visit column", "Visit variable name", "ATPT", "EGTPT", "visitn_col", "custom_ecg", "Visit number column", "Visit number variable name", "ATPTN", NA, "period_col", "custom_ecg", "Period column", "Period variable name", "APERIOD", NA, "unit_col", "custom_ecg", "Unit column", "Unit of measure variable name", "AVALU", "EGSTRESU" ) %>% mutate( col_key = text_key, type="column" ) qtOutliers<-prepare_chart(read_yaml('https://raw.githubusercontent.com/SafetyGraphics/safetyCharts/dev/inst/config/safetyOutlierExplorer.yaml') ) qtOutliers$label <- "QT Outlier explorer" qtOutliers$domain <- "custom_ecg" qtOutliers$meta <- ecg_meta safetyGraphicsApp( meta=ecg_meta, domainData=list(custom_ecg=adeg), charts=list(qtOutliers) ) ```