Introduction
This vignette contains sample code showing how to use the Good
Statistical Monitoring gsm package using sample data from
{clindata}
.
For more information on the gsm package see the package homepage.
Setup and Installation
Run the following:
## Install devtools
install.packages('devtools')
## Install and load sample raw data
devtools::install_github("Gilead-BioStats/clindata", ref = "main")
library(clindata)
## Install and load gsm
devtools::install_github("Gilead-BioStats/gsm", ref = "main")
library(gsm)
Example 1 - Adverse Events Metric - Scripted
This example uses the standard {gsm} analysis workflows to creates site-level Adverse Event scripts. See the Data Analysis Vignette for more detail.
- Example 1.1 calculates the Site-level AE rates.
- Example 1.2 adds a filter to include only Serious Adverse Events (SAEs) and implements pipes to run through the workflow.
- Example 1.3 generates bar charts showing SAE rates and z-scores by study.
- Example 1.4 generates a scatter plot with confidence bound for SAE rates.
#### Example 1.1 - Generate an Adverse Event Metric using the standard {gsm} workflow
dfInput <- Input_Rate(
dfSubjects= clindata::rawplus_dm,
dfNumerator= clindata::rawplus_ae,
dfDenominator = clindata::rawplus_dm,
strSubjectCol = "subjid",
strGroupCol = "siteid",
strNumeratorMethod= "Count",
strDenominatorMethod= "Sum",
strDenominatorCol= "timeonstudy"
)
dfTransformed <- Transform_Rate(dfInput)
dfAnalyzed <- Analyze_NormalApprox(dfTransformed, strType = "rate")
dfFlagged <- Flag_NormalApprox(dfAnalyzed, vThreshold = c(-3,-2,2,3))
dfSummarized <- Summarize(dfFlagged)
table(dfSummarized$Flag)
#### Example 1.2 - Make an SAE Metric by adding a filter. Also works with pipes.
SAE_KRI <- Input_Rate(
dfSubjects= clindata::rawplus_dm,
dfNumerator= clindata::rawplus_ae %>% filter(aeser=="Y"),
dfDenominator = clindata::rawplus_dm,
strSubjectCol = "subjid",
strGroupCol = "siteid",
strNumeratorMethod= "Count",
strDenominatorMethod= "Sum",
strDenominatorCol= "timeonstudy"
) %>%
Transform_Rate %>%
Analyze_NormalApprox(strType = "rate") %>%
Flag_NormalApprox(vThreshold = c(-3,-2,2,3)) %>%
Summarize
table(SAE_KRI$Flag)
### Example 1.3 - Visualize Metric distribution using Bar Charts using provided htmlwidgets
labels <- list(
Metric= "Serious Adverse Event Rate",
Numerator= "Serious Adverse Events",
Denominator= "Days on Study"
)
Widget_BarChart(dfResults = SAE_KRI, lMetric=labels, strOutcome="Metric")
Widget_BarChart(dfResults = SAE_KRI, lMetric=labels, strOutcome="Score")
Widget_BarChart(dfResults = SAE_KRI, lMetric=labels, strOutcome="Numerator")
### Example 1.4 - Create Scatter plot with confidence bounds
dfBounds <- Analyze_NormalApprox_PredictBounds(SAE_KRI, vThreshold = c(-3,-2,2,3))
Widget_ScatterPlot(SAE_KRI, lMetric = labels, dfBounds = dfBounds)
Example 2 - Adverse Events Metrics - Workflow
This examples introduces YAML workflows to re-generate the same results as in Example 1 via a reusable pipeline. See the Data Model Vignette for more detail.
- Example 2.1 runs the AE KRI workflow.
- Example 2.2 updates the metadata to run country-level metrics.
- Example 2.3 adds a filtering step to the workflow to generate the SAE metric.
#### Example 2.1 - Configurable Adverse Event Workflow
# Define YAML workflow
AE_workflow <- read_yaml(text=
'meta:
File: AE_KRI
GroupLevel: Site
Metric: Adverse Event Rate
Numerator: Adverse Events
Denominator: Days on Study
Model: Normal Approximation
Score: Adjusted Z-Score
Type: rate
Threshold: -2,-1,2,3
nMinDenominator: 30
steps:
- name: ParseThreshold
output: vThreshold
params:
strThreshold: Threshold
- name: Input_Rate
output: dfInput
params:
dfSubjects: dfSubjects
dfNumerator: dfAE
dfDenominator: dfSubjects
strSubjectCol: subjid
strGroupCol: invid
strGroupLevel: GroupLevel
strNumeratorMethod: Count
strDenominatorMethod: Sum
strDenominatorCol: timeonstudy
- name: Transform_Rate
output: dfTransformed
params:
dfInput: dfInput
- name: Analyze_NormalApprox
output: dfAnalyzed
params:
dfTransformed: dfTransformed
strType: Type
- name: Flag_NormalApprox
output: dfFlagged
params:
dfAnalyzed: dfAnalyzed
vThreshold: vThreshold
- name: Summarize
output: dfSummary
params:
dfFlagged: dfFlagged
nMinDenominator: nMinDenominator
')
# Run the workflow
AE_data <-list(
dfSubjects= clindata::rawplus_dm,
dfAE= clindata::rawplus_ae
)
AE_KRI <- RunWorkflow(lWorkflow = AE_workflow, lData = AE_data )
# Create Barchart from workflow
Widget_BarChart(dfResults = AE_KRI$dfSummary, lMetric = AE_workflow$meta)
#### Example 2.2 - Run Country-Level Metric
AE_country_workflow <- AE_workflow
AE_country_workflow$meta$GroupLevel <- "Country"
AE_country_workflow$steps[[2]]$params$strGroupCol <- "country"
AE_country_KRI <- RunWorkflow(lWorkflow = AE_country_workflow, lData = AE_data )
Widget_BarChart(dfResults = AE_country_KRI$dfSummary, lMetric = AE_country_workflow$meta)
#### Example 2.3 - Create SAE workflow
# Tweak AE workflow metadata
SAE_workflow <- AE_workflow
SAE_workflow$meta$File <- "SAE_KRI"
SAE_workflow$meta$Metric <- "Serious Adverse Event Rate"
SAE_workflow$meta$Numerator <- "Serious Adverse Events"
# Add a step to filter out non-serious AEs `RunQuery`
filterStep <- list(list(
name = "RunQuery",
output = "dfAE",
params= list(
df= "dfAE",
strQuery = "SELECT * FROM df WHERE aeser = 'Y'"
))
)
SAE_workflow$steps <- SAE_workflow$steps %>% append(filterStep, after=0)
# Run the updated workflow
SAE_KRI <- RunWorkflow(lWorkflow = SAE_workflow, lData = AE_data )
Widget_BarChart(dfResults = SAE_KRI$dfSummary, lMetric = SAE_workflow$meta)
Example 3 - Study-Level Reporting Workflows
This example extends the previous examples to generate charts and reports for multiple KRIs. See the Data Reporting Vignette for more detail.
- Example 3.1 steps through several workflows to generate a report for all 12 standard site-level KRIs.
- Example 3.2 combines the analytics and reporting steps into a single workflow.
- Example 3.3 generates a report for all 12 standard country-level KRIs.
-
Example 3.4 generates a report incorporating
multiple timepoints using the sample
reporting
data saved as part of {gsm}.
#### 3.1 - Create a KRI Report using 12 standard metrics with multiple workflows
# Step 1 - Create Mapped Data - filter/map raw data
lData <- list(
dfSUBJ = clindata::rawplus_dm,
dfAE = clindata::rawplus_ae,
dfPD = clindata::ctms_protdev,
dfLB = clindata::rawplus_lb,
dfSTUDCOMP = clindata::rawplus_studcomp,
dfSDRGCOMP = clindata::rawplus_sdrgcomp %>% dplyr::filter(.data$phase == 'Blinded Study Drug Completion'),
dfDATACHG = clindata::edc_data_points,
dfDATAENT = clindata::edc_data_pages,
dfQUERY = clindata::edc_queries,
dfENROLL = clindata::rawplus_enroll
)
mapping_wf <- MakeWorkflowList(strNames = "data_mapping")
mapped <- RunWorkflows(mapping_wf, lData, bKeepInputData=TRUE)
# Step 2 - Create Analysis Data - Generate 12 KRIs
kri_wf <- MakeWorkflowList(strNames = "kri")
kris <- RunWorkflows(kri_wf, mapped)
# Step 3 - Create Reporting Data - Import Metadata and stack KRI Results
lReporting_Input <- list(
ctms_site = clindata::ctms_site,
ctms_study = clindata::ctms_study,
dfEnrolled = mapped$dfEnrolled,
lWorkflows = kri_wf,
lAnalysis = kris,
dSnapshotDate = Sys.Date(),
strStudyID = "ABC-123"
)
reporting_wf <- MakeWorkflowList(strNames = "reporting")
reporting <- RunWorkflows(reporting_wf, lReporting_Input)
# Step 4 - Generate Reports - Create Charts + Report
wf_reports <- MakeWorkflowList(strNames = "reports")
lReports <- RunWorkflows(wf_reports, reporting)
#### 3.2 - Create a KRI Report using 12 standard metrics with a single composite workflow
lData <- list(
# Raw Data
dfSUBJ = clindata::rawplus_dm,
dfAE = clindata::rawplus_ae,
dfPD = clindata::ctms_protdev,
dfLB = clindata::rawplus_lb,
dfSTUDCOMP = clindata::rawplus_studcomp,
dfSDRGCOMP = clindata::rawplus_sdrgcomp %>% dplyr::filter(.data$phase == 'Blinded Study Drug Completion'),
dfDATACHG = clindata::edc_data_points,
dfDATAENT = clindata::edc_data_pages,
dfQUERY = clindata::edc_queries,
dfENROLL = clindata::rawplus_enroll,
# CTMS data
ctms_site = clindata::ctms_site,
ctms_study = clindata::ctms_study,
# SnapshotDate and StudyID
dSnapshotDate = Sys.Date(),
strStudyID = "ABC-123",
# Metrics
Metrics = 'kri'
)
ss_wf <- MakeWorkflowList(strNames = "snapshot")
snapshot <- RunWorkflows(ss_wf, lData, bKeepInputData = TRUE)
#### 3.3 - Create a country-level KRI Report
lData$Metrics <- 'cou'
country_snapshot <- RunWorkflows(ss_wf, lData, bKeepInputData = TRUE)
#### 3.4 Site-Level KRI Report with multiple SnapshotDate
lCharts <- MakeCharts(
dfResults = gsm::reportingResults,
dfGroups = gsm::reportingGroups,
dfMetrics = gsm::reportingMetrics,
dfBounds = gsm::reportingBounds
)
kri_report_path <- Report_KRI(
lCharts = lCharts,
dfResults = gsm::reportingResults,
dfGroups = gsm::reportingGroups,
dfMetrics = gsm::reportingMetrics
)