From 50e536186af50af321bded186716749ab6c5fd6e Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Wed, 20 Sep 2023 16:57:33 +0000 Subject: [PATCH 01/11] Update index categories --- book/tlg-index.qmd | 252 ++++++++++++++++++++++++++++----------------- 1 file changed, 155 insertions(+), 97 deletions(-) diff --git a/book/tlg-index.qmd b/book/tlg-index.qmd index 51b0c6ca53..a7d87373a0 100644 --- a/book/tlg-index.qmd +++ b/book/tlg-index.qmd @@ -8,45 +8,116 @@ toc-depth: 4 ### **Tables** -#### Adverse Events +#### ADA + +        [ADAT01 -- Baseline Prevalence and Incidence of Treatment Emergent ADA](./tables/ada/adat01.qmd) + +        [ADAT02 -- Summary of Patients with Treatment-Induced ADA](./tables/ada/adat02.qmd) + +        [ADAT03 -- Summary of Serum Concentrations at Timepoints Where ADA Samples Were Collected and Analyzed](./tables/ada/adat03.qmd) + +        [ADAT04A -- Baseline Prevalence and Incidence of Treatment Emergent NAbs](./tables/ada/adat04a.qmd) + +        [ADAT04B -- Baseline Prevalence and Incidence of NAbs](./tables/ada/adat04b.qmd) -        [AET01 -- Safety Summary](./tables/adverse-events/aet01.qmd) + +#### Adverse Events         [AET01_AESI -- Safety Summary (Adverse Events of Special Interest)](./tables/adverse-events/aet01_aesi.qmd) -        [AET02 -- Adverse Events](./tables/adverse-events/aet02.qmd) +        [AET01 -- Safety Summary](./tables/adverse-events/aet01.qmd)         [AET02_SMQ -- Adverse Events by Standardized MedDRA Query](./tables/adverse-events/aet02_smq.qmd) -        [AET03 -- Adverse Events by Greatest Intensity](./tables/adverse-events/aet03.qmd) +        [AET02 -- Adverse Events](./tables/adverse-events/aet02.qmd) -        [AET04 -- Adverse Events by Highest NCI CTCAE Grade](./tables/adverse-events/aet04.qmd) +        [AET03 -- Adverse Events by Greatest Intensity](./tables/adverse-events/aet03.qmd)         [AET04_PI -- Adverse Events Reported in $\geq$ 10% of Patients by Highest NCI CTCAE Grade](./tables/adverse-events/aet04_pi.qmd) -        [AET05 -- Adverse Event Rate Adjusted for Patient-Years at Risk -- First Occurrence](./tables/adverse-events/aet05.qmd) +        [AET04 -- Adverse Events by Highest NCI CTCAE Grade](./tables/adverse-events/aet04.qmd)         [AET05_ALL -- Adverse Event Rate Adjusted for Patient-Years at Risk -- All Occurrences](./tables/adverse-events/aet05_all.qmd) -        [AET06 -- Adverse Events by Baseline Characteristic](./tables/adverse-events/aet06.qmd) +        [AET05 -- Adverse Event Rate Adjusted for Patient-Years at Risk -- First Occurrence](./tables/adverse-events/aet05.qmd)         [AET06_SMQ -- Adverse Events by Baseline Characteristic, by SMQ and Preferred Term](./tables/adverse-events/aet06_smq.qmd) -        [AET07 -- Adverse Events Resulting in Death](./tables/adverse-events/aet07.qmd) +        [AET06 -- Adverse Events by Baseline Characteristic](./tables/adverse-events/aet06.qmd) -        [AET09 -- Adverse Events Related to Study Drug](./tables/adverse-events/aet09.qmd) +        [AET07 -- Adverse Events Resulting in Death](./tables/adverse-events/aet07.qmd)         [AET09_SMQ -- Adverse Events Related to Study Drug by Standardized MedDRA Query](./tables/adverse-events/aet09_smq.qmd) +        [AET09 -- Adverse Events Related to Study Drug](./tables/adverse-events/aet09.qmd) +         [AET10 -- Most Common ($\geq$ 5%) Adverse Events](./tables/adverse-events/aet10.qmd) +#### Concomitant Medications + +        [CMT01 -- Concomitant Medications (GNEDrug Legacy Coding)](./tables/con-med/cmt01.qmd) + +        [CMT01A -- Concomitant Medications by Medication Class and Preferred Name](./tables/con-med/cmt01a.qmd) + +        [CMT01B -- Concomitant Medications by Medication Class and Preferred Name](./tables/con-med/cmt01b.qmd) + +        [CMT02_PT -- Concomitant Medications by Preferred Name (WHODrug Coding)](./tables/con-med/cmt02_pt.qmd) + + +#### Deaths + +        [DTHT01 -- Deaths](./tables/deaths/dtht01.qmd) + + +#### Demography + +        [DMT01 -- Demographics and Baseline Characteristics](./tables/demography/dmt01.qmd) + + +#### Disclosures + +        [DISCLOSUREST01 -- Disclosures Outputs](./tables/disclosures/disclosurest01.qmd) + +        [EUDRAT01 -- Non-Serious Adverse Events Reported in $\geq$ 5% of Patients in Any Treatment Group -- Patients and Events](./tables/disclosures/eudrat01.qmd) + +        [EUDRAT02 -- Serious Adverse Events, Fatal Serious Adverse Events, and Serious Adverse Events Related to Study Medication](./tables/disclosures/eudrat02.qmd) + + +#### Disposition + +        [DST01 -- Patient Disposition](./tables/disposition/dst01.qmd) + +        [PDT01 -- Major Protocol Deviations](./tables/disposition/pdt01.qmd) + +        [PDT02 -- Major Protocol Deviations Related to Epidemic/Pandemic](./tables/disposition/pdt02.qmd) + + +#### ECG + +        [EGT01 -- ECG Results and Change from Baseline by Visit](./tables/ecg/egt01.qmd) + +        [EGT02 -- ECG Abnormalities (EGT02_1 & EGT02_2)](./tables/ecg/egt02.qmd) + +        [EGT03 -- Shift Table of ECG Interval Data -- Baseline Versus Minimum/Maximum Post-Baseline](./tables/ecg/egt03.qmd) + +        [EGT04 -- Shift Table of Qualitative ECG Assessments](./tables/ecg/egt04.qmd) + +        [EGT05_QTCAT -- ECG Actual Values and Changes from Baseline by Visit](./tables/ecg/egt05_qtcat.qmd) + + #### Efficacy         [AOVT01 -- ANCOVA for Multiple End Points](./tables/efficacy/aovt01.qmd) +        [AOVT02 -- ANCOVA with Single End Point and Customized Table](./tables/efficacy/aovt02.qmd) + +        [AOVT03 -- ANCOVA with Consideration of Interaction](./tables/efficacy/aovt03.qmd) +         [CFBT01 -- Efficacy Data and Change from Baseline by Visit](./tables/efficacy/cfbt01.qmd) +        [CMHT01 -- Cochran-Mantel-Haenszel (CMH) Summary](./tables/efficacy/cmht01.qmd) +         [COXT01 -- Cox Regression](./tables/efficacy/coxt01.qmd)         [COXT02 -- Multivariable Cox Regression](./tables/efficacy/coxt02.qmd) @@ -59,11 +130,20 @@ toc-depth: 4         [ONCT05 -- Objective Response Rate by Subgroup](./tables/efficacy/onct05.qmd) +        [RATET01 -- Event Rate Summary for Recurrent Events](./tables/efficacy/ratet01.qmd) + +        [RBMIT01 -- Tables for RBMI](./tables/efficacy/rbmit01.qmd) +         [RSPT01 -- Best Overall Response](./tables/efficacy/rspt01.qmd)         [TTET01 -- Time-To-Event Summary](./tables/efficacy/ttet01.qmd) +#### Exposure + +        [EXT01 -- Study Drug Exposure Table](./tables/exposure/ext01.qmd) + + #### Lab Results         [LBT01 -- Laboratory Test Results and Change from Baseline by Visit](./tables/lab-results/lbt01.qmd) @@ -84,18 +164,18 @@ toc-depth: 4         [LBT09 -- Liver Laboratory Tests -- Patients with Elevated Post-Baseline AST or ALT Levels](./tables/lab-results/lbt09.qmd) -        [LBT10 -- Liver Laboratory Tests -- Patients with Elevated Post-Baseline AST or ALT Levels at Two Consecutive Visits (with Respect to ULN)](./tables/lab-results/lbt10.qmd) -         [LBT10_BL -- Liver Laboratory Tests -- Patients with Elevated Post-Baseline AST or ALT Levels at Two Consecutive Visits (with Respect to Baseline)](./tables/lab-results/lbt10_bl.qmd) -        [LBT11 -- Time to First Increase in Liver Laboratory Test Result Meeting Hy's Law Laboratory Critieria (with Respect to ULN)](./tables/lab-results/lbt11.qmd) +        [LBT10 -- Liver Laboratory Tests -- Patients with Elevated Post-Baseline AST or ALT Levels at Two Consecutive Visits (with Respect to ULN)](./tables/lab-results/lbt10.qmd)         [LBT11_BL -- Time to First Increase in Liver Laboratory Test Result Meeting Hy's Law Laboratory Critieria (with Respect to Baseline)](./tables/lab-results/lbt11_bl.qmd) -        [LBT12 -- Liver Laboratory Tests by Time on Treatment -- Patients with Elevated Post-Baseline AST or ALT Levels (with Respect to ULN)](./tables/lab-results/lbt12.qmd) +        [LBT11 -- Time to First Increase in Liver Laboratory Test Result Meeting Hy's Law Laboratory Critieria (with Respect to ULN)](./tables/lab-results/lbt11.qmd)         [LBT12_BL -- Liver Laboratory Tests by Time on Treatment -- Patients with Elevated Post-Baseline AST or ALT Levels (with Respect to Baseline)](./tables/lab-results/lbt12_bl.qmd) +        [LBT12 -- Liver Laboratory Tests by Time on Treatment -- Patients with Elevated Post-Baseline AST or ALT Levels (with Respect to ULN)](./tables/lab-results/lbt12.qmd) +         [LBT13 -- NCI CTCAE Grade Laboratory Abnormalities by Visit and Baseline Grade](./tables/lab-results/lbt13.qmd)         [LBT14 -- Laboratory Test Results Shift Table -- Highest NCI CTCAE Grade Post-Baseline by Baseline NCI CTCAE Grade](./tables/lab-results/lbt14.qmd) @@ -103,17 +183,12 @@ toc-depth: 4         [LBT15 -- Laboratory Test Shifts to NCI CTCAE Grade 3-4 Post-Baseline](./tables/lab-results/lbt15.qmd) -#### Pharmacokinetic - -        [ADAT01 -- Baseline Prevalence and Incidence of Treatment Emergent ADA](./tables/pharmacokinetic/adat01.qmd) +#### Medical History -        [ADAT02 -- Summary of Patients with Treatment-Induced ADA](./tables/pharmacokinetic/adat02.qmd) +        [MHT01 -- Medical History](./tables/medical-history/mht01.qmd) -        [ADAT03 -- Summary of Serum Concentrations at Timepoints Where ADA Samples Were Collected and Analyzed](./tables/pharmacokinetic/adat03.qmd) -        [ADAT04A -- Baseline Prevalence and Incidence of Treatment Emergent NAbs](./tables/pharmacokinetic/adat04a.qmd) - -        [ADAT04B -- Baseline Prevalence and Incidence of NAbs](./tables/pharmacokinetic/adat04b.qmd) +#### Pharmacokinetic         [PKCT01 -- Summary Concentration Table](./tables/pharmacokinetic/pkct01.qmd) @@ -134,145 +209,136 @@ toc-depth: 4         [PKPT11 -- Pharmacokinetic Parameter Estimated Ratios of Geometric Means and 90% Confidence Intervals for AUC and CMAX](./tables/pharmacokinetic/pkpt11.qmd) -#### Safety +#### Risk Management Plan -        [CMT01 -- Concomitant Medications (GNEDrug Legacy Coding)](./tables/safety/cmt01.qmd) +        [RMPT01 -- Duration of Exposure for Risk Management Plan](./tables/rmp/rmpt01.qmd) -        [CMT01A -- Concomitant Medications by Medication Class and Preferred Name](./tables/safety/cmt01a.qmd) +        [RMPT03 -- Extent of Exposure by Age Group and Gender for Risk Management Plan](./tables/rmp/rmpt03.qmd) -        [CMT01B -- Concomitant Medications by Medication Class and Preferred Name](./tables/safety/cmt01b.qmd) +        [RMPT04 -- Extent of Exposure by Ethnic Origin for Risk Management Plan](./tables/rmp/rmpt04.qmd) -        [CMT02_PT -- Concomitant Medications by Preferred Name (WHODrug Coding)](./tables/safety/cmt02_pt.qmd) +        [RMPT05 -- Extent of Exposure by Race for Risk Management Plan](./tables/rmp/rmpt05.qmd) -        [DMT01 -- Demographics and Baseline Characteristics](./tables/safety/dmt01.qmd) +        [RMPT06 -- Seriousness, Outcomes, Severity, Frequency with 95% CI for Risk Management Plan](./tables/rmp/rmpt06.qmd) -        [DST01 -- Patient Disposition](./tables/safety/dst01.qmd) -        [DTHT01 -- Deaths](./tables/safety/dtht01.qmd) +#### Safety -        [EGT01 -- ECG Results and Change from Baseline by Visit](./tables/safety/egt01.qmd) +        [ENTXX -- Enrollment Variants](./tables/safety/enrollment01.qmd) -        [EGT02 -- ECG Abnormalities (EGT02_1 & EGT02_2)](./tables/safety/egt02.qmd) -        [EGT03 -- Shift Table of ECG Interval Data -- Baseline Versus Minimum/Maximum Post-Baseline](./tables/safety/egt03.qmd) +#### Vital Signs -        [EGT04 -- Shift Table of Qualitative ECG Assessments](./tables/safety/egt04.qmd) +        [VST01 -- Vital Sign Results and Change from Baseline by Visit](./tables/vital-signs/vst01.qmd) -        [EGT05_QTCAT -- ECG Actual Values and Changes from Baseline by Visit](./tables/safety/egt05_qtcat.qmd) +        [VST02 -- Vital Sign Abnormalities](./tables/vital-signs/vst02.qmd) -        [ENTXX -- Enrollment Variants](./tables/safety/enrollment01.qmd) -        [EUDRAT01 -- Non-Serious Adverse Events Reported in $\geq$ 5% of Patients in Any Treatment Group -- Patients and Events](./tables/safety/eudrat01.qmd) +------------------------------------------------------------------------ + +### **Listings** -        [EUDRAT02 -- Serious Adverse Events, Fatal Serious Adverse Events, and Serious Adverse Events Related to Study Medication](./tables/safety/eudrat02.qmd) +#### ADA -        [EXT01 -- Study Drug Exposure Table](./tables/safety/ext01.qmd) +        [ADAL02 -- Listing of Anti-Drug Antibody Data for Treatment Emergent ADA Positive Patients](./listings/ada/adal02.qmd) -        [MHT01 -- Medical History](./tables/safety/mht01.qmd) -        [PDT01 -- Major Protocol Deviations](./tables/safety/pdt01.qmd) +#### Adverse Events -        [PDT02 -- Major Protocol Deviations Related to Epidemic/Pandemic](./tables/safety/pdt02.qmd) +        [AEL01_NOLLT -- Listing of Preferred Terms and Investigator-Specified Adverse Event Terms](./listings/adverse-events/ael01_nollt.qmd) -        [VST01 -- Vital Sign Results and Change from Baseline by Visit](./tables/safety/vst01.qmd) +        [AEL01 -- Listing of Preferred Terms, Lowest Level Terms, and Investigator-Specified Adverse Event Terms](./listings/adverse-events/ael01.qmd) -        [VST02 -- Vital Sign Abnormalities](./tables/safety/vst02.qmd) +        [AEL02_ED -- Listing of Adverse Events (for Early Development Studies)](./listings/adverse-events/ael02_ed.qmd) +        [AEL02 -- Listing of Adverse Events](./listings/adverse-events/ael02.qmd) -#### Other +        [AEL03 -- Listing of Serious Adverse Events](./listings/adverse-events/ael03.qmd) -        [AOVT02 -- ANCOVA with Single End Point and Customized Table](./tables/other/aovt02.qmd) +        [AEL04 -- Listing of Patient Deaths](./listings/adverse-events/ael04.qmd) -        [AOVT03 -- ANCOVA with Consideration of Interaction](./tables/other/aovt03.qmd) -        [CMHT01 -- Cochran-Mantel-Haenszel (CMH) Summary](./tables/other/cmht01.qmd) +#### Concomitant Medications -        [DISCLOSUREST01 -- Disclosures Outputs](./tables/other/disclosurest01.qmd) +        [CML01 -- Listing of Previous and Concomitant Medications](./listings/con-med/cml01.qmd) -        [RATET01 -- Event Rate Summary for Recurrent Events](./tables/other/ratet01.qmd) +        [CML02A_GL -- Listing of Concomitant Medication Class Level 2, Preferred Name, and Investigator-Specified Terms](./listings/con-med/cml02a_gl.qmd) -        [RBMIT01 -- Tables for RBMI](./tables/other/rbmit01.qmd) +        [CML02B_GL -- Listing of Concomitant Medication Class, Preferred Name, and Investigator-Specified Terms](./listings/con-med/cml02b_gl.qmd) -        [RMPT01 -- Duration of Exposure for Risk Management Plan](./tables/other/rmpt01.qmd) -        [RMPT03 -- Extent of Exposure by Age Group and Gender for Risk Management Plan](./tables/other/rmpt03.qmd) +#### Disposition -        [RMPT04 -- Extent of Exposure by Ethnic Origin for Risk Management Plan](./tables/other/rmpt04.qmd) +        [DSL01 -- Listing of Patients with Study Drug Withdrawn Due to Adverse Events](./listings/disposition/dsl01.qmd) -        [RMPT05 -- Extent of Exposure by Race for Risk Management Plan](./tables/other/rmpt05.qmd) +        [DSL02 -- Listing of Patients Who Discontinued Early from Study](./listings/disposition/dsl02.qmd) -        [RMPT06 -- Seriousness, Outcomes, Severity, Frequency with 95% CI for Risk Management Plan](./tables/other/rmpt06.qmd) +#### Development Safety Update Report ------------------------------------------------------------------------- +        [DSUR4 -- Listing of Patients Who Died During Reporting Period](./listings/dsur/dsur4.qmd) -### **Listings** -#### Pharmacokinetic +#### ECG -        [ADAL02 -- Listing of Anti-Drug Antibody Data for Treatment Emergent ADA Positive Patients](./listings/pharmacokinetic/adal02.qmd) +        [EGL01 -- 'Listing of ECG Data: Safety-Evaluable Patients'](./listings/ecg/egl01.qmd) -        [PKCL01 -- Listing of Drug A Concentration by Treatment Group, Patient and Nominal Time](./listings/pharmacokinetic/pkcl01.qmd) -        [PKCL02 -- Listing of Drug A Urine Concentration and Volumes](./listings/pharmacokinetic/pkcl02.qmd) +#### Exposure -        [PKPL01 -- Listing of Drug A Plasma PK Parameters](./listings/pharmacokinetic/pkpl01.qmd) +        [EXL01 -- Listing of Exposure to Study Drug](./listings/exposure/exl01.qmd) -        [PKPL02 -- Listing of Drug A Urine PK Parameters](./listings/pharmacokinetic/pkpl02.qmd) -        [PKPL04 -- Listing of Individual Drug A AUCIFO and CMAX Ratios Following Drug A or Drug B](./listings/pharmacokinetic/pkpl04.qmd) +#### Lab Results +        [LBL01_RLS -- Listing of Laboratory Test Results Using Roche Safety Lab Standardization](./listings/lab-results/lbl01_rls.qmd) -#### Other +        [LBL01 -- Listing of Laboratory Test Results](./listings/lab-results/lbl01.qmd) -        [AEL01 -- Listing of Preferred Terms, Lowest Level Terms, and Investigator-Specified Adverse Event Terms](./listings/other/ael01.qmd) +        [LBL02A_RLS -- Listing of Laboratory Abnormalities Defined by Roche Safety Lab Standardization](./listings/lab-results/lbl02a_rls.qmd) -        [AEL01_NOLLT -- Listing of Preferred Terms and Investigator-Specified Adverse Event Terms](./listings/other/ael01_nollt.qmd) +        [LBL02A -- Listing of Laboratory Abnormalities (constant units)](./listings/lab-results/lbl02a.qmd) -        [AEL02 -- Listing of Adverse Events](./listings/other/ael02.qmd) +        [LBL02B -- Listing of Laboratory Abnormalities (variable units)](./listings/lab-results/lbl02b.qmd) -        [AEL02_ED -- Listing of Adverse Events (for Early Development Studies)](./listings/other/ael02_ed.qmd) -        [AEL03 -- Listing of Serious Adverse Events](./listings/other/ael03.qmd) +#### Medical History -        [AEL04 -- Listing of Patient Deaths](./listings/other/ael04.qmd) +        [MHL01 -- Listing of Medical History and Concurrent Diseases](./listings/medical-history/mhl01.qmd) -        [CML01 -- Listing of Previous and Concomitant Medications](./listings/other/cml01.qmd) -        [CML02A_GL -- Listing of Concomitant Medication Class Level 2, Preferred Name, and Investigator-Specified Terms](./listings/other/cml02a_gl.qmd) +#### Pharmacokinetic -        [CML02B_GL -- Listing of Concomitant Medication Class, Preferred Name, and Investigator-Specified Terms](./listings/other/cml02b_gl.qmd) +        [PKCL01 -- Listing of Drug A Concentration by Treatment Group, Patient and Nominal Time](./listings/pharmacokinetic/pkcl01.qmd) -        [DSL01 -- Listing of Patients with Study Drug Withdrawn Due to Adverse Events](./listings/other/dsl01.qmd) +        [PKCL02 -- Listing of Drug A Urine Concentration and Volumes](./listings/pharmacokinetic/pkcl02.qmd) -        [DSL02 -- Listing of Patients Who Discontinued Early from Study](./listings/other/dsl02.qmd) +        [PKPL01 -- Listing of Drug A Plasma PK Parameters](./listings/pharmacokinetic/pkpl01.qmd) -        [DSUR4 -- Listing of Patients Who Died During Reporting Period](./listings/other/dsur4.qmd) +        [PKPL02 -- Listing of Drug A Urine PK Parameters](./listings/pharmacokinetic/pkpl02.qmd) -        [EGL01 -- 'Listing of ECG Data: Safety-Evaluable Patients'](./listings/other/egl01.qmd) +        [PKPL04 -- Listing of Individual Drug A AUCIFO and CMAX Ratios Following Drug A or Drug B](./listings/pharmacokinetic/pkpl04.qmd) -        [EXL01 -- Listing of Exposure to Study Drug](./listings/other/exl01.qmd) -        [LBL01 -- Listing of Laboratory Test Results](./listings/other/lbl01.qmd) +#### Vital Signs -        [LBL01_RLS -- Listing of Laboratory Test Results Using Roche Safety Lab Standardization](./listings/other/lbl01_rls.qmd) +        [VSL01 -- 'Listing of Vital Signs: Safety-Evaluable Patients'](./listings/vital-signs/vsl01.qmd) -        [LBL02A -- Listing of Laboratory Abnormalities (constant units)](./listings/other/lbl02a.qmd) -        [LBL02A_RLS -- Listing of Laboratory Abnormalities Defined by Roche Safety Lab Standardization](./listings/other/lbl02a_rls.qmd) +------------------------------------------------------------------------ -        [LBL02B -- Listing of Laboratory Abnormalities (variable units)](./listings/other/lbl02b.qmd) +### **Graphs** -        [MHL01 -- Listing of Medical History and Concurrent Diseases](./listings/other/mhl01.qmd) +#### Efficacy -        [ONCL01 -- Listing of Individual Efficacy Data](./listings/other/oncl01.qmd) +        [FSTG01 -- Subgroup Analysis of Best Overall Response](./graphs/efficacy/fstg01.qmd) -        [VSL01 -- 'Listing of Vital Signs: Safety-Evaluable Patients'](./listings/other/vsl01.qmd) +        [FSTG02 -- Subgroup Analysis of Survival Duration](./graphs/efficacy/fstg02.qmd) +        [MMRMG01 -- Plots for Mixed-Effect Model Repeated Measures Analysis](./graphs/efficacy/mmrmg01.qmd) ------------------------------------------------------------------------- +        [MMRMG02 -- Forest Plot for Mixed-Effect Model Repeated Measures](./graphs/efficacy/mmrmg02.qmd) -### **Graphs** #### Pharmacokinetic @@ -301,19 +367,11 @@ toc-depth: 4         [CIG01 -- Confidence Interval Plot](./graphs/other/cig01.qmd) -        [FSTG01 -- Subgroup Analysis of Best Overall Response](./graphs/other/fstg01.qmd) - -        [FSTG02 -- Subgroup Analysis of Survival Duration](./graphs/other/fstg02.qmd) -         [IPPG01 -- Individual Patient Plot Over Time](./graphs/other/ippg01.qmd)         [KMG01 -- Kaplan-Meier Plot](./graphs/other/kmg01.qmd)         [LTG01 -- Lattice Plot of Laboratory Tests by Treatment Group Over Time](./graphs/other/ltg01.qmd) -        [MMRMG01 -- Plots for Mixed-Effect Model Repeated Measures Analysis](./graphs/other/mmrmg01.qmd) - -        [MMRMG02 -- Forest Plot for Mixed-Effect Model Repeated Measures](./graphs/other/mmrmg02.qmd) -         [MNG01 -- Mean Plot](./graphs/other/mng01.qmd) From 84714b1ab559e7d9ef7184b17b37fb3e5863d9c5 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Wed, 20 Sep 2023 18:04:57 +0000 Subject: [PATCH 02/11] update folder names for sidebar --- book/generate-index.R | 9 ++++--- .../cml01.qmd | 0 .../cml02a_gl.qmd | 0 .../cml02b_gl.qmd | 0 .../dsur4.qmd | 0 .../cmt01.qmd | 0 .../cmt01a.qmd | 0 .../cmt01b.qmd | 0 .../cmt02_pt.qmd | 0 .../{rmp => risk-management-plan}/rmpt01.qmd | 0 .../{rmp => risk-management-plan}/rmpt03.qmd | 0 .../{rmp => risk-management-plan}/rmpt04.qmd | 0 .../{rmp => risk-management-plan}/rmpt05.qmd | 0 .../{rmp => risk-management-plan}/rmpt06.qmd | 0 book/tlg-index.qmd | 26 +++++++++---------- 15 files changed, 18 insertions(+), 17 deletions(-) rename book/listings/{con-med => concomitant-medications}/cml01.qmd (100%) rename book/listings/{con-med => concomitant-medications}/cml02a_gl.qmd (100%) rename book/listings/{con-med => concomitant-medications}/cml02b_gl.qmd (100%) rename book/listings/{dsur => development-safety-update-report}/dsur4.qmd (100%) rename book/tables/{con-med => concomitant-medications}/cmt01.qmd (100%) rename book/tables/{con-med => concomitant-medications}/cmt01a.qmd (100%) rename book/tables/{con-med => concomitant-medications}/cmt01b.qmd (100%) rename book/tables/{con-med => concomitant-medications}/cmt02_pt.qmd (100%) rename book/tables/{rmp => risk-management-plan}/rmpt01.qmd (100%) rename book/tables/{rmp => risk-management-plan}/rmpt03.qmd (100%) rename book/tables/{rmp => risk-management-plan}/rmpt04.qmd (100%) rename book/tables/{rmp => risk-management-plan}/rmpt05.qmd (100%) rename book/tables/{rmp => risk-management-plan}/rmpt06.qmd (100%) diff --git a/book/generate-index.R b/book/generate-index.R index 2fd8e3c71a..20473e2308 100755 --- a/book/generate-index.R +++ b/book/generate-index.R @@ -39,7 +39,7 @@ cat( section_header("Tables") create_subsection("./tables/ada", "ADA") create_subsection("./tables/adverse-events", "Adverse Events") -create_subsection("./tables/con-med", "Concomitant Medications") +create_subsection("./tables/concomitant-medications", "Concomitant Medications") create_subsection("./tables/deaths", "Deaths") create_subsection("./tables/demography", "Demography") create_subsection("./tables/disclosures", "Disclosures") @@ -50,7 +50,7 @@ create_subsection("./tables/exposure", "Exposure") create_subsection("./tables/lab-results", "Lab Results") create_subsection("./tables/medical-history", "Medical History") create_subsection("./tables/pharmacokinetic", "Pharmacokinetic") -create_subsection("./tables/rmp", "Risk Management Plan") +create_subsection("./tables/risk-management-plan", "Risk Management Plan") create_subsection("./tables/safety", "Safety") create_subsection("./tables/vital-signs", "Vital Signs") @@ -59,9 +59,9 @@ create_subsection("./tables/vital-signs", "Vital Signs") section_header("Listings") create_subsection("./listings/ada", "ADA") create_subsection("./listings/adverse-events", "Adverse Events") -create_subsection("./listings/con-med", "Concomitant Medications") +create_subsection("./listings/concomitant-medications", "Concomitant Medications") create_subsection("./listings/disposition", "Disposition") -create_subsection("./listings/dsur", "Development Safety Update Report") +create_subsection("./listings/development-safety-update-report", "Development Safety Update Report") create_subsection("./listings/ecg", "ECG") create_subsection("./listings/exposure", "Exposure") create_subsection("./listings/lab-results", "Lab Results") @@ -75,3 +75,4 @@ section_header("Graphs") create_subsection("./graphs/efficacy", "Efficacy") create_subsection("./graphs/pharmacokinetic", "Pharmacokinetic") create_subsection("./graphs/other", "Other") + diff --git a/book/listings/con-med/cml01.qmd b/book/listings/concomitant-medications/cml01.qmd similarity index 100% rename from book/listings/con-med/cml01.qmd rename to book/listings/concomitant-medications/cml01.qmd diff --git a/book/listings/con-med/cml02a_gl.qmd b/book/listings/concomitant-medications/cml02a_gl.qmd similarity index 100% rename from book/listings/con-med/cml02a_gl.qmd rename to book/listings/concomitant-medications/cml02a_gl.qmd diff --git a/book/listings/con-med/cml02b_gl.qmd b/book/listings/concomitant-medications/cml02b_gl.qmd similarity index 100% rename from book/listings/con-med/cml02b_gl.qmd rename to book/listings/concomitant-medications/cml02b_gl.qmd diff --git a/book/listings/dsur/dsur4.qmd b/book/listings/development-safety-update-report/dsur4.qmd similarity index 100% rename from book/listings/dsur/dsur4.qmd rename to book/listings/development-safety-update-report/dsur4.qmd diff --git a/book/tables/con-med/cmt01.qmd b/book/tables/concomitant-medications/cmt01.qmd similarity index 100% rename from book/tables/con-med/cmt01.qmd rename to book/tables/concomitant-medications/cmt01.qmd diff --git a/book/tables/con-med/cmt01a.qmd b/book/tables/concomitant-medications/cmt01a.qmd similarity index 100% rename from book/tables/con-med/cmt01a.qmd rename to book/tables/concomitant-medications/cmt01a.qmd diff --git a/book/tables/con-med/cmt01b.qmd b/book/tables/concomitant-medications/cmt01b.qmd similarity index 100% rename from book/tables/con-med/cmt01b.qmd rename to book/tables/concomitant-medications/cmt01b.qmd diff --git a/book/tables/con-med/cmt02_pt.qmd b/book/tables/concomitant-medications/cmt02_pt.qmd similarity index 100% rename from book/tables/con-med/cmt02_pt.qmd rename to book/tables/concomitant-medications/cmt02_pt.qmd diff --git a/book/tables/rmp/rmpt01.qmd b/book/tables/risk-management-plan/rmpt01.qmd similarity index 100% rename from book/tables/rmp/rmpt01.qmd rename to book/tables/risk-management-plan/rmpt01.qmd diff --git a/book/tables/rmp/rmpt03.qmd b/book/tables/risk-management-plan/rmpt03.qmd similarity index 100% rename from book/tables/rmp/rmpt03.qmd rename to book/tables/risk-management-plan/rmpt03.qmd diff --git a/book/tables/rmp/rmpt04.qmd b/book/tables/risk-management-plan/rmpt04.qmd similarity index 100% rename from book/tables/rmp/rmpt04.qmd rename to book/tables/risk-management-plan/rmpt04.qmd diff --git a/book/tables/rmp/rmpt05.qmd b/book/tables/risk-management-plan/rmpt05.qmd similarity index 100% rename from book/tables/rmp/rmpt05.qmd rename to book/tables/risk-management-plan/rmpt05.qmd diff --git a/book/tables/rmp/rmpt06.qmd b/book/tables/risk-management-plan/rmpt06.qmd similarity index 100% rename from book/tables/rmp/rmpt06.qmd rename to book/tables/risk-management-plan/rmpt06.qmd diff --git a/book/tlg-index.qmd b/book/tlg-index.qmd index a7d87373a0..19a704936b 100644 --- a/book/tlg-index.qmd +++ b/book/tlg-index.qmd @@ -56,13 +56,13 @@ toc-depth: 4 #### Concomitant Medications -        [CMT01 -- Concomitant Medications (GNEDrug Legacy Coding)](./tables/con-med/cmt01.qmd) +        [CMT01 -- Concomitant Medications (GNEDrug Legacy Coding)](./tables/concomitant-medications/cmt01.qmd) -        [CMT01A -- Concomitant Medications by Medication Class and Preferred Name](./tables/con-med/cmt01a.qmd) +        [CMT01A -- Concomitant Medications by Medication Class and Preferred Name](./tables/concomitant-medications/cmt01a.qmd) -        [CMT01B -- Concomitant Medications by Medication Class and Preferred Name](./tables/con-med/cmt01b.qmd) +        [CMT01B -- Concomitant Medications by Medication Class and Preferred Name](./tables/concomitant-medications/cmt01b.qmd) -        [CMT02_PT -- Concomitant Medications by Preferred Name (WHODrug Coding)](./tables/con-med/cmt02_pt.qmd) +        [CMT02_PT -- Concomitant Medications by Preferred Name (WHODrug Coding)](./tables/concomitant-medications/cmt02_pt.qmd) #### Deaths @@ -211,15 +211,15 @@ toc-depth: 4 #### Risk Management Plan -        [RMPT01 -- Duration of Exposure for Risk Management Plan](./tables/rmp/rmpt01.qmd) +        [RMPT01 -- Duration of Exposure for Risk Management Plan](./tables/risk-management-plan/rmpt01.qmd) -        [RMPT03 -- Extent of Exposure by Age Group and Gender for Risk Management Plan](./tables/rmp/rmpt03.qmd) +        [RMPT03 -- Extent of Exposure by Age Group and Gender for Risk Management Plan](./tables/risk-management-plan/rmpt03.qmd) -        [RMPT04 -- Extent of Exposure by Ethnic Origin for Risk Management Plan](./tables/rmp/rmpt04.qmd) +        [RMPT04 -- Extent of Exposure by Ethnic Origin for Risk Management Plan](./tables/risk-management-plan/rmpt04.qmd) -        [RMPT05 -- Extent of Exposure by Race for Risk Management Plan](./tables/rmp/rmpt05.qmd) +        [RMPT05 -- Extent of Exposure by Race for Risk Management Plan](./tables/risk-management-plan/rmpt05.qmd) -        [RMPT06 -- Seriousness, Outcomes, Severity, Frequency with 95% CI for Risk Management Plan](./tables/rmp/rmpt06.qmd) +        [RMPT06 -- Seriousness, Outcomes, Severity, Frequency with 95% CI for Risk Management Plan](./tables/risk-management-plan/rmpt06.qmd) #### Safety @@ -260,11 +260,11 @@ toc-depth: 4 #### Concomitant Medications -        [CML01 -- Listing of Previous and Concomitant Medications](./listings/con-med/cml01.qmd) +        [CML01 -- Listing of Previous and Concomitant Medications](./listings/concomitant-medications/cml01.qmd) -        [CML02A_GL -- Listing of Concomitant Medication Class Level 2, Preferred Name, and Investigator-Specified Terms](./listings/con-med/cml02a_gl.qmd) +        [CML02A_GL -- Listing of Concomitant Medication Class Level 2, Preferred Name, and Investigator-Specified Terms](./listings/concomitant-medications/cml02a_gl.qmd) -        [CML02B_GL -- Listing of Concomitant Medication Class, Preferred Name, and Investigator-Specified Terms](./listings/con-med/cml02b_gl.qmd) +        [CML02B_GL -- Listing of Concomitant Medication Class, Preferred Name, and Investigator-Specified Terms](./listings/concomitant-medications/cml02b_gl.qmd) #### Disposition @@ -276,7 +276,7 @@ toc-depth: 4 #### Development Safety Update Report -        [DSUR4 -- Listing of Patients Who Died During Reporting Period](./listings/dsur/dsur4.qmd) +        [DSUR4 -- Listing of Patients Who Died During Reporting Period](./listings/development-safety-update-report/dsur4.qmd) #### ECG From 850d24bcd0d71b61543879d4919655973243ad4b Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 18:13:43 +0000 Subject: [PATCH 03/11] [skip actions] Restyle files --- book/generate-index.R | 1 - 1 file changed, 1 deletion(-) diff --git a/book/generate-index.R b/book/generate-index.R index 20473e2308..99cec8b787 100755 --- a/book/generate-index.R +++ b/book/generate-index.R @@ -75,4 +75,3 @@ section_header("Graphs") create_subsection("./graphs/efficacy", "Efficacy") create_subsection("./graphs/pharmacokinetic", "Pharmacokinetic") create_subsection("./graphs/other", "Other") - From d7c151e764f644bc04013661e0d2cc841d387997 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Thu, 21 Sep 2023 15:39:17 +0000 Subject: [PATCH 04/11] update folders to uppercase. --- book/listings/ADA/adal02.qmd | 131 ++++++++++++++++ book/listings/ECG/egl01.qmd | 89 +++++++++++ book/tables/ADA/adat01.qmd | 230 ++++++++++++++++++++++++++++ book/tables/ADA/adat02.qmd | 151 +++++++++++++++++++ book/tables/ADA/adat03.qmd | 131 ++++++++++++++++ book/tables/ADA/adat04a.qmd | 240 ++++++++++++++++++++++++++++++ book/tables/ADA/adat04b.qmd | 223 ++++++++++++++++++++++++++++ book/tables/ECG/egt01.qmd | 142 ++++++++++++++++++ book/tables/ECG/egt02.qmd | 126 ++++++++++++++++ book/tables/ECG/egt03.qmd | 204 +++++++++++++++++++++++++ book/tables/ECG/egt04.qmd | 100 +++++++++++++ book/tables/ECG/egt05_qtcat.qmd | 255 ++++++++++++++++++++++++++++++++ 12 files changed, 2022 insertions(+) create mode 100644 book/listings/ADA/adal02.qmd create mode 100644 book/listings/ECG/egl01.qmd create mode 100644 book/tables/ADA/adat01.qmd create mode 100644 book/tables/ADA/adat02.qmd create mode 100644 book/tables/ADA/adat03.qmd create mode 100644 book/tables/ADA/adat04a.qmd create mode 100644 book/tables/ADA/adat04b.qmd create mode 100644 book/tables/ECG/egt01.qmd create mode 100644 book/tables/ECG/egt02.qmd create mode 100644 book/tables/ECG/egt03.qmd create mode 100644 book/tables/ECG/egt04.qmd create mode 100644 book/tables/ECG/egt05_qtcat.qmd diff --git a/book/listings/ADA/adal02.qmd b/book/listings/ADA/adal02.qmd new file mode 100644 index 0000000000..9ddcaf7f56 --- /dev/null +++ b/book/listings/ADA/adal02.qmd @@ -0,0 +1,131 @@ +--- +title: ADAL02 +subtitle: Listing of Anti-Drug Antibody Data for Treatment Emergent ADA Positive Patients +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(dplyr) +library(rlistings) +library(scda) + +adab <- synthetic_cdisc_dataset("latest", "adab") %>% + filter(NFRLT %% 1 == 0 & NFRLT > 0) + +trt <- "A: Drug X" +drug_a <- "A: Drug X Antibody" +drugcd <- unique(adab$PARAMCD[adab$PARAM == "Antibody titer units"])[1] +min_titer <- 1.10 + +adab_x <- adab %>% + filter( + ARM == trt, + PARCAT1 == drug_a, + ADPBLPFL == "Y" + ) %>% + select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% + unique() %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + filter(if_any(matches("Treatment Emergent - Positive"), ~ .x == 1)) %>% + # filter(`Treatment Emergent - Positive` == 1) %>% + mutate( + VISN = factor(paste0( + VISIT, "\n(Day ", + ifelse( + NFRLT %% 1 == 0, + NFRLT, + as.character(format(round(NFRLT, 2), nsmall = 2)) + ), + ")" + )), + PTES = ifelse( + ifelse("Treatment induced ADA" %in% names(.), `Treatment induced ADA` == 1, F), + ifelse( + "Transient ADA" %in% names(.) & `Transient ADA` == 1, + "Induced (Transient)", + "Induced (Persistent)" + ), + "Enhanced" + ) + ) %>% + mutate( + AVAL = paste0( + ifelse( + ifelse("ADA interpreted per sample result" %in% names(.), `ADA interpreted per sample result` == 0, F), + "NEGATIVE", + ifelse( + ifelse("Antibody titer units" %in% names(.), !is.na(`Antibody titer units`), F), + ifelse( + `Antibody titer units` < min_titer, + paste0("<", format(min_titer, nsmall = 2)), + as.character(format(round(`Antibody titer units`, 2), nsmall = 2)) + ), + "---" + ) + ), + ifelse( + ifelse("NAB interpreted per sample result" %in% names(.), `NAB interpreted per sample result` == 1, F), + "*", + "" + ) + ) + ) + +out <- adab_x %>% + select(USUBJID, VISN, AVAL, PTES) %>% + tidyr::pivot_wider( + names_from = VISN, + values_from = AVAL + ) %>% + select(USUBJID, unique(adab_x$VISN[order(adab_x$NFRLT)]), PTES) + +var_labels(out) <- names(out) + +out <- out %>% + var_relabel( + USUBJID = "Subject ID", + PTES = "Patient Treatment\nEmergent ADA Status" + ) +``` + +## Standard Listing + +```{r lsting, test = list(lsting = "lsting")} +lsting <- as_listing( + out, + key_cols = "USUBJID", + disp_cols = names(out), + main_title = paste0( + "Listing of Anti-", drugcd, " Antibody Data for Treatment Emergent ADA Positive Patients, PK Population", + "\nProtocol: ", unique(adab$PARCAT1)[1] + ), + subtitles = paste("\nTreatment Group:", trt), + main_footer = "Minimum reportable titer = 1.10 (example only) +--- = No sample evaluated +ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) +Number of patients positive for Treatment Emergent ADA = the number of post-baseline evaluable patients determined to have treatment-induced ADA or treatment-enhanced ADA during the study period. +Treatment-induced ADA = a patient with negative or missing baseline ADA result(s) and at least one positive post-baseline ADA result. +Treatment-enhanced ADA = a patient with positive ADA result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. +Transient ADA = ADA positive result detected (a) at only one post-baseline sampling timepoint (excluding last timepoint) OR (b) at 2 or more timepoints during treatment where the first and last ADA positive samples are separated by a period of < 16 weeks, irrespective of any negative samples in between. +Persistent ADA = ADA positive result detected (a) at the last post-baseline sampling timepoint, OR (b) at 2 or more time points during treatment where the first and last ADA positive samples are separated by a period ≥ 16 weeks, irrespective of any negative samples in between. +Asterisk denotes sample that tested positive for Neutralizing Antibodies." +) + +head(lsting, 20) +``` + +{{< include ../../test-utils/save_results.qmd >}} + +{{< include ../../repro.qmd >}} +::: diff --git a/book/listings/ECG/egl01.qmd b/book/listings/ECG/egl01.qmd new file mode 100644 index 0000000000..a595b864c9 --- /dev/null +++ b/book/listings/ECG/egl01.qmd @@ -0,0 +1,89 @@ +--- +title: EGL01 +subtitle: 'Listing of ECG Data: Safety-Evaluable Patients' +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(dplyr) +library(scda) +library(rlistings) + +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +get_param_unit_range <- function(dataset) { + u_rng <- lapply(unique(dataset$PARAMCD), function(p) { + dat <- dataset %>% filter(PARAMCD == p) + list( + unit = unique(dat$AVALU), + range = paste0(unique(dat$ANRLO), "-", unique(dat$ANRHI)) + ) + }) + names(u_rng) <- unique(dataset$PARAMCD) + u_rng +} + +eg_u_rng <- get_param_unit_range(adeg) + +adeg_sub <- adeg %>% + filter(!is.na(AVAL) & SAFFL == "Y" & ANL01FL == "Y" & !is.na(EGSEQ) & PARAMCD != "ECGINTP") %>% + mutate( + CRTNPT = paste(SITEID, sub("^.*-([[:alnum:]]+)$", "\\1", SUBJID), sep = "/"), + AGSXRC = paste(AGE, SEX, RACE, sep = "/"), + AVAL = format(round(AVAL, 2), nsmall = 2), + AVAL_ANRIND = ifelse(ANRIND %in% c("NORMAL", ""), AVAL, paste(AVAL, substr(ANRIND, 1, 1), sep = "/")), + CHG = format(round(CHG, 2), nsmall = 2) + ) + +anl_eg <- adeg_sub %>% + select(SUBJID, CRTNPT, AGSXRC, TRT01A, PARAMCD, AVAL_ANRIND, CHG, ADY, AVISIT, ADTM) %>% + tidyr::pivot_wider( + id_cols = c(SUBJID, CRTNPT, AGSXRC, TRT01A, ADY, AVISIT, ADTM), + names_from = PARAMCD, + values_from = c(AVAL_ANRIND, CHG) + ) + +out <- anl_eg %>% + select(CRTNPT, AGSXRC, TRT01A, AVISIT, ADY, AVAL_ANRIND_HR, CHG_HR, AVAL_ANRIND_QT, CHG_QT, AVAL_ANRIND_RR, CHG_RR) %>% + var_relabel( + CRTNPT = "Center/Subject ID", + AGSXRC = "Age/Sex/Race", + TRT01A = "Treatment", + AVISIT = "Visit", + ADY = "Study\nDay", + AVAL_ANRIND_HR = paste0("Heart Rate Result\n(", eg_u_rng$HR$unit, ");\nRange:(", eg_u_rng$HR$range, ")"), + CHG_HR = "Heart Rate\nChange from BL", + AVAL_ANRIND_QT = paste0("QT Duration Result\n(", eg_u_rng$QT$unit, ");\nRange:(", eg_u_rng$QT$range, ")"), + CHG_QT = "QT Duration\nChange from BL", + AVAL_ANRIND_RR = paste0("RR Duration Result\n(", eg_u_rng$RR$unit, ");\nRange:(", eg_u_rng$RR$range, ")"), + CHG_RR = "RR Duration\nChange from BL" + ) +``` + +## Standard Listing + +```{r lsting, test = list(lsting = "lsting")} +lsting <- as_listing( + out, + key_cols = c("CRTNPT", "AGSXRC", "TRT01A", "AVISIT", "ADY"), + disp_cols = names(out), + main_title = "Listing of ECG Data: Safety-Evaluable Patients", + main_footer = "Baseline is the patient's last observation prior to initiation of study drug. Abnormalities are flagged as high (H) or low (L) if + outside the Roche standard reference range." +) + +head(lsting, 20) +``` + +{{< include ../../test-utils/save_results.qmd >}} + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ADA/adat01.qmd b/book/tables/ADA/adat01.qmd new file mode 100644 index 0000000000..31a13bd819 --- /dev/null +++ b/book/tables/ADA/adat01.qmd @@ -0,0 +1,230 @@ +--- +title: ADAT01 +subtitle: Baseline Prevalence and Incidence of Treatment Emergent ADA +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(tern) +library(dplyr) +library(scda) +library(tibble) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adab <- synthetic_cdisc_dataset("latest", "adab") + +combodf <- tribble( + ~valname, ~label, ~levelcombo, ~exargs, + "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), + "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() +) + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adab <- adab %>% + filter(PARCAT1 == "A: Drug X Antibody") %>% + select(-ARRLT, -NRRLT) + +# Baseline Pts +adab_b <- df_explicit_na(adab) %>% + filter( + ABLFL == "Y", + ADABLPFL == "Y", + PARAM %in% c("ADA interpreted per sample result") + ) %>% + select(-PARAMCD, -AVALC, -AVALU) %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate_at( + c("ADA interpreted per sample result"), + as.logical + ) %>% + mutate( + ADABLPFL = ADABLPFL == "Y", + PADABLPFL = `ADA interpreted per sample result` == "TRUE", + NADABLPFL = `ADA interpreted per sample result` == "FALSE" + ) %>% + var_relabel( + ADABLPFL = "Baseline evaluable patients", + PADABLPFL = "Patient with a positive sample at baseline", + NADABLPFL = "Patient with no positive samples at baseline" + ) + +# Post Baseline Treatment Enhanced NAb positive Pts +adab_pb <- df_explicit_na(adab) %>% + filter( + ABLFL != "Y", + ADPBLPFL == "Y", + PARAM %in% c( + "ADA interpreted per sample result", + "Treatment Emergent - Positive", + "Treatment induced ADA", + "Treatment enhanced ADA", + "Treatment Emergent - Negative", + "Treatment unaffected" + ) + ) %>% + select(-PARAMCD, -AVALC, -AVALU) %>% + unique() %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate( + across( + any_of(c( + "ADA interpreted per sample result", "Treatment Emergent - Positive", + "Treatment induced ADA", "Treatment enhanced ADA", + "Treatment Emergent - Negative", "Treatment unaffected" + )), + as.logical + ) + ) %>% + mutate( + ADPBLPFL = ADPBLPFL == "Y", + PTEFL = if (exists("Treatment Emergent - Positive", where = .)) `Treatment Emergent - Positive` == "TRUE" else FALSE, + TIFL = if (exists("Treatment induced ADA", where = .)) `Treatment induced ADA` == "TRUE" else FALSE, + TEFL = if (exists("Treatment enhanced ADA", where = .)) `Treatment enhanced ADA` == "TRUE" else FALSE, + NTEFL = if (exists("Treatment Emergent - Negative", where = .)) `Treatment Emergent - Negative` == "TRUE" else FALSE, + TUFL = if (exists("Treatment unaffected", where = .)) `Treatment unaffected` == "TRUE" else FALSE + ) %>% + var_relabel( + ADPBLPFL = "Post-baseline evaluable patients", + PTEFL = "Patient positive for Treatment Emergent ADA", + TIFL = "Treatment-induced ADA", + TEFL = "Treatment-enhanced ADA", + NTEFL = "Patient negative for Treatment Emergent ADA", + TUFL = "Treatment unaffected" + ) +``` + +## Standard Table + +```{r variant1, test = list(result_v1 = "result")} +# Layout for Baseline Prevalence of NAbs +lyt_bl <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "ADABLPFL", + .stats = "count", + var_labels = "Baseline Prevalence of ADAs", + show_labels = "visible", + table_names = "t1" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "PADABLPFL", + table_names = "t2", + .indent_mods = 1L, + var_labels = "a", + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NADABLPFL", + .stats = "count", + show_labels = "hidden", + .indent_mods = 1L, + table_names = "t3" + ) + +# Layout for incidence of NAbs +lyt_pb <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "ADPBLPFL", + .stats = "count", + var_labels = "Incidence of Treatment Emergent ADAs", + show_labels = "visible", + table_names = "tb1" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "PTEFL", + table_names = "tb2", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("TIFL", "TEFL"), + .stats = "count", + table_names = "tb3", + .indent_mods = 2L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NTEFL", + table_names = "tb4", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "TUFL", + .stats = "count", + table_names = "tb5", + .indent_mods = 2L, + show_labels = "hidden" + ) + +result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) +result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) + +# Combine tables. +result_1@col_info <- result_2@col_info +result <- rbind(result_1, result_2) + +# Change the column order. +result <- cbind_rtables(result[, 1], result[, 3]) %>% + cbind_rtables(result[, 4]) %>% + cbind_rtables(result[, 2]) %>% + cbind_rtables(result[, 5]) + +main_title(result) <- paste( + "Baseline Prevalence and Incidence of Treatment Emergent ADA" +) +main_footer(result) <- paste( + "ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient = a patient with an ADA assay result from a baseline sample(s) + Post-baseline evaluable patient = a patient with an ADA assay result from at least one post-baseline sample Number of patients positive for Treatment Emergent + ADA = the number (and percentage) of post-baseline evaluable patients determined to have treatment-induced ADA or treatment-enhanced ADA during the study period. + Treatment-induced ADA = a patient with negative or missing baseline ADA result(s) and at least one positive post-baseline ADA result. + Treatment-enhanced ADA = a patient with positive ADA result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. + Number of patients negative for Treatment Emergent ADA = number of post-baseline evaluable patients with negative or missing baseline ADA result(s) and all negative post-baseline results, or a patient who is treatment unaffected. + Treatment unaffected = A post-baseline evaluable patient with a positive ADA result at baseline and (a) where all post-baseline titer results are less than 0.60 t.u. greater than the baseline titer result, OR (b) where all post-baseline results are negative or missing. + For any positive sample with titer result less than the minimum reportable titer or any positive sample where a titer cannot be obtained, titer value is imputed as equal to the minimum reportable titer." +) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ADA/adat02.qmd b/book/tables/ADA/adat02.qmd new file mode 100644 index 0000000000..630e8e817e --- /dev/null +++ b/book/tables/ADA/adat02.qmd @@ -0,0 +1,151 @@ +--- +title: ADAT02 +subtitle: Summary of Patients with Treatment-Induced ADA +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(tern) +library(dplyr) +library(scda) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adab <- synthetic_cdisc_dataset("latest", "adab") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adab <- df_explicit_na(adab) %>% + mutate(ADPBLPFL = "Y") %>% # temp fix + filter( + ADPBLPFL == "Y", + !PARAM %in% c( + "NAB interpreted per sample result", + "NAB Status of a patient", + "Treatment enhanced ADA" + ) + ) %>% + select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% + unique() %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate( + across( + any_of(c( + "Treatment induced ADA", + "Transient ADA", + "Persistent ADA" + )), + as.logical + ) + ) %>% + mutate( + ADPBLPFL = ADPBLPFL == "Y", + TI_ADA = if (exists("Treatment induced ADA", where = .)) `Treatment induced ADA` else FALSE + ) %>% + var_relabel( + ADPBLPFL = "Post-baseline evaluable patients", + TI_ADA = "Treatment-induced ADA patients" + ) + +adab_ti <- adab %>% + filter(TI_ADA) +``` + +## Standard Table + +```{r variant1, test = list(result_v1 = "result")} +# Layout for post-baseline evaluable patient variables from adab dataset. +lyt_adab <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = drop_split_levels + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "ADPBLPFL", + .stats = "count", + table_names = "post_baseline" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "TI_ADA" + ) + +# Layout for treatment-induced patient variables from adab dataset. +lyt_adab_ti <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = keep_split_levels(c("A: Drug X", "C: Combination", "")) # temp fix + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("Transient ADA", "Persistent ADA"), + var_labels = "Treatment-induced ADA patients with", + show_labels = "visible" + ) %>% + analyze_vars( + "Time to onset of ADA", + .stats = "median", + nested = FALSE, + .labels = c(median = "Median time to onset of ADA (weeks)") + ) %>% + analyze_vars( + "Antibody titer units", + .stats = "range", + nested = FALSE, + .labels = c(range = "ADA titer range (min - max)") + ) + +result_adab <- build_table(lyt_adab, df = adab, alt_counts_df = adsl) +result_adab_ti <- build_table(lyt_adab_ti, df = adab_ti, alt_counts_df = adsl) + +# Combine tables. +col_info(result_adab) <- col_info(result_adab_ti) +result <- rbind( + result_adab, + result_adab_ti +) + +main_title(result) <- paste( + "Summary of Patients with Treatment-Induced ADA, PK Population" +) +subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) +main_footer(result) <- paste( + "ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic + Antibodies) + Treatment-induced ADA = negative or missing baseline. + ADA result(s) and at least one positive post-baseline ADA result. + Transient ADA = ADA positive result detected (a) at only one post-baseline + sampling timepoint (excluding last timepoint) OR (b) at 2 or more timepoints + during treatment where the first and last ADA positive samples are separated + by a period of < 16 weeks, irrespective of any negative samples in between. + Persistent ADA = ADA positive result detected (a) at the last post-baseline + sampling timepoint, OR (b) at 2 or more time points during treatment where + the first and last ADA positive samples are separated by a period ≥ 16 + weeks, irrespective of any negative samples in between." +) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ADA/adat03.qmd b/book/tables/ADA/adat03.qmd new file mode 100644 index 0000000000..561c5ab1af --- /dev/null +++ b/book/tables/ADA/adat03.qmd @@ -0,0 +1,131 @@ +--- +title: ADAT03 +subtitle: Summary of Serum Concentrations at Timepoints Where ADA Samples Were Collected and Analyzed +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(dplyr) +library(scda) +library(tern) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adab <- synthetic_cdisc_dataset("latest", "adab") +adpc <- synthetic_cdisc_dataset("latest", "adpc") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adab <- df_explicit_na(adab) +adpc <- df_explicit_na(adpc) + +# Adjust zzz parameter +max_conc <- 15 + +adpc <- adpc %>% select(USUBJID, NFRLT, AVAL, AVALU, AVALCAT1) + +anl <- adab %>% + filter(., PARAM == "ADA interpreted per sample result") %>% + select(-AVAL, AVALC, AVALU) + +anl <- merge(anl, adpc, by = c("USUBJID", "NFRLT")) %>% + mutate(AVAL_LT = ifelse(AVAL <= max_conc, TRUE, FALSE)) +``` + +## Standard Table (μg/mL) + +```{r variant1, test = list(result_v1 = "result")} +# parameters in columns +adat03_stats <- c("n", "mean", "sd", "median", "min", "max", "cv", "geom_mean", "count_fraction") +adat03_lbls <- c( + n = "Total Number\nof Measurable\n Samples", + mean = "Mean", + sd = "SD", + median = "Median", + min = "Minimum", + max = "Maximum", + cv = "CV (%)", + geom_mean = "Geometric Mean", + count_fraction = paste0("Samples with\nConcentration\n≤ ", max_conc, "μg/mL") +) +adat03_fmts <- c( + n = "xx.", + mean = sprintf_format("%.3e"), + sd = sprintf_format("%.3e"), + median = sprintf_format("%.3e"), + min = sprintf_format("%.3e"), + max = sprintf_format("%.3e"), + cv = "xx.x", + geom_mean = sprintf_format("%.3e"), + count_fraction = format_count_fraction +) + +afun_list <- lapply( + 1:9, + function(i) make_afun(s_summary, .stats = adat03_stats[i], .formats = adat03_fmts[i], .labels = "Overall") +) + +# lyt creation +lyt <- basic_table() %>% + split_rows_by( + var = "ARM", + label_pos = "topleft", + split_label = "Treatment Group", + split_fun = drop_split_levels, + section_div = "" + ) %>% + add_rowcounts() %>% + split_rows_by( + var = "VISIT", + label_pos = "topleft", + split_label = "Visit", + split_fun = drop_split_levels, + child_labels = "hidden" + ) %>% + analyze_vars_in_cols( + vars = c(rep("AVAL", 8), "AVAL_LT"), + .stats = adat03_stats, + .labels = adat03_lbls, + .formats = adat03_fmts + ) %>% + analyze_colvars( + afun_list, + nested = FALSE, + extra_args = list(".labels" = "Overall") + ) + +result <- build_table(lyt, anl, alt_counts_df = adsl) + +main_title(result) <- paste( + "Summary of Serum Concentrations (μg/mL) at Timepoints Where ADA Samples Were Collected and Analyzed\n + Protocol:", unique(adab$PARCAT1)[1] +) +subtitles(result) <- paste("Analyte:", unique(adab$PARAMCD)[1]) +fnotes_at_path(result, rowpath = NULL, colpath = c("multivars", "AVAL")) <- "Refers to the total no. of measurable ADA samples that have a corresponding measurable drug concentration sample (i.e. results with +valid numeric values and LTRs). LTR results on post-dose samples are replaced by aaa µg/mL i.e. half of MQC value." +fnotes_at_path(result, rowpath = NULL, colpath = c("multivars", "AVAL_LT")) <- "In validation, the assay was able to detect yyy ng/mL of surrogate ADA in the presence of zzz µg/mL of [drug]. BLQ = Below Limit of +Quantitation, LTR = Lower than Reportable, MQC = Minimum Quantifiable Concentration, ADA = Anti-Drug Antibodies (is also referred to as ATA, +or Anti-Therapeutic Antibodies). RXXXXXXX is also known as [drug]" + +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ADA/adat04a.qmd b/book/tables/ADA/adat04a.qmd new file mode 100644 index 0000000000..3a3f56d998 --- /dev/null +++ b/book/tables/ADA/adat04a.qmd @@ -0,0 +1,240 @@ +--- +title: ADAT04A +subtitle: Baseline Prevalence and Incidence of Treatment Emergent NAbs +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(tern) +library(dplyr) +library(scda) +library(tibble) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adab <- synthetic_cdisc_dataset("latest", "adab") + +combodf <- tribble( + ~valname, ~label, ~levelcombo, ~exargs, + "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), + "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() +) + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) + +# Baseline Pts +adab_b <- df_explicit_na(adab) %>% + filter( + ABLFL == "Y", + ADABLPFL == "Y", + PARAM %in% c( + "ADA interpreted per sample result", + "NAB interpreted per sample result" + ) + ) %>% + select(-PARAMCD, -AVALC, -AVALU) %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate( + across( + any_of(c( + "ADA interpreted per sample result", + "NAB interpreted per sample result" + )), + as.logical + ) + ) %>% + mutate( + ADABLPFL = ADABLPFL == "Y", + PADABLPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, + PNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "TRUE" else FALSE, + NNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE + ) %>% + var_relabel( + ADABLPFL = "Baseline evaluable patients for ADA", + PADABLPFL = "Patients with a positive ADA sample at baseline", + PNABBLFL = "Patients with a positive NAb sample at baseline", + NNABBLFL = "Patient with no positive NAb samples at baseline" + ) + +# Post Baseline Treatment Enhanced NAb positive Pts +adab_pb <- df_explicit_na(adab) %>% + filter( + ABLFL != "Y", + ADPBLPFL == "Y", + PARAM %in% c( + "ADA interpreted per sample result", + "Treatment Emergent - Positive, Neutralizing Antibody", + "Treatment induced ADA, Neutralizing Antibody", + "Treatment enhanced ADA, Neutralizing Antibody", + "NAB interpreted per sample result", + "Treatment unaffected, Neutralizing Antibody" + ) + ) %>% + select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% + unique() %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate( + across( + any_of(c( + "ADA interpreted per sample result", "NAB interpreted per sample result", + "Treatment Emergent - Positive, Neutralizing Antibody", + "Treatment induced ADA, Neutralizing Antibody", + "Treatment enhanced ADA, Neutralizing Antibody", + "Treatment unaffected, Neutralizing Antibody" + )), + as.logical + ) + ) %>% + mutate( + ADPBLPFL = ADPBLPFL == "Y", + ADAPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, + TENABPFL = if (exists("Treatment Emergent - Positive, Neutralizing Antibody", where = .)) `Treatment Emergent - Positive, Neutralizing Antibody` == "TRUE" else FALSE, + TINPBFL = if (exists("Treatment induced ADA, Neutralizing Antibody", where = .)) `Treatment induced ADA, Neutralizing Antibody` == "TRUE" else FALSE, + TENPBFL = if (exists("Treatment enhanced ADA, Neutralizing Antibody", where = .)) `Treatment enhanced ADA, Neutralizing Antibody` == "TRUE" else FALSE, + NABNFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE, + TUNPBFL = if (exists("Treatment unaffected, Neutralizing Antibody", where = .)) `Treatment unaffected, Neutralizing Antibody` == "TRUE" else FALSE + ) %>% + var_relabel( + ADPBLPFL = "Post-baseline evaluable patients for ADA", + ADAPFL = "Patients positive for ADA", + TENABPFL = "Patients positive for Treatment Emergent NAb", + TINPBFL = "Treatment-induced NAb", + TENPBFL = "Treatment-enhanced NAb", + NABNFL = "Patients negative for NAb", + TUNPBFL = "Treatment unaffected" + ) +``` + +## Summary of Treatment Emergent NAbs + +```{r variant1, test = list(result_v1 = "result")} +# Layout for Baseline Prevalence of NAbs +lyt_bl <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("ADABLPFL", "PADABLPFL"), + table_names = "t1", + .stats = "count", + var_labels = "Baseline Prevalence of NAbs", + show_labels = "visible" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "PNABBLFL", + table_names = "t2", + .indent_mods = 1L + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NNABBLFL", + .stats = "count", + table_names = "t3", + .indent_mods = 1L, + show_labels = "hidden" + ) + +# Layout for incidence of NAbs +lyt_pb <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("ADPBLPFL", "ADAPFL"), + .stats = "count", + var_labels = "Incidence of Treatment Emergent NAbs", + show_labels = "visible", + table_names = "tb1" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "TENABPFL", + table_names = "tb2", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("TINPBFL", "TENPBFL"), + .stats = "count", + table_names = "tb3", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NABNFL", + table_names = "tb4", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "TUNPBFL", + .stats = "count", + table_names = "tb5", + .indent_mods = 1L, + show_labels = "hidden" + ) + +result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) +result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) + +# Combine tables +result <- rbind(result_1, result_2) + +# Change the column order +result <- cbind_rtables(result[, 1], result[, 3]) %>% + cbind_rtables(result[, 4]) %>% + cbind_rtables(result[, 2]) %>% + cbind_rtables(result[, 5]) + +main_title(result) <- paste( + "Baseline Prevalence and Incidence of Treatment Emergent NAbs" +) +subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) +main_footer(result) <- paste( + "NAb = Neutralizing Antibodies ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient for ADA = a patient with an ADA assay result from a baseline sample(s) + Baseline evaluable patient for NAb = a patient with a NAb assay result from a baseline sample(s) + Post-baseline evaluable patient for ADA = a patient with an ADA assay result from at least one post-baseline sample + Post-baseline evaluable patient for NAb = a patient with a NAb assay result from at least one post-baseline sample + Number of patients positive for ADA = the number of post-baseline evaluable patients for ADA determined to have Treatment Emergent ADA during the study period. +Number of patients positive for Treatment Emergent NAb = the number (and percentage) of post-baseline evaluable patients for ADA determined to have treatment-induced NAb or treatment-enhanced NAb during the study period. +Treatment-induced = a patient with negative or missing baseline result(s) and at least one positive post-baseline result. Treatment-enhanced = a patient with positive result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. +Number of patients negative for Treatment Emergent NAb = number of post-baseline evaluable patients with negative or missing baseline NAb result(s) and all negative post-baseline NAb results, or a patient who is NAb treatment unaffected. +Treatment unaffected = A post-baseline evaluable patient with a positive result at baseline and (a) where all post-baseline titer results are less than 0.60 t.u. greater than the baseline titer result, OR (b) where all post-baseline results are negative or missing. For any positive sample with titer result less than the minimum reportable titer or any positive sample where a titer cannot be obtained, titer value is imputed as equal to the minimum reportable titer." +) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ADA/adat04b.qmd b/book/tables/ADA/adat04b.qmd new file mode 100644 index 0000000000..5994f04002 --- /dev/null +++ b/book/tables/ADA/adat04b.qmd @@ -0,0 +1,223 @@ +--- +title: ADAT04B +subtitle: Baseline Prevalence and Incidence of NAbs +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(tern) +library(dplyr) +library(scda) +library(tibble) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adab <- synthetic_cdisc_dataset("latest", "adab") + +combodf <- tribble( + ~valname, ~label, ~levelcombo, ~exargs, + "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), + "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() +) + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) + +# Baseline Pts +adab_b <- df_explicit_na(adab) %>% + filter( + ABLFL == "Y", + ADABLPFL == "Y", + PARAM %in% c( + "ADA interpreted per sample result", + "NAB interpreted per sample result" + ) + ) %>% + select(-PARAMCD, -AVALC, -AVALU) %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate( + across( + any_of(c( + "ADA interpreted per sample result", + "NAB interpreted per sample result" + )), + as.logical + ) + ) %>% + mutate( + ADABLPFL = ADABLPFL == "Y", + PADABLPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, + PNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "TRUE" else FALSE, + NNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE + ) %>% + var_relabel( + ADABLPFL = "Baseline evaluable patients for ADA", + PADABLPFL = "Patients with a positive ADA sample at baseline", + PNABBLFL = "Patients with a positive NAb sample at baseline", + NNABBLFL = "Patients with no positive NAb sample at baseline" + ) + +# Post-Baseline Evaluable Pts +adab_pb_ada <- df_explicit_na(adab) %>% + filter(ADPBLPFL == "Y") %>% + select(STUDYID, USUBJID, ARM, ACTARM, ADPBLPFL) %>% + mutate(ADPBLPFL = ADPBLPFL == "Y") %>% + distinct() + +# Post-Baseline ADA Positive Pts +adab_pb_adap <- df_explicit_na(adab) %>% + filter( + ABLFL != "Y", + PARAM == "ADA interpreted per sample result", + AVALC == "POSITIVE" + ) %>% + mutate(ADAPFL = AVALC == "POSITIVE") %>% + select(STUDYID, USUBJID, ARM, ACTARM, ADAPFL) %>% + distinct() + +# Post-Baseline NAb Positive Pts +adab_pb_nabp <- df_explicit_na(adab) %>% + filter( + ABLFL != "Y", + PARAM == "NAb interpreted per sample result", + AVALC == "POSITIVE" + ) %>% + mutate(NABPFL = AVALC == "POSITIVE") %>% + select(STUDYID, USUBJID, ARM, ACTARM, NABPFL) %>% + distinct() + +# Post-Baseline NAb Negative Pts +adab_pb_nabn <- df_explicit_na(adab) %>% + filter( + ABLFL != "Y", + PARAM == "NAb interpreted per sample result", + AVALC == "NEGATIVE" + ) %>% + rename(NABNFL = AVALC) %>% + select(STUDYID, USUBJID, ARM, ACTARM, NABNFL) %>% + distinct() + +mergecol <- c("STUDYID", "USUBJID", "ARM", "ACTARM") + +adab_pb <- left_join(adab_pb_ada, adab_pb_adap, by = mergecol) %>% + left_join(adab_pb_nabp, by = mergecol) %>% + mutate( + NABNFL = ifelse(is.na(NABPFL), "TRUE", "FALSE"), + NABNFL = NABNFL == "TRUE" + ) %>% + var_relabel( + ADPBLPFL = "Post-baseline evaluable patients for ADA", + ADAPFL = "Patients positive for ADA", + NABPFL = "Patients positive for NAb", + NABNFL = "Patients negative for NAb" + ) +``` + +## Standard Table + +```{r variant1, test = list(result_v1 = "result")} +# Layout for Baseline Prevalence of NAbs +lyt_bl <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("ADABLPFL", "PADABLPFL"), + .stats = "count", + var_labels = "Baseline Prevalence of NAbs", + show_labels = "visible", + table_names = "t1" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "PNABBLFL", + table_names = "t2", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NNABBLFL", + .stats = "count", + table_names = "t3", + .indent_mods = 1L, + show_labels = "hidden" + ) + +# Layout for incidence of NAbs +lyt_pb <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("ADPBLPFL", "ADAPFL"), + .stats = "count", + var_labels = "Incidence of NAbs", + show_labels = "visible", + table_names = "tb1" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NABPFL", + table_names = "tb2", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NABNFL", + .stats = "count", + table_names = "tb3", + .indent_mods = 1L, + show_labels = "hidden" + ) + +result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) +result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) + +# Combine tables. +result <- rbind(result_1, result_2) + +# Change the column order. +result <- cbind_rtables(result[, 1], result[, 3]) %>% + cbind_rtables(result[, 4]) %>% + cbind_rtables(result[, 2]) %>% + cbind_rtables(result[, 5]) + +main_title(result) <- paste( + "Baseline Prevalence and Incidence of Neutralizing Antibodies (NAbs)" +) +subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) +main_footer(result) <- paste( + "NAb = Neutralizing Antibodies ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient for ADA = a patient with an ADA assay result from a baseline sample(s) Baseline evaluable patient for NAb = a patient with a NAb assay result from a baseline sample(s) Post-baseline evaluable patient for ADA = a patient with an ADA assay result from at least one post-baseline sample Post-baseline evaluable patient for NAb = a patient with a NAb assay result from at least one post-baseline sample Number of patients positive for ADA = the number of post-baseline evaluable patients for ADA determined to have Treatment Emergent ADA during the study period. +Number of patients positive for NAb = the number (and percentage) of post-baseline evaluable patients for ADA determined to have at least one positive post-baseline NAb result during the study period. Number of patients negative for NAb = number of post-baseline evaluable patients with all negative post-baseline NAb results." +) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ECG/egt01.qmd b/book/tables/ECG/egt01.qmd new file mode 100644 index 0000000000..017188e635 --- /dev/null +++ b/book/tables/ECG/egt01.qmd @@ -0,0 +1,142 @@ +--- +title: EGT01 +subtitle: ECG Results and Change from Baseline by Visit +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(dplyr) +library(tern) +library(scda) + +# Data should be filtered for the studied Parameter (`PARAM`) and the +# Analysis Visit (`AVISIT`). According to the GDSR template, the values for +# the `AVISIT` reported in the EGT01 standard may be: +# 'POST-BASELINE MAXIMUM', 'POST-BASELINE MINIMUM', 'POST-BASELINE LAST'. + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg) + +adeg_f <- adeg %>% + filter(ANL01FL == "Y") %>% + filter(PARAM %in% c("Heart Rate", "QT Duration", "RR Duration")) +``` + +## Standard Table + +```{r variant1, test = list(result_v1 = "result")} +# Define the split function +split_fun <- drop_split_levels + +afun <- function(x, .var, .spl_context, ...) { + n_fun <- sum(!is.na(x), na.rm = TRUE) + if (n_fun == 0) { + mean_sd_fun <- c(NA, NA) + median_fun <- NA + min_max_fun <- c(NA, NA) + } else { + mean_sd_fun <- c(mean(x, na.rm = TRUE), sd(x, na.rm = TRUE)) + median_fun <- median(x, na.rm = TRUE) + min_max_fun <- c(min(x), max(x)) + } + is_chg <- .var == "CHG" + is_baseline <- .spl_context$value[which(.spl_context$split == "AVISIT")] == "BASELINE" + if (is_baseline && is_chg) n_fun <- mean_sd_fun <- median_fun <- min_max_fun <- NULL + + in_rows( + "n" = n_fun, + "Mean (SD)" = mean_sd_fun, + "Median" = median_fun, + "Min - Max" = min_max_fun, + .formats = list("n" = "xx", "Mean (SD)" = "xx.xx (xx.xx)", "Median" = "xx.xx", "Min - Max" = "xx.xx - xx.xx"), + .format_na_strs = list("n" = "NE", "Mean (SD)" = "NE (NE)", "Median" = "NE", "Min - Max" = "NE - NE") + ) +} + +lyt <- basic_table(show_colcounts = TRUE) %>% + split_cols_by("ACTARM") %>% + split_rows_by("PARAM", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$PARAM)) %>% + split_rows_by("AVISIT", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$AVISIT)) %>% + split_cols_by_multivar( + vars = c("AVAL", "CHG"), + varlabels = c("Value at Visit", "Change from\nBaseline") + ) %>% + analyze_colvars(afun = afun) + +result <- build_table(lyt, adeg_f, alt_counts_df = adsl) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| screenshot.opts = list(delay = 16) + +library(teal.modules.clinical) +library(scda) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg) + +app <- init( + data = cdisc_data( + cdisc_dataset("ADSL", + adsl, + code = 'ADSL <- df_explicit_na(synthetic_cdisc_dataset("latest", "adsl"))' + ), + cdisc_dataset("ADEG", + adeg, + code = 'ADEG <- df_explicit_na(synthetic_cdisc_dataset("latest", "adeg"))' + ), + check = TRUE + ), + modules = modules( + tm_t_summary_by( + label = "ECG Results and Change from Baseline by Visit", + dataname = "ADEG", + arm_var = choices_selected( + choices = variable_choices(adsl, c("ARM", "ARMCD")), + selected = "ARM" + ), + by_vars = choices_selected( + choices = variable_choices(adeg, c("PARAM", "AVISIT")), + selected = c("AVISIT") + ), + summarize_vars = choices_selected( + choices = variable_choices(adeg, c("AVAL", "CHG")), + selected = c("AVAL") + ), + useNA = "ifany", + paramcd = choices_selected( + choices = value_choices(adeg, "PARAMCD", "PARAM"), + selected = "HR" + ), + parallel_vars = TRUE + ) + ), + filter = list(ADEG = list(AVAL = list())) +) + +shinyApp(app$ui, app$server) +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ECG/egt02.qmd b/book/tables/ECG/egt02.qmd new file mode 100644 index 0000000000..addbda506f --- /dev/null +++ b/book/tables/ECG/egt02.qmd @@ -0,0 +1,126 @@ +--- +title: EGT02 +subtitle: ECG Abnormalities (EGT02_1 & EGT02_2) +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(dplyr) +library(scda) +library(tern) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg) + +# Note: We keep only post-baseline for analysis. +adeg_f <- adeg %>% + filter(ONTRTFL == "Y") %>% + filter(PARAM %in% c("Heart Rate", "QT Duration", "RR Duration")) %>% + filter(ANRIND != "") %>% + var_relabel( + PARAM = "Assessment", + ANRIND = "Abnormality" + ) +``` + +## ECG Abnormalities Regardless
of Abnormality at Baseline + +```{r variant1, test = list(result_v1 = "result")} +split_fun <- drop_split_levels + +lyt <- basic_table(show_colcounts = TRUE) %>% + split_cols_by(var = "ACTARM") %>% + split_rows_by( + "PARAM", + split_fun = split_fun, + label_pos = "topleft", + split_label = obj_label(adeg_f$PARAM) + ) %>% + count_abnormal("ANRIND", abnormal = list(Low = "LOW", High = "HIGH"), exclude_base_abn = FALSE) %>% + append_varlabels(adeg_f, "ANRIND", indent = 1L) + +result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) +result +``` + +## ECG Abnormalities Among Subjects
Without Abnormality at Baseline + +```{r variant2, test = list(result_v2 = "result")} +split_fun <- drop_split_levels + +lyt <- basic_table(show_colcounts = TRUE) %>% + split_cols_by(var = "ACTARM") %>% + split_rows_by( + "PARAM", + split_fun = split_fun, + label_pos = "topleft", + split_label = obj_label(adeg_f$PARAM) + ) %>% + count_abnormal("ANRIND", abnormal = list(Low = "LOW", High = "HIGH"), exclude_base_abn = TRUE) %>% + append_varlabels(adeg_f, "ANRIND", indent = 1L) + +result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| screenshot.opts = list(delay = 18) + +library(scda) +library(teal.modules.clinical) +library(dplyr) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +app <- init( + data = cdisc_data( + cdisc_dataset("ADSL", adsl, code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl")'), + cdisc_dataset("ADEG", adeg, code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg")'), + check = TRUE + ), + modules = modules( + tm_t_abnormality( + label = "Abnormality Table", + dataname = "ADEG", + arm_var = choices_selected( + choices = variable_choices(adsl, subset = c("ARM", "ARMCD")), + selected = "ARM" + ), + by_vars = choices_selected( + choices = variable_choices(adeg, subset = c("EGCAT", "PARAM", "AVISIT")), + selected = c("PARAM"), + keep_order = TRUE + ), + grade = choices_selected( + choices = variable_choices(adeg, subset = "ANRIND"), + selected = "ANRIND", + fixed = TRUE + ), + abnormal = list(Low = "LOW", High = "HIGH"), + exclude_base_abn = FALSE + ) + ) +) + +shinyApp(app$ui, app$server) +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ECG/egt03.qmd b/book/tables/ECG/egt03.qmd new file mode 100644 index 0000000000..6d335eb12e --- /dev/null +++ b/book/tables/ECG/egt03.qmd @@ -0,0 +1,204 @@ +--- +title: EGT03 +subtitle: Shift Table of ECG Interval Data -- Baseline Versus Minimum/Maximum Post-Baseline +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(scda) +library(tern) +library(dplyr) + +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adeg <- df_explicit_na(adeg) + +adeg_labels <- var_labels(adeg) + +adeg_f_pbmin <- subset( + adeg, + PARAMCD == "HR" & # Heart Rate + SAFFL == "Y" & # "Safety Population Flag" + ONTRTFL == "Y" & # "On Treatment Record Flag" + AVISIT == "POST-BASELINE MINIMUM" # "Analysis Visit" +) + +adeg_f_pbmax <- subset( + adeg, + PARAMCD == "HR" & # Heart Rate + SAFFL == "Y" & # "Safety Population Flag" + ONTRTFL == "Y" & # "On Treatment Record Flag" + AVISIT == "POST-BASELINE MAXIMUM" # "Analysis Visit" +) + +var_labels(adeg_f_pbmin) <- adeg_labels +var_labels(adeg_f_pbmax) <- adeg_labels +``` + +## Table of Baseline Versus
Minimum Post-Baseline + +For the EGT03 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. +For illustration purposes, missing data are added to the example dataset. + +```{r variant1, test = list(result_v1 = "result")} +set.seed(123, kind = "Mersenne-Twister") + +adeg_f_pbmin$BNRIND <- factor( + adeg_f_pbmin$BNRIND, + levels = c("LOW", "NORMAL", "HIGH", "Missing"), + labels = c("LOW", "NORMAL", "HIGH", "Missing") +) +adeg_f_pbmin$ANRIND <- factor( + adeg_f_pbmin$ANRIND, + levels = c("LOW", "NORMAL", "HIGH", "Missing"), + labels = c("LOW", "NORMAL", "HIGH", "Missing") +) + +adeg_f_pbmin$BNRIND[sample(1:nrow(adeg_f_pbmin), size = 5)] <- "Missing" +adeg_f_pbmin$ANRIND[sample(1:nrow(adeg_f_pbmin), size = 5)] <- "Missing" + +attr(adeg_f_pbmin$ANRIND, "label") <- "Analysis Reference Range Indicator" +attr(adeg_f_pbmin$BNRIND, "label") <- "Baseline Reference Range Indicator" + +# Temporary solution for overarching column +adeg_f_pbmin <- adeg_f_pbmin %>% mutate(min_label = "Minimum Post-Baseline Assessment") + +# Define the split function +split_fun <- drop_split_levels + +lyt <- basic_table() %>% + split_cols_by("min_label") %>% + split_cols_by("ANRIND") %>% + split_rows_by("ARMCD", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f_pbmin$ARMCD)) %>% + add_rowcounts() %>% + analyze_vars("BNRIND", denom = "N_row", .stats = "count_fraction") %>% + append_varlabels(adeg_f_pbmin, c("BNRIND"), indent = 1L) + +result <- build_table( + lyt = lyt, + df = adeg_f_pbmin +) + +result +``` + +## Table of Baseline Versus
Maximum Post-Baseline + +For the EGT03 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. +For illustration purpose, missing data are added to the example dataset. + +```{r variant2, test = list(result_v2 = "result")} +set.seed(123, kind = "Mersenne-Twister") + +adeg_f_pbmax$BNRIND <- factor( + adeg_f_pbmax$BNRIND, + levels = c("LOW", "NORMAL", "HIGH", "Missing"), + labels = c("LOW", "NORMAL", "HIGH", "Missing") +) +adeg_f_pbmax$ANRIND <- factor( + adeg_f_pbmax$ANRIND, + levels = c("LOW", "NORMAL", "HIGH", "Missing"), + labels = c("LOW", "NORMAL", "HIGH", "Missing") +) + +adeg_f_pbmax$BNRIND[sample(1:nrow(adeg_f_pbmax), size = 5)] <- "Missing" +adeg_f_pbmax$ANRIND[sample(1:nrow(adeg_f_pbmax), size = 5)] <- "Missing" + +attr(adeg_f_pbmax$ANRIND, "label") <- "Analysis Reference Range Indicator" +attr(adeg_f_pbmax$BNRIND, "label") <- "Baseline Reference Range Indicator" + +# Temporary solution for overarching column +adeg_f_pbmax <- adeg_f_pbmax %>% mutate(max_label = "Maximum Post-Baseline Assessment") + +# Define the split function +split_fun <- drop_split_levels + +lyt <- basic_table() %>% + split_cols_by("max_label") %>% + split_cols_by("ANRIND") %>% + split_rows_by("ARMCD", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f_pbmax$ARMCD)) %>% + add_rowcounts() %>% + analyze_vars("BNRIND", denom = "N_row", .stats = "count_fraction") %>% + append_varlabels(adeg_f_pbmax, c("BNRIND"), indent = 1L) + +result <- build_table( + lyt = lyt, + df = adeg_f_pbmax +) + +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| screenshot.opts = list(delay = 16) + +library(dplyr) +library(tern) +library(scda) +library(teal.modules.clinical) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +app <- init( + data = cdisc_data( + cdisc_dataset("ADSL", adsl, code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl")'), + cdisc_dataset("ADEG", adeg, code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg")'), + check = TRUE + ), + modules = modules( + tm_t_shift_by_arm( + label = "Shift by Arm Table", + dataname = "ADEG", + arm_var = choices_selected( + variable_choices(adsl, subset = c("ARM", "ARMCD")), + selected = "ARM" + ), + paramcd = choices_selected( + value_choices(adeg, "PARAMCD"), + selected = "HR" + ), + visit_var = choices_selected( + value_choices(adeg, "AVISIT"), + selected = "POST-BASELINE MINIMUM" + ), + aval_var = choices_selected( + variable_choices(adeg, subset = "ANRIND"), + selected = "ANRIND", fixed = TRUE + ), + base_var = choices_selected( + variable_choices(adeg, subset = "BNRIND"), + selected = "BNRIND", fixed = TRUE + ), + treatment_flag_var = choices_selected( + variable_choices(adeg, subset = "ONTRTFL"), + selected = "ONTRTFL", fixed = TRUE + ), + treatment_flag = choices_selected( + value_choices(adeg, "ONTRTFL"), + selected = "Y", fixed = TRUE + ) + ) + ), + filter = list(ADSL = list(SAFFL = "Y")) +) + +shinyApp(app$ui, app$server) +``` + +{{< include ../../repro.qmd >}} + +::: diff --git a/book/tables/ECG/egt04.qmd b/book/tables/ECG/egt04.qmd new file mode 100644 index 0000000000..fb960b9b2a --- /dev/null +++ b/book/tables/ECG/egt04.qmd @@ -0,0 +1,100 @@ +--- +title: EGT04 +subtitle: Shift Table of Qualitative ECG Assessments +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +For the EGT04 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. +For illustration purposes, missing data are added to the example dataset. + +```{r setup, message=FALSE} +#| code-fold: show + +library(scda) +library(tern) +library(dplyr) +set.seed(123) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg, omit_columns = c("AVALC", "BASEC")) + +adeg_labels <- var_labels(adeg) + +adeg_f <- subset( + adeg, + PARAMCD == "ECGINTP" & # Analysis in terms of "NORMAL"/"ABNORMAL" (AVALC) + SAFFL == "Y" & # "Safety Population Flag" + ONTRTFL == "Y" & # "On Treatment Record Flag" + WORS02FL == "Y" # "Worst Post-Baseline Observation" +) + +adeg_f$AVALC[sample(1:nrow(adeg_f), size = 5)] <- "Missing" +adeg_f$BASEC[sample(1:nrow(adeg_f), size = 5)] <- "Missing" +adeg_f$AVALC <- factor( + adeg_f$AVALC, + levels = c("NORMAL", "ABNORMAL", "Missing"), + labels = c("Normal", "Abnormal", "Missing") +) +adeg_f$BASEC <- factor( + adeg_f$BASEC, + levels = c("NORMAL", "ABNORMAL", "Missing"), + labels = c("Normal", "Abnormal", "Missing") +) + +var_labels(adeg_f) <- adeg_labels +adeg_f <- adeg_f %>% + var_relabel(BASEC = "Baseline") + +# Temprary solution for over arching column +adeg_f <- adeg_f %>% mutate(postbaseline_label = "Post-Baseline") +``` + +## Standard Table + +The EGT04 template consists of a stacked list of contingency tables, one per group. +For each group, the n's across all cells must add up to the group N in the analysis, and percentages are calculated using N as the denominator. + +```{r variant1, test = list(result_v1 = "result")} +# Define the split function +split_fun <- drop_split_levels + +lyt <- basic_table() %>% + split_cols_by("postbaseline_label") %>% + split_cols_by("AVALC") %>% + split_rows_by("ARM", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$ARM)) %>% + add_rowcounts() %>% + analyze_vars( + "BASEC", + denom = "N_row", + .stats = "count_fraction", + na.rm = FALSE + ) %>% + append_varlabels(adeg_f, c("BASEC"), indent = 1L) + +result <- build_table(lyt, adeg_f) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} + +::: diff --git a/book/tables/ECG/egt05_qtcat.qmd b/book/tables/ECG/egt05_qtcat.qmd new file mode 100644 index 0000000000..db249bacc5 --- /dev/null +++ b/book/tables/ECG/egt05_qtcat.qmd @@ -0,0 +1,255 @@ +--- +title: EGT05_QTCAT +subtitle: ECG Actual Values and Changes from Baseline by Visit +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(tern) +library(scda) +library(dplyr) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg) + +adeg_labels <- var_labels(adeg) +adeg_f <- adeg %>% + filter( + PARAMCD == "QT", + ANL01FL == "Y" + ) %>% + mutate( + AVALCAT1 = case_when( + AVAL <= 450 ~ "<=450 msec", + AVAL <= 480 ~ ">450 to <=480 msec", + AVAL <= 500 ~ ">480 to <= 500 msec", + AVAL > 500 ~ ">500 msec", + is.na(AVAL) ~ "" + ), + CHGCAT1 = case_when( + CHG <= 30 ~ "<=30 msec", + CHG <= 60 ~ ">30 to <=60 msec", + CHG > 60 ~ ">60 msec", + is.na(CHG) ~ "" + ) + ) %>% + mutate( + AVALCAT1 = factor( + AVALCAT1, + levels = c( + "<=450 msec", + ">450 to <=480 msec", + ">480 to <= 500 msec", + ">500 msec", + "" + ) + ), + CHGCAT1 = factor( + CHGCAT1, + levels = c( + "<=30 msec", + ">30 to <=60 msec", + ">60 msec", + "" + ) + ) + ) %>% + var_relabel( + AVALCAT1 = "Value at Visit", + CHGCAT1 = "Change from Baseline" + ) +``` + +## Standard Table + +```{r variant1, test = list(result_v1 = "result")} +split_fun <- drop_split_levels + +lyt <- basic_table(show_colcounts = TRUE) %>% + split_cols_by("ARM") %>% + split_rows_by( + "PARAM", + split_label = obj_label(adeg_f$PARAM), + split_fun = split_fun, + label_pos = "topleft" + ) %>% + split_rows_by( + "AVISIT", + split_label = obj_label(adeg_f$AVISIT), + split_fun = split_fun, + label_pos = "topleft" + ) %>% + analyze_vars( + vars = c("AVALCAT1", "CHGCAT1"), + var_labels = c("Value at Visit", "Change from Baseline") + ) %>% + append_topleft(" Category") + +result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) %>% + prune_table() + +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| screenshot.opts = list(delay = 24) + +library(teal.modules.clinical) +library(scda) +library(dplyr) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg) +adeg_labels <- var_labels(adeg) + +adeg_f <- adeg %>% + filter( + ANL01FL == "Y" # no need to filter for PARAMCD here + ) %>% + mutate( + AVALCAT1 = case_when( + AVAL <= 450 ~ "<=450 msec", + AVAL <= 480 ~ ">450 to <=480 msec", + AVAL <= 500 ~ ">480 to <= 500 msec", + AVAL > 500 ~ ">500 msec", + is.na(AVAL) ~ "" + ), + CHGCAT1 = case_when( + CHG <= 30 ~ "<=30 msec", + CHG <= 60 ~ ">30 to <=60 msec", + CHG > 60 ~ ">60 msec", + is.na(CHG) ~ "" + ) + ) %>% + mutate( + AVALCAT1 = factor( + AVALCAT1, + levels = c( + "<=450 msec", + ">450 to <=480 msec", + ">480 to <= 500 msec", + ">500 msec", + "" + ) + ), + CHGCAT1 = factor( + CHGCAT1, + levels = c( + "<=30 msec", + ">30 to <=60 msec", + ">60 msec", + "" + ) + ) + ) +var_labels(adeg_f) <- c( + adeg_labels, + "AVALCAT1" = "Value at Visit", + "CHGCAT1" = "Change from Baseline" +) +app <- init( + data = cdisc_data( + cdisc_dataset("ADSL", + adsl, + code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl") + ADSL <- df_explicit_na(ADSL)' + ), + cdisc_dataset("ADEG", + adeg_f, + code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg") + ADEG <- df_explicit_na(ADEG) + ADEG_labels <- var_labels(ADEG) + + ADEG <- ADEG %>% + filter( + ANL01FL == "Y" + ) %>% + mutate( + AVALCAT1 = case_when( + AVAL <= 450 ~ "<=450 msec", + AVAL <= 480 ~ ">450 to <=480 msec", + AVAL <= 500 ~ ">480 to <= 500 msec", + AVAL > 500 ~ ">500 msec", + is.na(AVAL) ~ ""), + CHGCAT1 = case_when( + CHG <= 30 ~ "<=30 msec", + CHG <= 60 ~ ">30 to <=60 msec", + CHG > 60 ~ ">60 msec", + is.na(CHG) ~ "") + ) %>% mutate( + AVALCAT1 = factor( + AVALCAT1, + levels = c( + "<=450 msec", + ">450 to <=480 msec", + ">480 to <= 500 msec", + ">500 msec", + "" + ) + ), + CHGCAT1 = factor( + CHGCAT1, + levels = c( + "<=30 msec", + ">30 to <=60 msec", + ">60 msec", + "" + ) + ) + ) + var_labels(ADEG) <- c( + ADEG_labels, + "AVALCAT1" = "Value at Visit", + "CHGCAT1" = "Change from Baseline" + )' + ), + check = TRUE + ), + modules = modules( + tm_t_summary_by( + label = "ECG Actual Values and Changes from Baseline by Visit", + dataname = "ADEG", + arm_var = choices_selected( + choices = variable_choices(adsl, c("ARM", "ARMCD")), + selected = "ARM" + ), + by_vars = choices_selected( + choices = variable_choices(adeg_f, c("PARAM", "AVISIT")), + selected = c("AVISIT") + ), + summarize_vars = choices_selected( + choices = variable_choices(adeg_f, c("AVALCAT1", "CHGCAT1")), + selected = c("AVALCAT1", "CHGCAT1") + ), + useNA = "ifany", + paramcd = choices_selected( + choices = value_choices(adeg_f, "PARAMCD", "PARAM"), + selected = "QT" + ) + ) + ) +) + +shinyApp(app$ui, app$server) +``` + +{{< include ../../repro.qmd >}} +::: From ba2fd8fef439b93adb8b51cf74aab4431a59b241 Mon Sep 17 00:00:00 2001 From: Emily de la Rua <59304861+edelarua@users.noreply.github.com> Date: Thu, 21 Sep 2023 12:48:16 -0400 Subject: [PATCH 05/11] Delete ada directory Signed-off-by: Emily de la Rua <59304861+edelarua@users.noreply.github.com> --- book/tables/ada/adat01.qmd | 230 ---------------------------------- book/tables/ada/adat02.qmd | 151 ----------------------- book/tables/ada/adat03.qmd | 131 -------------------- book/tables/ada/adat04a.qmd | 240 ------------------------------------ book/tables/ada/adat04b.qmd | 223 --------------------------------- 5 files changed, 975 deletions(-) delete mode 100644 book/tables/ada/adat01.qmd delete mode 100644 book/tables/ada/adat02.qmd delete mode 100644 book/tables/ada/adat03.qmd delete mode 100644 book/tables/ada/adat04a.qmd delete mode 100644 book/tables/ada/adat04b.qmd diff --git a/book/tables/ada/adat01.qmd b/book/tables/ada/adat01.qmd deleted file mode 100644 index 31a13bd819..0000000000 --- a/book/tables/ada/adat01.qmd +++ /dev/null @@ -1,230 +0,0 @@ ---- -title: ADAT01 -subtitle: Baseline Prevalence and Incidence of Treatment Emergent ADA ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(tern) -library(dplyr) -library(scda) -library(tibble) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adab <- synthetic_cdisc_dataset("latest", "adab") - -combodf <- tribble( - ~valname, ~label, ~levelcombo, ~exargs, - "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), - "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() -) - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adab <- adab %>% - filter(PARCAT1 == "A: Drug X Antibody") %>% - select(-ARRLT, -NRRLT) - -# Baseline Pts -adab_b <- df_explicit_na(adab) %>% - filter( - ABLFL == "Y", - ADABLPFL == "Y", - PARAM %in% c("ADA interpreted per sample result") - ) %>% - select(-PARAMCD, -AVALC, -AVALU) %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate_at( - c("ADA interpreted per sample result"), - as.logical - ) %>% - mutate( - ADABLPFL = ADABLPFL == "Y", - PADABLPFL = `ADA interpreted per sample result` == "TRUE", - NADABLPFL = `ADA interpreted per sample result` == "FALSE" - ) %>% - var_relabel( - ADABLPFL = "Baseline evaluable patients", - PADABLPFL = "Patient with a positive sample at baseline", - NADABLPFL = "Patient with no positive samples at baseline" - ) - -# Post Baseline Treatment Enhanced NAb positive Pts -adab_pb <- df_explicit_na(adab) %>% - filter( - ABLFL != "Y", - ADPBLPFL == "Y", - PARAM %in% c( - "ADA interpreted per sample result", - "Treatment Emergent - Positive", - "Treatment induced ADA", - "Treatment enhanced ADA", - "Treatment Emergent - Negative", - "Treatment unaffected" - ) - ) %>% - select(-PARAMCD, -AVALC, -AVALU) %>% - unique() %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate( - across( - any_of(c( - "ADA interpreted per sample result", "Treatment Emergent - Positive", - "Treatment induced ADA", "Treatment enhanced ADA", - "Treatment Emergent - Negative", "Treatment unaffected" - )), - as.logical - ) - ) %>% - mutate( - ADPBLPFL = ADPBLPFL == "Y", - PTEFL = if (exists("Treatment Emergent - Positive", where = .)) `Treatment Emergent - Positive` == "TRUE" else FALSE, - TIFL = if (exists("Treatment induced ADA", where = .)) `Treatment induced ADA` == "TRUE" else FALSE, - TEFL = if (exists("Treatment enhanced ADA", where = .)) `Treatment enhanced ADA` == "TRUE" else FALSE, - NTEFL = if (exists("Treatment Emergent - Negative", where = .)) `Treatment Emergent - Negative` == "TRUE" else FALSE, - TUFL = if (exists("Treatment unaffected", where = .)) `Treatment unaffected` == "TRUE" else FALSE - ) %>% - var_relabel( - ADPBLPFL = "Post-baseline evaluable patients", - PTEFL = "Patient positive for Treatment Emergent ADA", - TIFL = "Treatment-induced ADA", - TEFL = "Treatment-enhanced ADA", - NTEFL = "Patient negative for Treatment Emergent ADA", - TUFL = "Treatment unaffected" - ) -``` - -## Standard Table - -```{r variant1, test = list(result_v1 = "result")} -# Layout for Baseline Prevalence of NAbs -lyt_bl <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "ADABLPFL", - .stats = "count", - var_labels = "Baseline Prevalence of ADAs", - show_labels = "visible", - table_names = "t1" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "PADABLPFL", - table_names = "t2", - .indent_mods = 1L, - var_labels = "a", - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NADABLPFL", - .stats = "count", - show_labels = "hidden", - .indent_mods = 1L, - table_names = "t3" - ) - -# Layout for incidence of NAbs -lyt_pb <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "ADPBLPFL", - .stats = "count", - var_labels = "Incidence of Treatment Emergent ADAs", - show_labels = "visible", - table_names = "tb1" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "PTEFL", - table_names = "tb2", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("TIFL", "TEFL"), - .stats = "count", - table_names = "tb3", - .indent_mods = 2L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NTEFL", - table_names = "tb4", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "TUFL", - .stats = "count", - table_names = "tb5", - .indent_mods = 2L, - show_labels = "hidden" - ) - -result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) -result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) - -# Combine tables. -result_1@col_info <- result_2@col_info -result <- rbind(result_1, result_2) - -# Change the column order. -result <- cbind_rtables(result[, 1], result[, 3]) %>% - cbind_rtables(result[, 4]) %>% - cbind_rtables(result[, 2]) %>% - cbind_rtables(result[, 5]) - -main_title(result) <- paste( - "Baseline Prevalence and Incidence of Treatment Emergent ADA" -) -main_footer(result) <- paste( - "ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient = a patient with an ADA assay result from a baseline sample(s) - Post-baseline evaluable patient = a patient with an ADA assay result from at least one post-baseline sample Number of patients positive for Treatment Emergent - ADA = the number (and percentage) of post-baseline evaluable patients determined to have treatment-induced ADA or treatment-enhanced ADA during the study period. - Treatment-induced ADA = a patient with negative or missing baseline ADA result(s) and at least one positive post-baseline ADA result. - Treatment-enhanced ADA = a patient with positive ADA result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. - Number of patients negative for Treatment Emergent ADA = number of post-baseline evaluable patients with negative or missing baseline ADA result(s) and all negative post-baseline results, or a patient who is treatment unaffected. - Treatment unaffected = A post-baseline evaluable patient with a positive ADA result at baseline and (a) where all post-baseline titer results are less than 0.60 t.u. greater than the baseline titer result, OR (b) where all post-baseline results are negative or missing. - For any positive sample with titer result less than the minimum reportable titer or any positive sample where a titer cannot be obtained, titer value is imputed as equal to the minimum reportable titer." -) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ada/adat02.qmd b/book/tables/ada/adat02.qmd deleted file mode 100644 index 630e8e817e..0000000000 --- a/book/tables/ada/adat02.qmd +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: ADAT02 -subtitle: Summary of Patients with Treatment-Induced ADA ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(tern) -library(dplyr) -library(scda) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adab <- synthetic_cdisc_dataset("latest", "adab") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adab <- df_explicit_na(adab) %>% - mutate(ADPBLPFL = "Y") %>% # temp fix - filter( - ADPBLPFL == "Y", - !PARAM %in% c( - "NAB interpreted per sample result", - "NAB Status of a patient", - "Treatment enhanced ADA" - ) - ) %>% - select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% - unique() %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate( - across( - any_of(c( - "Treatment induced ADA", - "Transient ADA", - "Persistent ADA" - )), - as.logical - ) - ) %>% - mutate( - ADPBLPFL = ADPBLPFL == "Y", - TI_ADA = if (exists("Treatment induced ADA", where = .)) `Treatment induced ADA` else FALSE - ) %>% - var_relabel( - ADPBLPFL = "Post-baseline evaluable patients", - TI_ADA = "Treatment-induced ADA patients" - ) - -adab_ti <- adab %>% - filter(TI_ADA) -``` - -## Standard Table - -```{r variant1, test = list(result_v1 = "result")} -# Layout for post-baseline evaluable patient variables from adab dataset. -lyt_adab <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = drop_split_levels - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "ADPBLPFL", - .stats = "count", - table_names = "post_baseline" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "TI_ADA" - ) - -# Layout for treatment-induced patient variables from adab dataset. -lyt_adab_ti <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = keep_split_levels(c("A: Drug X", "C: Combination", "")) # temp fix - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("Transient ADA", "Persistent ADA"), - var_labels = "Treatment-induced ADA patients with", - show_labels = "visible" - ) %>% - analyze_vars( - "Time to onset of ADA", - .stats = "median", - nested = FALSE, - .labels = c(median = "Median time to onset of ADA (weeks)") - ) %>% - analyze_vars( - "Antibody titer units", - .stats = "range", - nested = FALSE, - .labels = c(range = "ADA titer range (min - max)") - ) - -result_adab <- build_table(lyt_adab, df = adab, alt_counts_df = adsl) -result_adab_ti <- build_table(lyt_adab_ti, df = adab_ti, alt_counts_df = adsl) - -# Combine tables. -col_info(result_adab) <- col_info(result_adab_ti) -result <- rbind( - result_adab, - result_adab_ti -) - -main_title(result) <- paste( - "Summary of Patients with Treatment-Induced ADA, PK Population" -) -subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) -main_footer(result) <- paste( - "ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic - Antibodies) - Treatment-induced ADA = negative or missing baseline. - ADA result(s) and at least one positive post-baseline ADA result. - Transient ADA = ADA positive result detected (a) at only one post-baseline - sampling timepoint (excluding last timepoint) OR (b) at 2 or more timepoints - during treatment where the first and last ADA positive samples are separated - by a period of < 16 weeks, irrespective of any negative samples in between. - Persistent ADA = ADA positive result detected (a) at the last post-baseline - sampling timepoint, OR (b) at 2 or more time points during treatment where - the first and last ADA positive samples are separated by a period ≥ 16 - weeks, irrespective of any negative samples in between." -) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ada/adat03.qmd b/book/tables/ada/adat03.qmd deleted file mode 100644 index 561c5ab1af..0000000000 --- a/book/tables/ada/adat03.qmd +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: ADAT03 -subtitle: Summary of Serum Concentrations at Timepoints Where ADA Samples Were Collected and Analyzed ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(dplyr) -library(scda) -library(tern) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adab <- synthetic_cdisc_dataset("latest", "adab") -adpc <- synthetic_cdisc_dataset("latest", "adpc") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adab <- df_explicit_na(adab) -adpc <- df_explicit_na(adpc) - -# Adjust zzz parameter -max_conc <- 15 - -adpc <- adpc %>% select(USUBJID, NFRLT, AVAL, AVALU, AVALCAT1) - -anl <- adab %>% - filter(., PARAM == "ADA interpreted per sample result") %>% - select(-AVAL, AVALC, AVALU) - -anl <- merge(anl, adpc, by = c("USUBJID", "NFRLT")) %>% - mutate(AVAL_LT = ifelse(AVAL <= max_conc, TRUE, FALSE)) -``` - -## Standard Table (μg/mL) - -```{r variant1, test = list(result_v1 = "result")} -# parameters in columns -adat03_stats <- c("n", "mean", "sd", "median", "min", "max", "cv", "geom_mean", "count_fraction") -adat03_lbls <- c( - n = "Total Number\nof Measurable\n Samples", - mean = "Mean", - sd = "SD", - median = "Median", - min = "Minimum", - max = "Maximum", - cv = "CV (%)", - geom_mean = "Geometric Mean", - count_fraction = paste0("Samples with\nConcentration\n≤ ", max_conc, "μg/mL") -) -adat03_fmts <- c( - n = "xx.", - mean = sprintf_format("%.3e"), - sd = sprintf_format("%.3e"), - median = sprintf_format("%.3e"), - min = sprintf_format("%.3e"), - max = sprintf_format("%.3e"), - cv = "xx.x", - geom_mean = sprintf_format("%.3e"), - count_fraction = format_count_fraction -) - -afun_list <- lapply( - 1:9, - function(i) make_afun(s_summary, .stats = adat03_stats[i], .formats = adat03_fmts[i], .labels = "Overall") -) - -# lyt creation -lyt <- basic_table() %>% - split_rows_by( - var = "ARM", - label_pos = "topleft", - split_label = "Treatment Group", - split_fun = drop_split_levels, - section_div = "" - ) %>% - add_rowcounts() %>% - split_rows_by( - var = "VISIT", - label_pos = "topleft", - split_label = "Visit", - split_fun = drop_split_levels, - child_labels = "hidden" - ) %>% - analyze_vars_in_cols( - vars = c(rep("AVAL", 8), "AVAL_LT"), - .stats = adat03_stats, - .labels = adat03_lbls, - .formats = adat03_fmts - ) %>% - analyze_colvars( - afun_list, - nested = FALSE, - extra_args = list(".labels" = "Overall") - ) - -result <- build_table(lyt, anl, alt_counts_df = adsl) - -main_title(result) <- paste( - "Summary of Serum Concentrations (μg/mL) at Timepoints Where ADA Samples Were Collected and Analyzed\n - Protocol:", unique(adab$PARCAT1)[1] -) -subtitles(result) <- paste("Analyte:", unique(adab$PARAMCD)[1]) -fnotes_at_path(result, rowpath = NULL, colpath = c("multivars", "AVAL")) <- "Refers to the total no. of measurable ADA samples that have a corresponding measurable drug concentration sample (i.e. results with -valid numeric values and LTRs). LTR results on post-dose samples are replaced by aaa µg/mL i.e. half of MQC value." -fnotes_at_path(result, rowpath = NULL, colpath = c("multivars", "AVAL_LT")) <- "In validation, the assay was able to detect yyy ng/mL of surrogate ADA in the presence of zzz µg/mL of [drug]. BLQ = Below Limit of -Quantitation, LTR = Lower than Reportable, MQC = Minimum Quantifiable Concentration, ADA = Anti-Drug Antibodies (is also referred to as ATA, -or Anti-Therapeutic Antibodies). RXXXXXXX is also known as [drug]" - -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ada/adat04a.qmd b/book/tables/ada/adat04a.qmd deleted file mode 100644 index 3a3f56d998..0000000000 --- a/book/tables/ada/adat04a.qmd +++ /dev/null @@ -1,240 +0,0 @@ ---- -title: ADAT04A -subtitle: Baseline Prevalence and Incidence of Treatment Emergent NAbs ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(tern) -library(dplyr) -library(scda) -library(tibble) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adab <- synthetic_cdisc_dataset("latest", "adab") - -combodf <- tribble( - ~valname, ~label, ~levelcombo, ~exargs, - "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), - "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() -) - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) - -# Baseline Pts -adab_b <- df_explicit_na(adab) %>% - filter( - ABLFL == "Y", - ADABLPFL == "Y", - PARAM %in% c( - "ADA interpreted per sample result", - "NAB interpreted per sample result" - ) - ) %>% - select(-PARAMCD, -AVALC, -AVALU) %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate( - across( - any_of(c( - "ADA interpreted per sample result", - "NAB interpreted per sample result" - )), - as.logical - ) - ) %>% - mutate( - ADABLPFL = ADABLPFL == "Y", - PADABLPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, - PNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "TRUE" else FALSE, - NNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE - ) %>% - var_relabel( - ADABLPFL = "Baseline evaluable patients for ADA", - PADABLPFL = "Patients with a positive ADA sample at baseline", - PNABBLFL = "Patients with a positive NAb sample at baseline", - NNABBLFL = "Patient with no positive NAb samples at baseline" - ) - -# Post Baseline Treatment Enhanced NAb positive Pts -adab_pb <- df_explicit_na(adab) %>% - filter( - ABLFL != "Y", - ADPBLPFL == "Y", - PARAM %in% c( - "ADA interpreted per sample result", - "Treatment Emergent - Positive, Neutralizing Antibody", - "Treatment induced ADA, Neutralizing Antibody", - "Treatment enhanced ADA, Neutralizing Antibody", - "NAB interpreted per sample result", - "Treatment unaffected, Neutralizing Antibody" - ) - ) %>% - select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% - unique() %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate( - across( - any_of(c( - "ADA interpreted per sample result", "NAB interpreted per sample result", - "Treatment Emergent - Positive, Neutralizing Antibody", - "Treatment induced ADA, Neutralizing Antibody", - "Treatment enhanced ADA, Neutralizing Antibody", - "Treatment unaffected, Neutralizing Antibody" - )), - as.logical - ) - ) %>% - mutate( - ADPBLPFL = ADPBLPFL == "Y", - ADAPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, - TENABPFL = if (exists("Treatment Emergent - Positive, Neutralizing Antibody", where = .)) `Treatment Emergent - Positive, Neutralizing Antibody` == "TRUE" else FALSE, - TINPBFL = if (exists("Treatment induced ADA, Neutralizing Antibody", where = .)) `Treatment induced ADA, Neutralizing Antibody` == "TRUE" else FALSE, - TENPBFL = if (exists("Treatment enhanced ADA, Neutralizing Antibody", where = .)) `Treatment enhanced ADA, Neutralizing Antibody` == "TRUE" else FALSE, - NABNFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE, - TUNPBFL = if (exists("Treatment unaffected, Neutralizing Antibody", where = .)) `Treatment unaffected, Neutralizing Antibody` == "TRUE" else FALSE - ) %>% - var_relabel( - ADPBLPFL = "Post-baseline evaluable patients for ADA", - ADAPFL = "Patients positive for ADA", - TENABPFL = "Patients positive for Treatment Emergent NAb", - TINPBFL = "Treatment-induced NAb", - TENPBFL = "Treatment-enhanced NAb", - NABNFL = "Patients negative for NAb", - TUNPBFL = "Treatment unaffected" - ) -``` - -## Summary of Treatment Emergent NAbs - -```{r variant1, test = list(result_v1 = "result")} -# Layout for Baseline Prevalence of NAbs -lyt_bl <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("ADABLPFL", "PADABLPFL"), - table_names = "t1", - .stats = "count", - var_labels = "Baseline Prevalence of NAbs", - show_labels = "visible" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "PNABBLFL", - table_names = "t2", - .indent_mods = 1L - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NNABBLFL", - .stats = "count", - table_names = "t3", - .indent_mods = 1L, - show_labels = "hidden" - ) - -# Layout for incidence of NAbs -lyt_pb <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("ADPBLPFL", "ADAPFL"), - .stats = "count", - var_labels = "Incidence of Treatment Emergent NAbs", - show_labels = "visible", - table_names = "tb1" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "TENABPFL", - table_names = "tb2", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("TINPBFL", "TENPBFL"), - .stats = "count", - table_names = "tb3", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NABNFL", - table_names = "tb4", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "TUNPBFL", - .stats = "count", - table_names = "tb5", - .indent_mods = 1L, - show_labels = "hidden" - ) - -result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) -result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) - -# Combine tables -result <- rbind(result_1, result_2) - -# Change the column order -result <- cbind_rtables(result[, 1], result[, 3]) %>% - cbind_rtables(result[, 4]) %>% - cbind_rtables(result[, 2]) %>% - cbind_rtables(result[, 5]) - -main_title(result) <- paste( - "Baseline Prevalence and Incidence of Treatment Emergent NAbs" -) -subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) -main_footer(result) <- paste( - "NAb = Neutralizing Antibodies ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient for ADA = a patient with an ADA assay result from a baseline sample(s) - Baseline evaluable patient for NAb = a patient with a NAb assay result from a baseline sample(s) - Post-baseline evaluable patient for ADA = a patient with an ADA assay result from at least one post-baseline sample - Post-baseline evaluable patient for NAb = a patient with a NAb assay result from at least one post-baseline sample - Number of patients positive for ADA = the number of post-baseline evaluable patients for ADA determined to have Treatment Emergent ADA during the study period. -Number of patients positive for Treatment Emergent NAb = the number (and percentage) of post-baseline evaluable patients for ADA determined to have treatment-induced NAb or treatment-enhanced NAb during the study period. -Treatment-induced = a patient with negative or missing baseline result(s) and at least one positive post-baseline result. Treatment-enhanced = a patient with positive result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. -Number of patients negative for Treatment Emergent NAb = number of post-baseline evaluable patients with negative or missing baseline NAb result(s) and all negative post-baseline NAb results, or a patient who is NAb treatment unaffected. -Treatment unaffected = A post-baseline evaluable patient with a positive result at baseline and (a) where all post-baseline titer results are less than 0.60 t.u. greater than the baseline titer result, OR (b) where all post-baseline results are negative or missing. For any positive sample with titer result less than the minimum reportable titer or any positive sample where a titer cannot be obtained, titer value is imputed as equal to the minimum reportable titer." -) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ada/adat04b.qmd b/book/tables/ada/adat04b.qmd deleted file mode 100644 index 5994f04002..0000000000 --- a/book/tables/ada/adat04b.qmd +++ /dev/null @@ -1,223 +0,0 @@ ---- -title: ADAT04B -subtitle: Baseline Prevalence and Incidence of NAbs ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(tern) -library(dplyr) -library(scda) -library(tibble) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adab <- synthetic_cdisc_dataset("latest", "adab") - -combodf <- tribble( - ~valname, ~label, ~levelcombo, ~exargs, - "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), - "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() -) - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) - -# Baseline Pts -adab_b <- df_explicit_na(adab) %>% - filter( - ABLFL == "Y", - ADABLPFL == "Y", - PARAM %in% c( - "ADA interpreted per sample result", - "NAB interpreted per sample result" - ) - ) %>% - select(-PARAMCD, -AVALC, -AVALU) %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate( - across( - any_of(c( - "ADA interpreted per sample result", - "NAB interpreted per sample result" - )), - as.logical - ) - ) %>% - mutate( - ADABLPFL = ADABLPFL == "Y", - PADABLPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, - PNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "TRUE" else FALSE, - NNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE - ) %>% - var_relabel( - ADABLPFL = "Baseline evaluable patients for ADA", - PADABLPFL = "Patients with a positive ADA sample at baseline", - PNABBLFL = "Patients with a positive NAb sample at baseline", - NNABBLFL = "Patients with no positive NAb sample at baseline" - ) - -# Post-Baseline Evaluable Pts -adab_pb_ada <- df_explicit_na(adab) %>% - filter(ADPBLPFL == "Y") %>% - select(STUDYID, USUBJID, ARM, ACTARM, ADPBLPFL) %>% - mutate(ADPBLPFL = ADPBLPFL == "Y") %>% - distinct() - -# Post-Baseline ADA Positive Pts -adab_pb_adap <- df_explicit_na(adab) %>% - filter( - ABLFL != "Y", - PARAM == "ADA interpreted per sample result", - AVALC == "POSITIVE" - ) %>% - mutate(ADAPFL = AVALC == "POSITIVE") %>% - select(STUDYID, USUBJID, ARM, ACTARM, ADAPFL) %>% - distinct() - -# Post-Baseline NAb Positive Pts -adab_pb_nabp <- df_explicit_na(adab) %>% - filter( - ABLFL != "Y", - PARAM == "NAb interpreted per sample result", - AVALC == "POSITIVE" - ) %>% - mutate(NABPFL = AVALC == "POSITIVE") %>% - select(STUDYID, USUBJID, ARM, ACTARM, NABPFL) %>% - distinct() - -# Post-Baseline NAb Negative Pts -adab_pb_nabn <- df_explicit_na(adab) %>% - filter( - ABLFL != "Y", - PARAM == "NAb interpreted per sample result", - AVALC == "NEGATIVE" - ) %>% - rename(NABNFL = AVALC) %>% - select(STUDYID, USUBJID, ARM, ACTARM, NABNFL) %>% - distinct() - -mergecol <- c("STUDYID", "USUBJID", "ARM", "ACTARM") - -adab_pb <- left_join(adab_pb_ada, adab_pb_adap, by = mergecol) %>% - left_join(adab_pb_nabp, by = mergecol) %>% - mutate( - NABNFL = ifelse(is.na(NABPFL), "TRUE", "FALSE"), - NABNFL = NABNFL == "TRUE" - ) %>% - var_relabel( - ADPBLPFL = "Post-baseline evaluable patients for ADA", - ADAPFL = "Patients positive for ADA", - NABPFL = "Patients positive for NAb", - NABNFL = "Patients negative for NAb" - ) -``` - -## Standard Table - -```{r variant1, test = list(result_v1 = "result")} -# Layout for Baseline Prevalence of NAbs -lyt_bl <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("ADABLPFL", "PADABLPFL"), - .stats = "count", - var_labels = "Baseline Prevalence of NAbs", - show_labels = "visible", - table_names = "t1" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "PNABBLFL", - table_names = "t2", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NNABBLFL", - .stats = "count", - table_names = "t3", - .indent_mods = 1L, - show_labels = "hidden" - ) - -# Layout for incidence of NAbs -lyt_pb <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("ADPBLPFL", "ADAPFL"), - .stats = "count", - var_labels = "Incidence of NAbs", - show_labels = "visible", - table_names = "tb1" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NABPFL", - table_names = "tb2", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NABNFL", - .stats = "count", - table_names = "tb3", - .indent_mods = 1L, - show_labels = "hidden" - ) - -result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) -result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) - -# Combine tables. -result <- rbind(result_1, result_2) - -# Change the column order. -result <- cbind_rtables(result[, 1], result[, 3]) %>% - cbind_rtables(result[, 4]) %>% - cbind_rtables(result[, 2]) %>% - cbind_rtables(result[, 5]) - -main_title(result) <- paste( - "Baseline Prevalence and Incidence of Neutralizing Antibodies (NAbs)" -) -subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) -main_footer(result) <- paste( - "NAb = Neutralizing Antibodies ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient for ADA = a patient with an ADA assay result from a baseline sample(s) Baseline evaluable patient for NAb = a patient with a NAb assay result from a baseline sample(s) Post-baseline evaluable patient for ADA = a patient with an ADA assay result from at least one post-baseline sample Post-baseline evaluable patient for NAb = a patient with a NAb assay result from at least one post-baseline sample Number of patients positive for ADA = the number of post-baseline evaluable patients for ADA determined to have Treatment Emergent ADA during the study period. -Number of patients positive for NAb = the number (and percentage) of post-baseline evaluable patients for ADA determined to have at least one positive post-baseline NAb result during the study period. Number of patients negative for NAb = number of post-baseline evaluable patients with all negative post-baseline NAb results." -) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} -::: From eb1abcf553faa0dead5b0876f52925b747c73ed9 Mon Sep 17 00:00:00 2001 From: Emily de la Rua <59304861+edelarua@users.noreply.github.com> Date: Thu, 21 Sep 2023 12:48:53 -0400 Subject: [PATCH 06/11] Delete tables/ecg directory Signed-off-by: Emily de la Rua <59304861+edelarua@users.noreply.github.com> --- book/tables/ecg/egt01.qmd | 142 ------------------ book/tables/ecg/egt02.qmd | 126 ---------------- book/tables/ecg/egt03.qmd | 204 ------------------------- book/tables/ecg/egt04.qmd | 100 ------------- book/tables/ecg/egt05_qtcat.qmd | 255 -------------------------------- 5 files changed, 827 deletions(-) delete mode 100644 book/tables/ecg/egt01.qmd delete mode 100644 book/tables/ecg/egt02.qmd delete mode 100644 book/tables/ecg/egt03.qmd delete mode 100644 book/tables/ecg/egt04.qmd delete mode 100644 book/tables/ecg/egt05_qtcat.qmd diff --git a/book/tables/ecg/egt01.qmd b/book/tables/ecg/egt01.qmd deleted file mode 100644 index 017188e635..0000000000 --- a/book/tables/ecg/egt01.qmd +++ /dev/null @@ -1,142 +0,0 @@ ---- -title: EGT01 -subtitle: ECG Results and Change from Baseline by Visit ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(dplyr) -library(tern) -library(scda) - -# Data should be filtered for the studied Parameter (`PARAM`) and the -# Analysis Visit (`AVISIT`). According to the GDSR template, the values for -# the `AVISIT` reported in the EGT01 standard may be: -# 'POST-BASELINE MAXIMUM', 'POST-BASELINE MINIMUM', 'POST-BASELINE LAST'. - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg) - -adeg_f <- adeg %>% - filter(ANL01FL == "Y") %>% - filter(PARAM %in% c("Heart Rate", "QT Duration", "RR Duration")) -``` - -## Standard Table - -```{r variant1, test = list(result_v1 = "result")} -# Define the split function -split_fun <- drop_split_levels - -afun <- function(x, .var, .spl_context, ...) { - n_fun <- sum(!is.na(x), na.rm = TRUE) - if (n_fun == 0) { - mean_sd_fun <- c(NA, NA) - median_fun <- NA - min_max_fun <- c(NA, NA) - } else { - mean_sd_fun <- c(mean(x, na.rm = TRUE), sd(x, na.rm = TRUE)) - median_fun <- median(x, na.rm = TRUE) - min_max_fun <- c(min(x), max(x)) - } - is_chg <- .var == "CHG" - is_baseline <- .spl_context$value[which(.spl_context$split == "AVISIT")] == "BASELINE" - if (is_baseline && is_chg) n_fun <- mean_sd_fun <- median_fun <- min_max_fun <- NULL - - in_rows( - "n" = n_fun, - "Mean (SD)" = mean_sd_fun, - "Median" = median_fun, - "Min - Max" = min_max_fun, - .formats = list("n" = "xx", "Mean (SD)" = "xx.xx (xx.xx)", "Median" = "xx.xx", "Min - Max" = "xx.xx - xx.xx"), - .format_na_strs = list("n" = "NE", "Mean (SD)" = "NE (NE)", "Median" = "NE", "Min - Max" = "NE - NE") - ) -} - -lyt <- basic_table(show_colcounts = TRUE) %>% - split_cols_by("ACTARM") %>% - split_rows_by("PARAM", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$PARAM)) %>% - split_rows_by("AVISIT", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$AVISIT)) %>% - split_cols_by_multivar( - vars = c("AVAL", "CHG"), - varlabels = c("Value at Visit", "Change from\nBaseline") - ) %>% - analyze_colvars(afun = afun) - -result <- build_table(lyt, adeg_f, alt_counts_df = adsl) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| screenshot.opts = list(delay = 16) - -library(teal.modules.clinical) -library(scda) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg) - -app <- init( - data = cdisc_data( - cdisc_dataset("ADSL", - adsl, - code = 'ADSL <- df_explicit_na(synthetic_cdisc_dataset("latest", "adsl"))' - ), - cdisc_dataset("ADEG", - adeg, - code = 'ADEG <- df_explicit_na(synthetic_cdisc_dataset("latest", "adeg"))' - ), - check = TRUE - ), - modules = modules( - tm_t_summary_by( - label = "ECG Results and Change from Baseline by Visit", - dataname = "ADEG", - arm_var = choices_selected( - choices = variable_choices(adsl, c("ARM", "ARMCD")), - selected = "ARM" - ), - by_vars = choices_selected( - choices = variable_choices(adeg, c("PARAM", "AVISIT")), - selected = c("AVISIT") - ), - summarize_vars = choices_selected( - choices = variable_choices(adeg, c("AVAL", "CHG")), - selected = c("AVAL") - ), - useNA = "ifany", - paramcd = choices_selected( - choices = value_choices(adeg, "PARAMCD", "PARAM"), - selected = "HR" - ), - parallel_vars = TRUE - ) - ), - filter = list(ADEG = list(AVAL = list())) -) - -shinyApp(app$ui, app$server) -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ecg/egt02.qmd b/book/tables/ecg/egt02.qmd deleted file mode 100644 index addbda506f..0000000000 --- a/book/tables/ecg/egt02.qmd +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: EGT02 -subtitle: ECG Abnormalities (EGT02_1 & EGT02_2) ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(dplyr) -library(scda) -library(tern) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg) - -# Note: We keep only post-baseline for analysis. -adeg_f <- adeg %>% - filter(ONTRTFL == "Y") %>% - filter(PARAM %in% c("Heart Rate", "QT Duration", "RR Duration")) %>% - filter(ANRIND != "") %>% - var_relabel( - PARAM = "Assessment", - ANRIND = "Abnormality" - ) -``` - -## ECG Abnormalities Regardless
of Abnormality at Baseline - -```{r variant1, test = list(result_v1 = "result")} -split_fun <- drop_split_levels - -lyt <- basic_table(show_colcounts = TRUE) %>% - split_cols_by(var = "ACTARM") %>% - split_rows_by( - "PARAM", - split_fun = split_fun, - label_pos = "topleft", - split_label = obj_label(adeg_f$PARAM) - ) %>% - count_abnormal("ANRIND", abnormal = list(Low = "LOW", High = "HIGH"), exclude_base_abn = FALSE) %>% - append_varlabels(adeg_f, "ANRIND", indent = 1L) - -result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) -result -``` - -## ECG Abnormalities Among Subjects
Without Abnormality at Baseline - -```{r variant2, test = list(result_v2 = "result")} -split_fun <- drop_split_levels - -lyt <- basic_table(show_colcounts = TRUE) %>% - split_cols_by(var = "ACTARM") %>% - split_rows_by( - "PARAM", - split_fun = split_fun, - label_pos = "topleft", - split_label = obj_label(adeg_f$PARAM) - ) %>% - count_abnormal("ANRIND", abnormal = list(Low = "LOW", High = "HIGH"), exclude_base_abn = TRUE) %>% - append_varlabels(adeg_f, "ANRIND", indent = 1L) - -result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| screenshot.opts = list(delay = 18) - -library(scda) -library(teal.modules.clinical) -library(dplyr) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -app <- init( - data = cdisc_data( - cdisc_dataset("ADSL", adsl, code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl")'), - cdisc_dataset("ADEG", adeg, code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg")'), - check = TRUE - ), - modules = modules( - tm_t_abnormality( - label = "Abnormality Table", - dataname = "ADEG", - arm_var = choices_selected( - choices = variable_choices(adsl, subset = c("ARM", "ARMCD")), - selected = "ARM" - ), - by_vars = choices_selected( - choices = variable_choices(adeg, subset = c("EGCAT", "PARAM", "AVISIT")), - selected = c("PARAM"), - keep_order = TRUE - ), - grade = choices_selected( - choices = variable_choices(adeg, subset = "ANRIND"), - selected = "ANRIND", - fixed = TRUE - ), - abnormal = list(Low = "LOW", High = "HIGH"), - exclude_base_abn = FALSE - ) - ) -) - -shinyApp(app$ui, app$server) -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ecg/egt03.qmd b/book/tables/ecg/egt03.qmd deleted file mode 100644 index 6d335eb12e..0000000000 --- a/book/tables/ecg/egt03.qmd +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: EGT03 -subtitle: Shift Table of ECG Interval Data -- Baseline Versus Minimum/Maximum Post-Baseline ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(scda) -library(tern) -library(dplyr) - -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adeg <- df_explicit_na(adeg) - -adeg_labels <- var_labels(adeg) - -adeg_f_pbmin <- subset( - adeg, - PARAMCD == "HR" & # Heart Rate - SAFFL == "Y" & # "Safety Population Flag" - ONTRTFL == "Y" & # "On Treatment Record Flag" - AVISIT == "POST-BASELINE MINIMUM" # "Analysis Visit" -) - -adeg_f_pbmax <- subset( - adeg, - PARAMCD == "HR" & # Heart Rate - SAFFL == "Y" & # "Safety Population Flag" - ONTRTFL == "Y" & # "On Treatment Record Flag" - AVISIT == "POST-BASELINE MAXIMUM" # "Analysis Visit" -) - -var_labels(adeg_f_pbmin) <- adeg_labels -var_labels(adeg_f_pbmax) <- adeg_labels -``` - -## Table of Baseline Versus
Minimum Post-Baseline - -For the EGT03 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. -For illustration purposes, missing data are added to the example dataset. - -```{r variant1, test = list(result_v1 = "result")} -set.seed(123, kind = "Mersenne-Twister") - -adeg_f_pbmin$BNRIND <- factor( - adeg_f_pbmin$BNRIND, - levels = c("LOW", "NORMAL", "HIGH", "Missing"), - labels = c("LOW", "NORMAL", "HIGH", "Missing") -) -adeg_f_pbmin$ANRIND <- factor( - adeg_f_pbmin$ANRIND, - levels = c("LOW", "NORMAL", "HIGH", "Missing"), - labels = c("LOW", "NORMAL", "HIGH", "Missing") -) - -adeg_f_pbmin$BNRIND[sample(1:nrow(adeg_f_pbmin), size = 5)] <- "Missing" -adeg_f_pbmin$ANRIND[sample(1:nrow(adeg_f_pbmin), size = 5)] <- "Missing" - -attr(adeg_f_pbmin$ANRIND, "label") <- "Analysis Reference Range Indicator" -attr(adeg_f_pbmin$BNRIND, "label") <- "Baseline Reference Range Indicator" - -# Temporary solution for overarching column -adeg_f_pbmin <- adeg_f_pbmin %>% mutate(min_label = "Minimum Post-Baseline Assessment") - -# Define the split function -split_fun <- drop_split_levels - -lyt <- basic_table() %>% - split_cols_by("min_label") %>% - split_cols_by("ANRIND") %>% - split_rows_by("ARMCD", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f_pbmin$ARMCD)) %>% - add_rowcounts() %>% - analyze_vars("BNRIND", denom = "N_row", .stats = "count_fraction") %>% - append_varlabels(adeg_f_pbmin, c("BNRIND"), indent = 1L) - -result <- build_table( - lyt = lyt, - df = adeg_f_pbmin -) - -result -``` - -## Table of Baseline Versus
Maximum Post-Baseline - -For the EGT03 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. -For illustration purpose, missing data are added to the example dataset. - -```{r variant2, test = list(result_v2 = "result")} -set.seed(123, kind = "Mersenne-Twister") - -adeg_f_pbmax$BNRIND <- factor( - adeg_f_pbmax$BNRIND, - levels = c("LOW", "NORMAL", "HIGH", "Missing"), - labels = c("LOW", "NORMAL", "HIGH", "Missing") -) -adeg_f_pbmax$ANRIND <- factor( - adeg_f_pbmax$ANRIND, - levels = c("LOW", "NORMAL", "HIGH", "Missing"), - labels = c("LOW", "NORMAL", "HIGH", "Missing") -) - -adeg_f_pbmax$BNRIND[sample(1:nrow(adeg_f_pbmax), size = 5)] <- "Missing" -adeg_f_pbmax$ANRIND[sample(1:nrow(adeg_f_pbmax), size = 5)] <- "Missing" - -attr(adeg_f_pbmax$ANRIND, "label") <- "Analysis Reference Range Indicator" -attr(adeg_f_pbmax$BNRIND, "label") <- "Baseline Reference Range Indicator" - -# Temporary solution for overarching column -adeg_f_pbmax <- adeg_f_pbmax %>% mutate(max_label = "Maximum Post-Baseline Assessment") - -# Define the split function -split_fun <- drop_split_levels - -lyt <- basic_table() %>% - split_cols_by("max_label") %>% - split_cols_by("ANRIND") %>% - split_rows_by("ARMCD", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f_pbmax$ARMCD)) %>% - add_rowcounts() %>% - analyze_vars("BNRIND", denom = "N_row", .stats = "count_fraction") %>% - append_varlabels(adeg_f_pbmax, c("BNRIND"), indent = 1L) - -result <- build_table( - lyt = lyt, - df = adeg_f_pbmax -) - -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| screenshot.opts = list(delay = 16) - -library(dplyr) -library(tern) -library(scda) -library(teal.modules.clinical) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -app <- init( - data = cdisc_data( - cdisc_dataset("ADSL", adsl, code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl")'), - cdisc_dataset("ADEG", adeg, code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg")'), - check = TRUE - ), - modules = modules( - tm_t_shift_by_arm( - label = "Shift by Arm Table", - dataname = "ADEG", - arm_var = choices_selected( - variable_choices(adsl, subset = c("ARM", "ARMCD")), - selected = "ARM" - ), - paramcd = choices_selected( - value_choices(adeg, "PARAMCD"), - selected = "HR" - ), - visit_var = choices_selected( - value_choices(adeg, "AVISIT"), - selected = "POST-BASELINE MINIMUM" - ), - aval_var = choices_selected( - variable_choices(adeg, subset = "ANRIND"), - selected = "ANRIND", fixed = TRUE - ), - base_var = choices_selected( - variable_choices(adeg, subset = "BNRIND"), - selected = "BNRIND", fixed = TRUE - ), - treatment_flag_var = choices_selected( - variable_choices(adeg, subset = "ONTRTFL"), - selected = "ONTRTFL", fixed = TRUE - ), - treatment_flag = choices_selected( - value_choices(adeg, "ONTRTFL"), - selected = "Y", fixed = TRUE - ) - ) - ), - filter = list(ADSL = list(SAFFL = "Y")) -) - -shinyApp(app$ui, app$server) -``` - -{{< include ../../repro.qmd >}} - -::: diff --git a/book/tables/ecg/egt04.qmd b/book/tables/ecg/egt04.qmd deleted file mode 100644 index fb960b9b2a..0000000000 --- a/book/tables/ecg/egt04.qmd +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: EGT04 -subtitle: Shift Table of Qualitative ECG Assessments ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -For the EGT04 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. -For illustration purposes, missing data are added to the example dataset. - -```{r setup, message=FALSE} -#| code-fold: show - -library(scda) -library(tern) -library(dplyr) -set.seed(123) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg, omit_columns = c("AVALC", "BASEC")) - -adeg_labels <- var_labels(adeg) - -adeg_f <- subset( - adeg, - PARAMCD == "ECGINTP" & # Analysis in terms of "NORMAL"/"ABNORMAL" (AVALC) - SAFFL == "Y" & # "Safety Population Flag" - ONTRTFL == "Y" & # "On Treatment Record Flag" - WORS02FL == "Y" # "Worst Post-Baseline Observation" -) - -adeg_f$AVALC[sample(1:nrow(adeg_f), size = 5)] <- "Missing" -adeg_f$BASEC[sample(1:nrow(adeg_f), size = 5)] <- "Missing" -adeg_f$AVALC <- factor( - adeg_f$AVALC, - levels = c("NORMAL", "ABNORMAL", "Missing"), - labels = c("Normal", "Abnormal", "Missing") -) -adeg_f$BASEC <- factor( - adeg_f$BASEC, - levels = c("NORMAL", "ABNORMAL", "Missing"), - labels = c("Normal", "Abnormal", "Missing") -) - -var_labels(adeg_f) <- adeg_labels -adeg_f <- adeg_f %>% - var_relabel(BASEC = "Baseline") - -# Temprary solution for over arching column -adeg_f <- adeg_f %>% mutate(postbaseline_label = "Post-Baseline") -``` - -## Standard Table - -The EGT04 template consists of a stacked list of contingency tables, one per group. -For each group, the n's across all cells must add up to the group N in the analysis, and percentages are calculated using N as the denominator. - -```{r variant1, test = list(result_v1 = "result")} -# Define the split function -split_fun <- drop_split_levels - -lyt <- basic_table() %>% - split_cols_by("postbaseline_label") %>% - split_cols_by("AVALC") %>% - split_rows_by("ARM", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$ARM)) %>% - add_rowcounts() %>% - analyze_vars( - "BASEC", - denom = "N_row", - .stats = "count_fraction", - na.rm = FALSE - ) %>% - append_varlabels(adeg_f, c("BASEC"), indent = 1L) - -result <- build_table(lyt, adeg_f) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} - -::: diff --git a/book/tables/ecg/egt05_qtcat.qmd b/book/tables/ecg/egt05_qtcat.qmd deleted file mode 100644 index db249bacc5..0000000000 --- a/book/tables/ecg/egt05_qtcat.qmd +++ /dev/null @@ -1,255 +0,0 @@ ---- -title: EGT05_QTCAT -subtitle: ECG Actual Values and Changes from Baseline by Visit ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(tern) -library(scda) -library(dplyr) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg) - -adeg_labels <- var_labels(adeg) -adeg_f <- adeg %>% - filter( - PARAMCD == "QT", - ANL01FL == "Y" - ) %>% - mutate( - AVALCAT1 = case_when( - AVAL <= 450 ~ "<=450 msec", - AVAL <= 480 ~ ">450 to <=480 msec", - AVAL <= 500 ~ ">480 to <= 500 msec", - AVAL > 500 ~ ">500 msec", - is.na(AVAL) ~ "" - ), - CHGCAT1 = case_when( - CHG <= 30 ~ "<=30 msec", - CHG <= 60 ~ ">30 to <=60 msec", - CHG > 60 ~ ">60 msec", - is.na(CHG) ~ "" - ) - ) %>% - mutate( - AVALCAT1 = factor( - AVALCAT1, - levels = c( - "<=450 msec", - ">450 to <=480 msec", - ">480 to <= 500 msec", - ">500 msec", - "" - ) - ), - CHGCAT1 = factor( - CHGCAT1, - levels = c( - "<=30 msec", - ">30 to <=60 msec", - ">60 msec", - "" - ) - ) - ) %>% - var_relabel( - AVALCAT1 = "Value at Visit", - CHGCAT1 = "Change from Baseline" - ) -``` - -## Standard Table - -```{r variant1, test = list(result_v1 = "result")} -split_fun <- drop_split_levels - -lyt <- basic_table(show_colcounts = TRUE) %>% - split_cols_by("ARM") %>% - split_rows_by( - "PARAM", - split_label = obj_label(adeg_f$PARAM), - split_fun = split_fun, - label_pos = "topleft" - ) %>% - split_rows_by( - "AVISIT", - split_label = obj_label(adeg_f$AVISIT), - split_fun = split_fun, - label_pos = "topleft" - ) %>% - analyze_vars( - vars = c("AVALCAT1", "CHGCAT1"), - var_labels = c("Value at Visit", "Change from Baseline") - ) %>% - append_topleft(" Category") - -result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) %>% - prune_table() - -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| screenshot.opts = list(delay = 24) - -library(teal.modules.clinical) -library(scda) -library(dplyr) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg) -adeg_labels <- var_labels(adeg) - -adeg_f <- adeg %>% - filter( - ANL01FL == "Y" # no need to filter for PARAMCD here - ) %>% - mutate( - AVALCAT1 = case_when( - AVAL <= 450 ~ "<=450 msec", - AVAL <= 480 ~ ">450 to <=480 msec", - AVAL <= 500 ~ ">480 to <= 500 msec", - AVAL > 500 ~ ">500 msec", - is.na(AVAL) ~ "" - ), - CHGCAT1 = case_when( - CHG <= 30 ~ "<=30 msec", - CHG <= 60 ~ ">30 to <=60 msec", - CHG > 60 ~ ">60 msec", - is.na(CHG) ~ "" - ) - ) %>% - mutate( - AVALCAT1 = factor( - AVALCAT1, - levels = c( - "<=450 msec", - ">450 to <=480 msec", - ">480 to <= 500 msec", - ">500 msec", - "" - ) - ), - CHGCAT1 = factor( - CHGCAT1, - levels = c( - "<=30 msec", - ">30 to <=60 msec", - ">60 msec", - "" - ) - ) - ) -var_labels(adeg_f) <- c( - adeg_labels, - "AVALCAT1" = "Value at Visit", - "CHGCAT1" = "Change from Baseline" -) -app <- init( - data = cdisc_data( - cdisc_dataset("ADSL", - adsl, - code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl") - ADSL <- df_explicit_na(ADSL)' - ), - cdisc_dataset("ADEG", - adeg_f, - code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg") - ADEG <- df_explicit_na(ADEG) - ADEG_labels <- var_labels(ADEG) - - ADEG <- ADEG %>% - filter( - ANL01FL == "Y" - ) %>% - mutate( - AVALCAT1 = case_when( - AVAL <= 450 ~ "<=450 msec", - AVAL <= 480 ~ ">450 to <=480 msec", - AVAL <= 500 ~ ">480 to <= 500 msec", - AVAL > 500 ~ ">500 msec", - is.na(AVAL) ~ ""), - CHGCAT1 = case_when( - CHG <= 30 ~ "<=30 msec", - CHG <= 60 ~ ">30 to <=60 msec", - CHG > 60 ~ ">60 msec", - is.na(CHG) ~ "") - ) %>% mutate( - AVALCAT1 = factor( - AVALCAT1, - levels = c( - "<=450 msec", - ">450 to <=480 msec", - ">480 to <= 500 msec", - ">500 msec", - "" - ) - ), - CHGCAT1 = factor( - CHGCAT1, - levels = c( - "<=30 msec", - ">30 to <=60 msec", - ">60 msec", - "" - ) - ) - ) - var_labels(ADEG) <- c( - ADEG_labels, - "AVALCAT1" = "Value at Visit", - "CHGCAT1" = "Change from Baseline" - )' - ), - check = TRUE - ), - modules = modules( - tm_t_summary_by( - label = "ECG Actual Values and Changes from Baseline by Visit", - dataname = "ADEG", - arm_var = choices_selected( - choices = variable_choices(adsl, c("ARM", "ARMCD")), - selected = "ARM" - ), - by_vars = choices_selected( - choices = variable_choices(adeg_f, c("PARAM", "AVISIT")), - selected = c("AVISIT") - ), - summarize_vars = choices_selected( - choices = variable_choices(adeg_f, c("AVALCAT1", "CHGCAT1")), - selected = c("AVALCAT1", "CHGCAT1") - ), - useNA = "ifany", - paramcd = choices_selected( - choices = value_choices(adeg_f, "PARAMCD", "PARAM"), - selected = "QT" - ) - ) - ) -) - -shinyApp(app$ui, app$server) -``` - -{{< include ../../repro.qmd >}} -::: From b0cb19eeca91c202024cb4a1f9d876e20a457ab1 Mon Sep 17 00:00:00 2001 From: Emily de la Rua <59304861+edelarua@users.noreply.github.com> Date: Thu, 21 Sep 2023 12:49:10 -0400 Subject: [PATCH 07/11] Delete listings/ada directory Signed-off-by: Emily de la Rua <59304861+edelarua@users.noreply.github.com> --- book/listings/ada/adal02.qmd | 131 ----------------------------------- 1 file changed, 131 deletions(-) delete mode 100644 book/listings/ada/adal02.qmd diff --git a/book/listings/ada/adal02.qmd b/book/listings/ada/adal02.qmd deleted file mode 100644 index 9ddcaf7f56..0000000000 --- a/book/listings/ada/adal02.qmd +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: ADAL02 -subtitle: Listing of Anti-Drug Antibody Data for Treatment Emergent ADA Positive Patients ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(dplyr) -library(rlistings) -library(scda) - -adab <- synthetic_cdisc_dataset("latest", "adab") %>% - filter(NFRLT %% 1 == 0 & NFRLT > 0) - -trt <- "A: Drug X" -drug_a <- "A: Drug X Antibody" -drugcd <- unique(adab$PARAMCD[adab$PARAM == "Antibody titer units"])[1] -min_titer <- 1.10 - -adab_x <- adab %>% - filter( - ARM == trt, - PARCAT1 == drug_a, - ADPBLPFL == "Y" - ) %>% - select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% - unique() %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - filter(if_any(matches("Treatment Emergent - Positive"), ~ .x == 1)) %>% - # filter(`Treatment Emergent - Positive` == 1) %>% - mutate( - VISN = factor(paste0( - VISIT, "\n(Day ", - ifelse( - NFRLT %% 1 == 0, - NFRLT, - as.character(format(round(NFRLT, 2), nsmall = 2)) - ), - ")" - )), - PTES = ifelse( - ifelse("Treatment induced ADA" %in% names(.), `Treatment induced ADA` == 1, F), - ifelse( - "Transient ADA" %in% names(.) & `Transient ADA` == 1, - "Induced (Transient)", - "Induced (Persistent)" - ), - "Enhanced" - ) - ) %>% - mutate( - AVAL = paste0( - ifelse( - ifelse("ADA interpreted per sample result" %in% names(.), `ADA interpreted per sample result` == 0, F), - "NEGATIVE", - ifelse( - ifelse("Antibody titer units" %in% names(.), !is.na(`Antibody titer units`), F), - ifelse( - `Antibody titer units` < min_titer, - paste0("<", format(min_titer, nsmall = 2)), - as.character(format(round(`Antibody titer units`, 2), nsmall = 2)) - ), - "---" - ) - ), - ifelse( - ifelse("NAB interpreted per sample result" %in% names(.), `NAB interpreted per sample result` == 1, F), - "*", - "" - ) - ) - ) - -out <- adab_x %>% - select(USUBJID, VISN, AVAL, PTES) %>% - tidyr::pivot_wider( - names_from = VISN, - values_from = AVAL - ) %>% - select(USUBJID, unique(adab_x$VISN[order(adab_x$NFRLT)]), PTES) - -var_labels(out) <- names(out) - -out <- out %>% - var_relabel( - USUBJID = "Subject ID", - PTES = "Patient Treatment\nEmergent ADA Status" - ) -``` - -## Standard Listing - -```{r lsting, test = list(lsting = "lsting")} -lsting <- as_listing( - out, - key_cols = "USUBJID", - disp_cols = names(out), - main_title = paste0( - "Listing of Anti-", drugcd, " Antibody Data for Treatment Emergent ADA Positive Patients, PK Population", - "\nProtocol: ", unique(adab$PARCAT1)[1] - ), - subtitles = paste("\nTreatment Group:", trt), - main_footer = "Minimum reportable titer = 1.10 (example only) ---- = No sample evaluated -ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) -Number of patients positive for Treatment Emergent ADA = the number of post-baseline evaluable patients determined to have treatment-induced ADA or treatment-enhanced ADA during the study period. -Treatment-induced ADA = a patient with negative or missing baseline ADA result(s) and at least one positive post-baseline ADA result. -Treatment-enhanced ADA = a patient with positive ADA result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. -Transient ADA = ADA positive result detected (a) at only one post-baseline sampling timepoint (excluding last timepoint) OR (b) at 2 or more timepoints during treatment where the first and last ADA positive samples are separated by a period of < 16 weeks, irrespective of any negative samples in between. -Persistent ADA = ADA positive result detected (a) at the last post-baseline sampling timepoint, OR (b) at 2 or more time points during treatment where the first and last ADA positive samples are separated by a period ≥ 16 weeks, irrespective of any negative samples in between. -Asterisk denotes sample that tested positive for Neutralizing Antibodies." -) - -head(lsting, 20) -``` - -{{< include ../../test-utils/save_results.qmd >}} - -{{< include ../../repro.qmd >}} -::: From 33e21cc982145ef85597a9fa21b8031d20374440 Mon Sep 17 00:00:00 2001 From: Emily de la Rua <59304861+edelarua@users.noreply.github.com> Date: Thu, 21 Sep 2023 12:49:30 -0400 Subject: [PATCH 08/11] Delete listings/ecg directory Signed-off-by: Emily de la Rua <59304861+edelarua@users.noreply.github.com> --- book/listings/ecg/egl01.qmd | 89 ------------------------------------- 1 file changed, 89 deletions(-) delete mode 100644 book/listings/ecg/egl01.qmd diff --git a/book/listings/ecg/egl01.qmd b/book/listings/ecg/egl01.qmd deleted file mode 100644 index a595b864c9..0000000000 --- a/book/listings/ecg/egl01.qmd +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: EGL01 -subtitle: 'Listing of ECG Data: Safety-Evaluable Patients' ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(dplyr) -library(scda) -library(rlistings) - -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -get_param_unit_range <- function(dataset) { - u_rng <- lapply(unique(dataset$PARAMCD), function(p) { - dat <- dataset %>% filter(PARAMCD == p) - list( - unit = unique(dat$AVALU), - range = paste0(unique(dat$ANRLO), "-", unique(dat$ANRHI)) - ) - }) - names(u_rng) <- unique(dataset$PARAMCD) - u_rng -} - -eg_u_rng <- get_param_unit_range(adeg) - -adeg_sub <- adeg %>% - filter(!is.na(AVAL) & SAFFL == "Y" & ANL01FL == "Y" & !is.na(EGSEQ) & PARAMCD != "ECGINTP") %>% - mutate( - CRTNPT = paste(SITEID, sub("^.*-([[:alnum:]]+)$", "\\1", SUBJID), sep = "/"), - AGSXRC = paste(AGE, SEX, RACE, sep = "/"), - AVAL = format(round(AVAL, 2), nsmall = 2), - AVAL_ANRIND = ifelse(ANRIND %in% c("NORMAL", ""), AVAL, paste(AVAL, substr(ANRIND, 1, 1), sep = "/")), - CHG = format(round(CHG, 2), nsmall = 2) - ) - -anl_eg <- adeg_sub %>% - select(SUBJID, CRTNPT, AGSXRC, TRT01A, PARAMCD, AVAL_ANRIND, CHG, ADY, AVISIT, ADTM) %>% - tidyr::pivot_wider( - id_cols = c(SUBJID, CRTNPT, AGSXRC, TRT01A, ADY, AVISIT, ADTM), - names_from = PARAMCD, - values_from = c(AVAL_ANRIND, CHG) - ) - -out <- anl_eg %>% - select(CRTNPT, AGSXRC, TRT01A, AVISIT, ADY, AVAL_ANRIND_HR, CHG_HR, AVAL_ANRIND_QT, CHG_QT, AVAL_ANRIND_RR, CHG_RR) %>% - var_relabel( - CRTNPT = "Center/Subject ID", - AGSXRC = "Age/Sex/Race", - TRT01A = "Treatment", - AVISIT = "Visit", - ADY = "Study\nDay", - AVAL_ANRIND_HR = paste0("Heart Rate Result\n(", eg_u_rng$HR$unit, ");\nRange:(", eg_u_rng$HR$range, ")"), - CHG_HR = "Heart Rate\nChange from BL", - AVAL_ANRIND_QT = paste0("QT Duration Result\n(", eg_u_rng$QT$unit, ");\nRange:(", eg_u_rng$QT$range, ")"), - CHG_QT = "QT Duration\nChange from BL", - AVAL_ANRIND_RR = paste0("RR Duration Result\n(", eg_u_rng$RR$unit, ");\nRange:(", eg_u_rng$RR$range, ")"), - CHG_RR = "RR Duration\nChange from BL" - ) -``` - -## Standard Listing - -```{r lsting, test = list(lsting = "lsting")} -lsting <- as_listing( - out, - key_cols = c("CRTNPT", "AGSXRC", "TRT01A", "AVISIT", "ADY"), - disp_cols = names(out), - main_title = "Listing of ECG Data: Safety-Evaluable Patients", - main_footer = "Baseline is the patient's last observation prior to initiation of study drug. Abnormalities are flagged as high (H) or low (L) if - outside the Roche standard reference range." -) - -head(lsting, 20) -``` - -{{< include ../../test-utils/save_results.qmd >}} - -{{< include ../../repro.qmd >}} -::: From 0dc258605e83069e1457fe2d0a68f9980a1d5de7 Mon Sep 17 00:00:00 2001 From: Abinaya Yogasekaram <73252787+ayogasekaram@users.noreply.github.com> Date: Thu, 21 Sep 2023 13:01:05 -0400 Subject: [PATCH 09/11] Apply suggestions from code review adding code review suggestions Co-authored-by: Emily de la Rua <59304861+edelarua@users.noreply.github.com> Signed-off-by: Abinaya Yogasekaram <73252787+ayogasekaram@users.noreply.github.com> --- book/generate-index.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/book/generate-index.R b/book/generate-index.R index 99cec8b787..91176eeda3 100755 --- a/book/generate-index.R +++ b/book/generate-index.R @@ -37,7 +37,7 @@ cat( # Tables section_header("Tables") -create_subsection("./tables/ada", "ADA") +create_subsection("./tables/ADA", "ADA") create_subsection("./tables/adverse-events", "Adverse Events") create_subsection("./tables/concomitant-medications", "Concomitant Medications") create_subsection("./tables/deaths", "Deaths") @@ -59,9 +59,9 @@ create_subsection("./tables/vital-signs", "Vital Signs") section_header("Listings") create_subsection("./listings/ada", "ADA") create_subsection("./listings/adverse-events", "Adverse Events") -create_subsection("./listings/concomitant-medications", "Concomitant Medications") +create_subsection("./listings/concomitant-medications", "Concomitant Medications") # nolint create_subsection("./listings/disposition", "Disposition") -create_subsection("./listings/development-safety-update-report", "Development Safety Update Report") +create_subsection("./listings/development-safety-update-report", "Development Safety Update Report") # nolint create_subsection("./listings/ecg", "ECG") create_subsection("./listings/exposure", "Exposure") create_subsection("./listings/lab-results", "Lab Results") From b7205e3186cfdb2abed76a161bee922461c9b369 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Thu, 21 Sep 2023 17:13:18 +0000 Subject: [PATCH 10/11] update index --- book/generate-index.R | 6 +- book/listings/ADA/adal02.qmd | 131 ---------------- book/listings/ECG/egl01.qmd | 89 ----------- book/tables/ADA/adat01.qmd | 230 ---------------------------- book/tables/ADA/adat02.qmd | 151 ------------------- book/tables/ADA/adat03.qmd | 131 ---------------- book/tables/ADA/adat04a.qmd | 240 ------------------------------ book/tables/ADA/adat04b.qmd | 223 ---------------------------- book/tables/ECG/egt01.qmd | 142 ------------------ book/tables/ECG/egt02.qmd | 126 ---------------- book/tables/ECG/egt03.qmd | 204 ------------------------- book/tables/ECG/egt04.qmd | 100 ------------- book/tables/ECG/egt05_qtcat.qmd | 255 -------------------------------- 13 files changed, 3 insertions(+), 2025 deletions(-) delete mode 100644 book/listings/ADA/adal02.qmd delete mode 100644 book/listings/ECG/egl01.qmd delete mode 100644 book/tables/ADA/adat01.qmd delete mode 100644 book/tables/ADA/adat02.qmd delete mode 100644 book/tables/ADA/adat03.qmd delete mode 100644 book/tables/ADA/adat04a.qmd delete mode 100644 book/tables/ADA/adat04b.qmd delete mode 100644 book/tables/ECG/egt01.qmd delete mode 100644 book/tables/ECG/egt02.qmd delete mode 100644 book/tables/ECG/egt03.qmd delete mode 100644 book/tables/ECG/egt04.qmd delete mode 100644 book/tables/ECG/egt05_qtcat.qmd diff --git a/book/generate-index.R b/book/generate-index.R index 91176eeda3..927a0df5c8 100755 --- a/book/generate-index.R +++ b/book/generate-index.R @@ -44,7 +44,7 @@ create_subsection("./tables/deaths", "Deaths") create_subsection("./tables/demography", "Demography") create_subsection("./tables/disclosures", "Disclosures") create_subsection("./tables/disposition", "Disposition") -create_subsection("./tables/ecg", "ECG") +create_subsection("./tables/ECG", "ECG") create_subsection("./tables/efficacy", "Efficacy") create_subsection("./tables/exposure", "Exposure") create_subsection("./tables/lab-results", "Lab Results") @@ -57,12 +57,12 @@ create_subsection("./tables/vital-signs", "Vital Signs") # Listings section_header("Listings") -create_subsection("./listings/ada", "ADA") +create_subsection("./listings/ADA", "ADA") create_subsection("./listings/adverse-events", "Adverse Events") create_subsection("./listings/concomitant-medications", "Concomitant Medications") # nolint create_subsection("./listings/disposition", "Disposition") create_subsection("./listings/development-safety-update-report", "Development Safety Update Report") # nolint -create_subsection("./listings/ecg", "ECG") +create_subsection("./listings/ECG", "ECG") create_subsection("./listings/exposure", "Exposure") create_subsection("./listings/lab-results", "Lab Results") create_subsection("./listings/medical-history", "Medical History") diff --git a/book/listings/ADA/adal02.qmd b/book/listings/ADA/adal02.qmd deleted file mode 100644 index 9ddcaf7f56..0000000000 --- a/book/listings/ADA/adal02.qmd +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: ADAL02 -subtitle: Listing of Anti-Drug Antibody Data for Treatment Emergent ADA Positive Patients ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(dplyr) -library(rlistings) -library(scda) - -adab <- synthetic_cdisc_dataset("latest", "adab") %>% - filter(NFRLT %% 1 == 0 & NFRLT > 0) - -trt <- "A: Drug X" -drug_a <- "A: Drug X Antibody" -drugcd <- unique(adab$PARAMCD[adab$PARAM == "Antibody titer units"])[1] -min_titer <- 1.10 - -adab_x <- adab %>% - filter( - ARM == trt, - PARCAT1 == drug_a, - ADPBLPFL == "Y" - ) %>% - select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% - unique() %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - filter(if_any(matches("Treatment Emergent - Positive"), ~ .x == 1)) %>% - # filter(`Treatment Emergent - Positive` == 1) %>% - mutate( - VISN = factor(paste0( - VISIT, "\n(Day ", - ifelse( - NFRLT %% 1 == 0, - NFRLT, - as.character(format(round(NFRLT, 2), nsmall = 2)) - ), - ")" - )), - PTES = ifelse( - ifelse("Treatment induced ADA" %in% names(.), `Treatment induced ADA` == 1, F), - ifelse( - "Transient ADA" %in% names(.) & `Transient ADA` == 1, - "Induced (Transient)", - "Induced (Persistent)" - ), - "Enhanced" - ) - ) %>% - mutate( - AVAL = paste0( - ifelse( - ifelse("ADA interpreted per sample result" %in% names(.), `ADA interpreted per sample result` == 0, F), - "NEGATIVE", - ifelse( - ifelse("Antibody titer units" %in% names(.), !is.na(`Antibody titer units`), F), - ifelse( - `Antibody titer units` < min_titer, - paste0("<", format(min_titer, nsmall = 2)), - as.character(format(round(`Antibody titer units`, 2), nsmall = 2)) - ), - "---" - ) - ), - ifelse( - ifelse("NAB interpreted per sample result" %in% names(.), `NAB interpreted per sample result` == 1, F), - "*", - "" - ) - ) - ) - -out <- adab_x %>% - select(USUBJID, VISN, AVAL, PTES) %>% - tidyr::pivot_wider( - names_from = VISN, - values_from = AVAL - ) %>% - select(USUBJID, unique(adab_x$VISN[order(adab_x$NFRLT)]), PTES) - -var_labels(out) <- names(out) - -out <- out %>% - var_relabel( - USUBJID = "Subject ID", - PTES = "Patient Treatment\nEmergent ADA Status" - ) -``` - -## Standard Listing - -```{r lsting, test = list(lsting = "lsting")} -lsting <- as_listing( - out, - key_cols = "USUBJID", - disp_cols = names(out), - main_title = paste0( - "Listing of Anti-", drugcd, " Antibody Data for Treatment Emergent ADA Positive Patients, PK Population", - "\nProtocol: ", unique(adab$PARCAT1)[1] - ), - subtitles = paste("\nTreatment Group:", trt), - main_footer = "Minimum reportable titer = 1.10 (example only) ---- = No sample evaluated -ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) -Number of patients positive for Treatment Emergent ADA = the number of post-baseline evaluable patients determined to have treatment-induced ADA or treatment-enhanced ADA during the study period. -Treatment-induced ADA = a patient with negative or missing baseline ADA result(s) and at least one positive post-baseline ADA result. -Treatment-enhanced ADA = a patient with positive ADA result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. -Transient ADA = ADA positive result detected (a) at only one post-baseline sampling timepoint (excluding last timepoint) OR (b) at 2 or more timepoints during treatment where the first and last ADA positive samples are separated by a period of < 16 weeks, irrespective of any negative samples in between. -Persistent ADA = ADA positive result detected (a) at the last post-baseline sampling timepoint, OR (b) at 2 or more time points during treatment where the first and last ADA positive samples are separated by a period ≥ 16 weeks, irrespective of any negative samples in between. -Asterisk denotes sample that tested positive for Neutralizing Antibodies." -) - -head(lsting, 20) -``` - -{{< include ../../test-utils/save_results.qmd >}} - -{{< include ../../repro.qmd >}} -::: diff --git a/book/listings/ECG/egl01.qmd b/book/listings/ECG/egl01.qmd deleted file mode 100644 index a595b864c9..0000000000 --- a/book/listings/ECG/egl01.qmd +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: EGL01 -subtitle: 'Listing of ECG Data: Safety-Evaluable Patients' ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(dplyr) -library(scda) -library(rlistings) - -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -get_param_unit_range <- function(dataset) { - u_rng <- lapply(unique(dataset$PARAMCD), function(p) { - dat <- dataset %>% filter(PARAMCD == p) - list( - unit = unique(dat$AVALU), - range = paste0(unique(dat$ANRLO), "-", unique(dat$ANRHI)) - ) - }) - names(u_rng) <- unique(dataset$PARAMCD) - u_rng -} - -eg_u_rng <- get_param_unit_range(adeg) - -adeg_sub <- adeg %>% - filter(!is.na(AVAL) & SAFFL == "Y" & ANL01FL == "Y" & !is.na(EGSEQ) & PARAMCD != "ECGINTP") %>% - mutate( - CRTNPT = paste(SITEID, sub("^.*-([[:alnum:]]+)$", "\\1", SUBJID), sep = "/"), - AGSXRC = paste(AGE, SEX, RACE, sep = "/"), - AVAL = format(round(AVAL, 2), nsmall = 2), - AVAL_ANRIND = ifelse(ANRIND %in% c("NORMAL", ""), AVAL, paste(AVAL, substr(ANRIND, 1, 1), sep = "/")), - CHG = format(round(CHG, 2), nsmall = 2) - ) - -anl_eg <- adeg_sub %>% - select(SUBJID, CRTNPT, AGSXRC, TRT01A, PARAMCD, AVAL_ANRIND, CHG, ADY, AVISIT, ADTM) %>% - tidyr::pivot_wider( - id_cols = c(SUBJID, CRTNPT, AGSXRC, TRT01A, ADY, AVISIT, ADTM), - names_from = PARAMCD, - values_from = c(AVAL_ANRIND, CHG) - ) - -out <- anl_eg %>% - select(CRTNPT, AGSXRC, TRT01A, AVISIT, ADY, AVAL_ANRIND_HR, CHG_HR, AVAL_ANRIND_QT, CHG_QT, AVAL_ANRIND_RR, CHG_RR) %>% - var_relabel( - CRTNPT = "Center/Subject ID", - AGSXRC = "Age/Sex/Race", - TRT01A = "Treatment", - AVISIT = "Visit", - ADY = "Study\nDay", - AVAL_ANRIND_HR = paste0("Heart Rate Result\n(", eg_u_rng$HR$unit, ");\nRange:(", eg_u_rng$HR$range, ")"), - CHG_HR = "Heart Rate\nChange from BL", - AVAL_ANRIND_QT = paste0("QT Duration Result\n(", eg_u_rng$QT$unit, ");\nRange:(", eg_u_rng$QT$range, ")"), - CHG_QT = "QT Duration\nChange from BL", - AVAL_ANRIND_RR = paste0("RR Duration Result\n(", eg_u_rng$RR$unit, ");\nRange:(", eg_u_rng$RR$range, ")"), - CHG_RR = "RR Duration\nChange from BL" - ) -``` - -## Standard Listing - -```{r lsting, test = list(lsting = "lsting")} -lsting <- as_listing( - out, - key_cols = c("CRTNPT", "AGSXRC", "TRT01A", "AVISIT", "ADY"), - disp_cols = names(out), - main_title = "Listing of ECG Data: Safety-Evaluable Patients", - main_footer = "Baseline is the patient's last observation prior to initiation of study drug. Abnormalities are flagged as high (H) or low (L) if - outside the Roche standard reference range." -) - -head(lsting, 20) -``` - -{{< include ../../test-utils/save_results.qmd >}} - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ADA/adat01.qmd b/book/tables/ADA/adat01.qmd deleted file mode 100644 index 31a13bd819..0000000000 --- a/book/tables/ADA/adat01.qmd +++ /dev/null @@ -1,230 +0,0 @@ ---- -title: ADAT01 -subtitle: Baseline Prevalence and Incidence of Treatment Emergent ADA ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(tern) -library(dplyr) -library(scda) -library(tibble) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adab <- synthetic_cdisc_dataset("latest", "adab") - -combodf <- tribble( - ~valname, ~label, ~levelcombo, ~exargs, - "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), - "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() -) - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adab <- adab %>% - filter(PARCAT1 == "A: Drug X Antibody") %>% - select(-ARRLT, -NRRLT) - -# Baseline Pts -adab_b <- df_explicit_na(adab) %>% - filter( - ABLFL == "Y", - ADABLPFL == "Y", - PARAM %in% c("ADA interpreted per sample result") - ) %>% - select(-PARAMCD, -AVALC, -AVALU) %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate_at( - c("ADA interpreted per sample result"), - as.logical - ) %>% - mutate( - ADABLPFL = ADABLPFL == "Y", - PADABLPFL = `ADA interpreted per sample result` == "TRUE", - NADABLPFL = `ADA interpreted per sample result` == "FALSE" - ) %>% - var_relabel( - ADABLPFL = "Baseline evaluable patients", - PADABLPFL = "Patient with a positive sample at baseline", - NADABLPFL = "Patient with no positive samples at baseline" - ) - -# Post Baseline Treatment Enhanced NAb positive Pts -adab_pb <- df_explicit_na(adab) %>% - filter( - ABLFL != "Y", - ADPBLPFL == "Y", - PARAM %in% c( - "ADA interpreted per sample result", - "Treatment Emergent - Positive", - "Treatment induced ADA", - "Treatment enhanced ADA", - "Treatment Emergent - Negative", - "Treatment unaffected" - ) - ) %>% - select(-PARAMCD, -AVALC, -AVALU) %>% - unique() %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate( - across( - any_of(c( - "ADA interpreted per sample result", "Treatment Emergent - Positive", - "Treatment induced ADA", "Treatment enhanced ADA", - "Treatment Emergent - Negative", "Treatment unaffected" - )), - as.logical - ) - ) %>% - mutate( - ADPBLPFL = ADPBLPFL == "Y", - PTEFL = if (exists("Treatment Emergent - Positive", where = .)) `Treatment Emergent - Positive` == "TRUE" else FALSE, - TIFL = if (exists("Treatment induced ADA", where = .)) `Treatment induced ADA` == "TRUE" else FALSE, - TEFL = if (exists("Treatment enhanced ADA", where = .)) `Treatment enhanced ADA` == "TRUE" else FALSE, - NTEFL = if (exists("Treatment Emergent - Negative", where = .)) `Treatment Emergent - Negative` == "TRUE" else FALSE, - TUFL = if (exists("Treatment unaffected", where = .)) `Treatment unaffected` == "TRUE" else FALSE - ) %>% - var_relabel( - ADPBLPFL = "Post-baseline evaluable patients", - PTEFL = "Patient positive for Treatment Emergent ADA", - TIFL = "Treatment-induced ADA", - TEFL = "Treatment-enhanced ADA", - NTEFL = "Patient negative for Treatment Emergent ADA", - TUFL = "Treatment unaffected" - ) -``` - -## Standard Table - -```{r variant1, test = list(result_v1 = "result")} -# Layout for Baseline Prevalence of NAbs -lyt_bl <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "ADABLPFL", - .stats = "count", - var_labels = "Baseline Prevalence of ADAs", - show_labels = "visible", - table_names = "t1" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "PADABLPFL", - table_names = "t2", - .indent_mods = 1L, - var_labels = "a", - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NADABLPFL", - .stats = "count", - show_labels = "hidden", - .indent_mods = 1L, - table_names = "t3" - ) - -# Layout for incidence of NAbs -lyt_pb <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "ADPBLPFL", - .stats = "count", - var_labels = "Incidence of Treatment Emergent ADAs", - show_labels = "visible", - table_names = "tb1" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "PTEFL", - table_names = "tb2", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("TIFL", "TEFL"), - .stats = "count", - table_names = "tb3", - .indent_mods = 2L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NTEFL", - table_names = "tb4", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "TUFL", - .stats = "count", - table_names = "tb5", - .indent_mods = 2L, - show_labels = "hidden" - ) - -result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) -result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) - -# Combine tables. -result_1@col_info <- result_2@col_info -result <- rbind(result_1, result_2) - -# Change the column order. -result <- cbind_rtables(result[, 1], result[, 3]) %>% - cbind_rtables(result[, 4]) %>% - cbind_rtables(result[, 2]) %>% - cbind_rtables(result[, 5]) - -main_title(result) <- paste( - "Baseline Prevalence and Incidence of Treatment Emergent ADA" -) -main_footer(result) <- paste( - "ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient = a patient with an ADA assay result from a baseline sample(s) - Post-baseline evaluable patient = a patient with an ADA assay result from at least one post-baseline sample Number of patients positive for Treatment Emergent - ADA = the number (and percentage) of post-baseline evaluable patients determined to have treatment-induced ADA or treatment-enhanced ADA during the study period. - Treatment-induced ADA = a patient with negative or missing baseline ADA result(s) and at least one positive post-baseline ADA result. - Treatment-enhanced ADA = a patient with positive ADA result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. - Number of patients negative for Treatment Emergent ADA = number of post-baseline evaluable patients with negative or missing baseline ADA result(s) and all negative post-baseline results, or a patient who is treatment unaffected. - Treatment unaffected = A post-baseline evaluable patient with a positive ADA result at baseline and (a) where all post-baseline titer results are less than 0.60 t.u. greater than the baseline titer result, OR (b) where all post-baseline results are negative or missing. - For any positive sample with titer result less than the minimum reportable titer or any positive sample where a titer cannot be obtained, titer value is imputed as equal to the minimum reportable titer." -) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ADA/adat02.qmd b/book/tables/ADA/adat02.qmd deleted file mode 100644 index 630e8e817e..0000000000 --- a/book/tables/ADA/adat02.qmd +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: ADAT02 -subtitle: Summary of Patients with Treatment-Induced ADA ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(tern) -library(dplyr) -library(scda) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adab <- synthetic_cdisc_dataset("latest", "adab") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adab <- df_explicit_na(adab) %>% - mutate(ADPBLPFL = "Y") %>% # temp fix - filter( - ADPBLPFL == "Y", - !PARAM %in% c( - "NAB interpreted per sample result", - "NAB Status of a patient", - "Treatment enhanced ADA" - ) - ) %>% - select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% - unique() %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate( - across( - any_of(c( - "Treatment induced ADA", - "Transient ADA", - "Persistent ADA" - )), - as.logical - ) - ) %>% - mutate( - ADPBLPFL = ADPBLPFL == "Y", - TI_ADA = if (exists("Treatment induced ADA", where = .)) `Treatment induced ADA` else FALSE - ) %>% - var_relabel( - ADPBLPFL = "Post-baseline evaluable patients", - TI_ADA = "Treatment-induced ADA patients" - ) - -adab_ti <- adab %>% - filter(TI_ADA) -``` - -## Standard Table - -```{r variant1, test = list(result_v1 = "result")} -# Layout for post-baseline evaluable patient variables from adab dataset. -lyt_adab <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = drop_split_levels - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "ADPBLPFL", - .stats = "count", - table_names = "post_baseline" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "TI_ADA" - ) - -# Layout for treatment-induced patient variables from adab dataset. -lyt_adab_ti <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = keep_split_levels(c("A: Drug X", "C: Combination", "")) # temp fix - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("Transient ADA", "Persistent ADA"), - var_labels = "Treatment-induced ADA patients with", - show_labels = "visible" - ) %>% - analyze_vars( - "Time to onset of ADA", - .stats = "median", - nested = FALSE, - .labels = c(median = "Median time to onset of ADA (weeks)") - ) %>% - analyze_vars( - "Antibody titer units", - .stats = "range", - nested = FALSE, - .labels = c(range = "ADA titer range (min - max)") - ) - -result_adab <- build_table(lyt_adab, df = adab, alt_counts_df = adsl) -result_adab_ti <- build_table(lyt_adab_ti, df = adab_ti, alt_counts_df = adsl) - -# Combine tables. -col_info(result_adab) <- col_info(result_adab_ti) -result <- rbind( - result_adab, - result_adab_ti -) - -main_title(result) <- paste( - "Summary of Patients with Treatment-Induced ADA, PK Population" -) -subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) -main_footer(result) <- paste( - "ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic - Antibodies) - Treatment-induced ADA = negative or missing baseline. - ADA result(s) and at least one positive post-baseline ADA result. - Transient ADA = ADA positive result detected (a) at only one post-baseline - sampling timepoint (excluding last timepoint) OR (b) at 2 or more timepoints - during treatment where the first and last ADA positive samples are separated - by a period of < 16 weeks, irrespective of any negative samples in between. - Persistent ADA = ADA positive result detected (a) at the last post-baseline - sampling timepoint, OR (b) at 2 or more time points during treatment where - the first and last ADA positive samples are separated by a period ≥ 16 - weeks, irrespective of any negative samples in between." -) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ADA/adat03.qmd b/book/tables/ADA/adat03.qmd deleted file mode 100644 index 561c5ab1af..0000000000 --- a/book/tables/ADA/adat03.qmd +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: ADAT03 -subtitle: Summary of Serum Concentrations at Timepoints Where ADA Samples Were Collected and Analyzed ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(dplyr) -library(scda) -library(tern) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adab <- synthetic_cdisc_dataset("latest", "adab") -adpc <- synthetic_cdisc_dataset("latest", "adpc") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adab <- df_explicit_na(adab) -adpc <- df_explicit_na(adpc) - -# Adjust zzz parameter -max_conc <- 15 - -adpc <- adpc %>% select(USUBJID, NFRLT, AVAL, AVALU, AVALCAT1) - -anl <- adab %>% - filter(., PARAM == "ADA interpreted per sample result") %>% - select(-AVAL, AVALC, AVALU) - -anl <- merge(anl, adpc, by = c("USUBJID", "NFRLT")) %>% - mutate(AVAL_LT = ifelse(AVAL <= max_conc, TRUE, FALSE)) -``` - -## Standard Table (μg/mL) - -```{r variant1, test = list(result_v1 = "result")} -# parameters in columns -adat03_stats <- c("n", "mean", "sd", "median", "min", "max", "cv", "geom_mean", "count_fraction") -adat03_lbls <- c( - n = "Total Number\nof Measurable\n Samples", - mean = "Mean", - sd = "SD", - median = "Median", - min = "Minimum", - max = "Maximum", - cv = "CV (%)", - geom_mean = "Geometric Mean", - count_fraction = paste0("Samples with\nConcentration\n≤ ", max_conc, "μg/mL") -) -adat03_fmts <- c( - n = "xx.", - mean = sprintf_format("%.3e"), - sd = sprintf_format("%.3e"), - median = sprintf_format("%.3e"), - min = sprintf_format("%.3e"), - max = sprintf_format("%.3e"), - cv = "xx.x", - geom_mean = sprintf_format("%.3e"), - count_fraction = format_count_fraction -) - -afun_list <- lapply( - 1:9, - function(i) make_afun(s_summary, .stats = adat03_stats[i], .formats = adat03_fmts[i], .labels = "Overall") -) - -# lyt creation -lyt <- basic_table() %>% - split_rows_by( - var = "ARM", - label_pos = "topleft", - split_label = "Treatment Group", - split_fun = drop_split_levels, - section_div = "" - ) %>% - add_rowcounts() %>% - split_rows_by( - var = "VISIT", - label_pos = "topleft", - split_label = "Visit", - split_fun = drop_split_levels, - child_labels = "hidden" - ) %>% - analyze_vars_in_cols( - vars = c(rep("AVAL", 8), "AVAL_LT"), - .stats = adat03_stats, - .labels = adat03_lbls, - .formats = adat03_fmts - ) %>% - analyze_colvars( - afun_list, - nested = FALSE, - extra_args = list(".labels" = "Overall") - ) - -result <- build_table(lyt, anl, alt_counts_df = adsl) - -main_title(result) <- paste( - "Summary of Serum Concentrations (μg/mL) at Timepoints Where ADA Samples Were Collected and Analyzed\n - Protocol:", unique(adab$PARCAT1)[1] -) -subtitles(result) <- paste("Analyte:", unique(adab$PARAMCD)[1]) -fnotes_at_path(result, rowpath = NULL, colpath = c("multivars", "AVAL")) <- "Refers to the total no. of measurable ADA samples that have a corresponding measurable drug concentration sample (i.e. results with -valid numeric values and LTRs). LTR results on post-dose samples are replaced by aaa µg/mL i.e. half of MQC value." -fnotes_at_path(result, rowpath = NULL, colpath = c("multivars", "AVAL_LT")) <- "In validation, the assay was able to detect yyy ng/mL of surrogate ADA in the presence of zzz µg/mL of [drug]. BLQ = Below Limit of -Quantitation, LTR = Lower than Reportable, MQC = Minimum Quantifiable Concentration, ADA = Anti-Drug Antibodies (is also referred to as ATA, -or Anti-Therapeutic Antibodies). RXXXXXXX is also known as [drug]" - -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ADA/adat04a.qmd b/book/tables/ADA/adat04a.qmd deleted file mode 100644 index 3a3f56d998..0000000000 --- a/book/tables/ADA/adat04a.qmd +++ /dev/null @@ -1,240 +0,0 @@ ---- -title: ADAT04A -subtitle: Baseline Prevalence and Incidence of Treatment Emergent NAbs ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(tern) -library(dplyr) -library(scda) -library(tibble) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adab <- synthetic_cdisc_dataset("latest", "adab") - -combodf <- tribble( - ~valname, ~label, ~levelcombo, ~exargs, - "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), - "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() -) - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) - -# Baseline Pts -adab_b <- df_explicit_na(adab) %>% - filter( - ABLFL == "Y", - ADABLPFL == "Y", - PARAM %in% c( - "ADA interpreted per sample result", - "NAB interpreted per sample result" - ) - ) %>% - select(-PARAMCD, -AVALC, -AVALU) %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate( - across( - any_of(c( - "ADA interpreted per sample result", - "NAB interpreted per sample result" - )), - as.logical - ) - ) %>% - mutate( - ADABLPFL = ADABLPFL == "Y", - PADABLPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, - PNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "TRUE" else FALSE, - NNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE - ) %>% - var_relabel( - ADABLPFL = "Baseline evaluable patients for ADA", - PADABLPFL = "Patients with a positive ADA sample at baseline", - PNABBLFL = "Patients with a positive NAb sample at baseline", - NNABBLFL = "Patient with no positive NAb samples at baseline" - ) - -# Post Baseline Treatment Enhanced NAb positive Pts -adab_pb <- df_explicit_na(adab) %>% - filter( - ABLFL != "Y", - ADPBLPFL == "Y", - PARAM %in% c( - "ADA interpreted per sample result", - "Treatment Emergent - Positive, Neutralizing Antibody", - "Treatment induced ADA, Neutralizing Antibody", - "Treatment enhanced ADA, Neutralizing Antibody", - "NAB interpreted per sample result", - "Treatment unaffected, Neutralizing Antibody" - ) - ) %>% - select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% - unique() %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate( - across( - any_of(c( - "ADA interpreted per sample result", "NAB interpreted per sample result", - "Treatment Emergent - Positive, Neutralizing Antibody", - "Treatment induced ADA, Neutralizing Antibody", - "Treatment enhanced ADA, Neutralizing Antibody", - "Treatment unaffected, Neutralizing Antibody" - )), - as.logical - ) - ) %>% - mutate( - ADPBLPFL = ADPBLPFL == "Y", - ADAPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, - TENABPFL = if (exists("Treatment Emergent - Positive, Neutralizing Antibody", where = .)) `Treatment Emergent - Positive, Neutralizing Antibody` == "TRUE" else FALSE, - TINPBFL = if (exists("Treatment induced ADA, Neutralizing Antibody", where = .)) `Treatment induced ADA, Neutralizing Antibody` == "TRUE" else FALSE, - TENPBFL = if (exists("Treatment enhanced ADA, Neutralizing Antibody", where = .)) `Treatment enhanced ADA, Neutralizing Antibody` == "TRUE" else FALSE, - NABNFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE, - TUNPBFL = if (exists("Treatment unaffected, Neutralizing Antibody", where = .)) `Treatment unaffected, Neutralizing Antibody` == "TRUE" else FALSE - ) %>% - var_relabel( - ADPBLPFL = "Post-baseline evaluable patients for ADA", - ADAPFL = "Patients positive for ADA", - TENABPFL = "Patients positive for Treatment Emergent NAb", - TINPBFL = "Treatment-induced NAb", - TENPBFL = "Treatment-enhanced NAb", - NABNFL = "Patients negative for NAb", - TUNPBFL = "Treatment unaffected" - ) -``` - -## Summary of Treatment Emergent NAbs - -```{r variant1, test = list(result_v1 = "result")} -# Layout for Baseline Prevalence of NAbs -lyt_bl <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("ADABLPFL", "PADABLPFL"), - table_names = "t1", - .stats = "count", - var_labels = "Baseline Prevalence of NAbs", - show_labels = "visible" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "PNABBLFL", - table_names = "t2", - .indent_mods = 1L - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NNABBLFL", - .stats = "count", - table_names = "t3", - .indent_mods = 1L, - show_labels = "hidden" - ) - -# Layout for incidence of NAbs -lyt_pb <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("ADPBLPFL", "ADAPFL"), - .stats = "count", - var_labels = "Incidence of Treatment Emergent NAbs", - show_labels = "visible", - table_names = "tb1" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "TENABPFL", - table_names = "tb2", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("TINPBFL", "TENPBFL"), - .stats = "count", - table_names = "tb3", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NABNFL", - table_names = "tb4", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "TUNPBFL", - .stats = "count", - table_names = "tb5", - .indent_mods = 1L, - show_labels = "hidden" - ) - -result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) -result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) - -# Combine tables -result <- rbind(result_1, result_2) - -# Change the column order -result <- cbind_rtables(result[, 1], result[, 3]) %>% - cbind_rtables(result[, 4]) %>% - cbind_rtables(result[, 2]) %>% - cbind_rtables(result[, 5]) - -main_title(result) <- paste( - "Baseline Prevalence and Incidence of Treatment Emergent NAbs" -) -subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) -main_footer(result) <- paste( - "NAb = Neutralizing Antibodies ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient for ADA = a patient with an ADA assay result from a baseline sample(s) - Baseline evaluable patient for NAb = a patient with a NAb assay result from a baseline sample(s) - Post-baseline evaluable patient for ADA = a patient with an ADA assay result from at least one post-baseline sample - Post-baseline evaluable patient for NAb = a patient with a NAb assay result from at least one post-baseline sample - Number of patients positive for ADA = the number of post-baseline evaluable patients for ADA determined to have Treatment Emergent ADA during the study period. -Number of patients positive for Treatment Emergent NAb = the number (and percentage) of post-baseline evaluable patients for ADA determined to have treatment-induced NAb or treatment-enhanced NAb during the study period. -Treatment-induced = a patient with negative or missing baseline result(s) and at least one positive post-baseline result. Treatment-enhanced = a patient with positive result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. -Number of patients negative for Treatment Emergent NAb = number of post-baseline evaluable patients with negative or missing baseline NAb result(s) and all negative post-baseline NAb results, or a patient who is NAb treatment unaffected. -Treatment unaffected = A post-baseline evaluable patient with a positive result at baseline and (a) where all post-baseline titer results are less than 0.60 t.u. greater than the baseline titer result, OR (b) where all post-baseline results are negative or missing. For any positive sample with titer result less than the minimum reportable titer or any positive sample where a titer cannot be obtained, titer value is imputed as equal to the minimum reportable titer." -) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ADA/adat04b.qmd b/book/tables/ADA/adat04b.qmd deleted file mode 100644 index 5994f04002..0000000000 --- a/book/tables/ADA/adat04b.qmd +++ /dev/null @@ -1,223 +0,0 @@ ---- -title: ADAT04B -subtitle: Baseline Prevalence and Incidence of NAbs ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(tern) -library(dplyr) -library(scda) -library(tibble) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adab <- synthetic_cdisc_dataset("latest", "adab") - -combodf <- tribble( - ~valname, ~label, ~levelcombo, ~exargs, - "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), - "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() -) - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) - -# Baseline Pts -adab_b <- df_explicit_na(adab) %>% - filter( - ABLFL == "Y", - ADABLPFL == "Y", - PARAM %in% c( - "ADA interpreted per sample result", - "NAB interpreted per sample result" - ) - ) %>% - select(-PARAMCD, -AVALC, -AVALU) %>% - tidyr::pivot_wider( - names_from = PARAM, - values_from = AVAL - ) %>% - mutate( - across( - any_of(c( - "ADA interpreted per sample result", - "NAB interpreted per sample result" - )), - as.logical - ) - ) %>% - mutate( - ADABLPFL = ADABLPFL == "Y", - PADABLPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, - PNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "TRUE" else FALSE, - NNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE - ) %>% - var_relabel( - ADABLPFL = "Baseline evaluable patients for ADA", - PADABLPFL = "Patients with a positive ADA sample at baseline", - PNABBLFL = "Patients with a positive NAb sample at baseline", - NNABBLFL = "Patients with no positive NAb sample at baseline" - ) - -# Post-Baseline Evaluable Pts -adab_pb_ada <- df_explicit_na(adab) %>% - filter(ADPBLPFL == "Y") %>% - select(STUDYID, USUBJID, ARM, ACTARM, ADPBLPFL) %>% - mutate(ADPBLPFL = ADPBLPFL == "Y") %>% - distinct() - -# Post-Baseline ADA Positive Pts -adab_pb_adap <- df_explicit_na(adab) %>% - filter( - ABLFL != "Y", - PARAM == "ADA interpreted per sample result", - AVALC == "POSITIVE" - ) %>% - mutate(ADAPFL = AVALC == "POSITIVE") %>% - select(STUDYID, USUBJID, ARM, ACTARM, ADAPFL) %>% - distinct() - -# Post-Baseline NAb Positive Pts -adab_pb_nabp <- df_explicit_na(adab) %>% - filter( - ABLFL != "Y", - PARAM == "NAb interpreted per sample result", - AVALC == "POSITIVE" - ) %>% - mutate(NABPFL = AVALC == "POSITIVE") %>% - select(STUDYID, USUBJID, ARM, ACTARM, NABPFL) %>% - distinct() - -# Post-Baseline NAb Negative Pts -adab_pb_nabn <- df_explicit_na(adab) %>% - filter( - ABLFL != "Y", - PARAM == "NAb interpreted per sample result", - AVALC == "NEGATIVE" - ) %>% - rename(NABNFL = AVALC) %>% - select(STUDYID, USUBJID, ARM, ACTARM, NABNFL) %>% - distinct() - -mergecol <- c("STUDYID", "USUBJID", "ARM", "ACTARM") - -adab_pb <- left_join(adab_pb_ada, adab_pb_adap, by = mergecol) %>% - left_join(adab_pb_nabp, by = mergecol) %>% - mutate( - NABNFL = ifelse(is.na(NABPFL), "TRUE", "FALSE"), - NABNFL = NABNFL == "TRUE" - ) %>% - var_relabel( - ADPBLPFL = "Post-baseline evaluable patients for ADA", - ADAPFL = "Patients positive for ADA", - NABPFL = "Patients positive for NAb", - NABNFL = "Patients negative for NAb" - ) -``` - -## Standard Table - -```{r variant1, test = list(result_v1 = "result")} -# Layout for Baseline Prevalence of NAbs -lyt_bl <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("ADABLPFL", "PADABLPFL"), - .stats = "count", - var_labels = "Baseline Prevalence of NAbs", - show_labels = "visible", - table_names = "t1" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "PNABBLFL", - table_names = "t2", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NNABBLFL", - .stats = "count", - table_names = "t3", - .indent_mods = 1L, - show_labels = "hidden" - ) - -# Layout for incidence of NAbs -lyt_pb <- basic_table(show_colcounts = TRUE) %>% - split_cols_by( - "ACTARM", - split_fun = add_combo_levels(combodf) - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = c("ADPBLPFL", "ADAPFL"), - .stats = "count", - var_labels = "Incidence of NAbs", - show_labels = "visible", - table_names = "tb1" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NABPFL", - table_names = "tb2", - .indent_mods = 1L, - show_labels = "hidden" - ) %>% - count_patients_with_flags( - "USUBJID", - flag_variables = "NABNFL", - .stats = "count", - table_names = "tb3", - .indent_mods = 1L, - show_labels = "hidden" - ) - -result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) -result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) - -# Combine tables. -result <- rbind(result_1, result_2) - -# Change the column order. -result <- cbind_rtables(result[, 1], result[, 3]) %>% - cbind_rtables(result[, 4]) %>% - cbind_rtables(result[, 2]) %>% - cbind_rtables(result[, 5]) - -main_title(result) <- paste( - "Baseline Prevalence and Incidence of Neutralizing Antibodies (NAbs)" -) -subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) -main_footer(result) <- paste( - "NAb = Neutralizing Antibodies ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient for ADA = a patient with an ADA assay result from a baseline sample(s) Baseline evaluable patient for NAb = a patient with a NAb assay result from a baseline sample(s) Post-baseline evaluable patient for ADA = a patient with an ADA assay result from at least one post-baseline sample Post-baseline evaluable patient for NAb = a patient with a NAb assay result from at least one post-baseline sample Number of patients positive for ADA = the number of post-baseline evaluable patients for ADA determined to have Treatment Emergent ADA during the study period. -Number of patients positive for NAb = the number (and percentage) of post-baseline evaluable patients for ADA determined to have at least one positive post-baseline NAb result during the study period. Number of patients negative for NAb = number of post-baseline evaluable patients with all negative post-baseline NAb results." -) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ECG/egt01.qmd b/book/tables/ECG/egt01.qmd deleted file mode 100644 index 017188e635..0000000000 --- a/book/tables/ECG/egt01.qmd +++ /dev/null @@ -1,142 +0,0 @@ ---- -title: EGT01 -subtitle: ECG Results and Change from Baseline by Visit ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(dplyr) -library(tern) -library(scda) - -# Data should be filtered for the studied Parameter (`PARAM`) and the -# Analysis Visit (`AVISIT`). According to the GDSR template, the values for -# the `AVISIT` reported in the EGT01 standard may be: -# 'POST-BASELINE MAXIMUM', 'POST-BASELINE MINIMUM', 'POST-BASELINE LAST'. - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg) - -adeg_f <- adeg %>% - filter(ANL01FL == "Y") %>% - filter(PARAM %in% c("Heart Rate", "QT Duration", "RR Duration")) -``` - -## Standard Table - -```{r variant1, test = list(result_v1 = "result")} -# Define the split function -split_fun <- drop_split_levels - -afun <- function(x, .var, .spl_context, ...) { - n_fun <- sum(!is.na(x), na.rm = TRUE) - if (n_fun == 0) { - mean_sd_fun <- c(NA, NA) - median_fun <- NA - min_max_fun <- c(NA, NA) - } else { - mean_sd_fun <- c(mean(x, na.rm = TRUE), sd(x, na.rm = TRUE)) - median_fun <- median(x, na.rm = TRUE) - min_max_fun <- c(min(x), max(x)) - } - is_chg <- .var == "CHG" - is_baseline <- .spl_context$value[which(.spl_context$split == "AVISIT")] == "BASELINE" - if (is_baseline && is_chg) n_fun <- mean_sd_fun <- median_fun <- min_max_fun <- NULL - - in_rows( - "n" = n_fun, - "Mean (SD)" = mean_sd_fun, - "Median" = median_fun, - "Min - Max" = min_max_fun, - .formats = list("n" = "xx", "Mean (SD)" = "xx.xx (xx.xx)", "Median" = "xx.xx", "Min - Max" = "xx.xx - xx.xx"), - .format_na_strs = list("n" = "NE", "Mean (SD)" = "NE (NE)", "Median" = "NE", "Min - Max" = "NE - NE") - ) -} - -lyt <- basic_table(show_colcounts = TRUE) %>% - split_cols_by("ACTARM") %>% - split_rows_by("PARAM", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$PARAM)) %>% - split_rows_by("AVISIT", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$AVISIT)) %>% - split_cols_by_multivar( - vars = c("AVAL", "CHG"), - varlabels = c("Value at Visit", "Change from\nBaseline") - ) %>% - analyze_colvars(afun = afun) - -result <- build_table(lyt, adeg_f, alt_counts_df = adsl) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| screenshot.opts = list(delay = 16) - -library(teal.modules.clinical) -library(scda) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg) - -app <- init( - data = cdisc_data( - cdisc_dataset("ADSL", - adsl, - code = 'ADSL <- df_explicit_na(synthetic_cdisc_dataset("latest", "adsl"))' - ), - cdisc_dataset("ADEG", - adeg, - code = 'ADEG <- df_explicit_na(synthetic_cdisc_dataset("latest", "adeg"))' - ), - check = TRUE - ), - modules = modules( - tm_t_summary_by( - label = "ECG Results and Change from Baseline by Visit", - dataname = "ADEG", - arm_var = choices_selected( - choices = variable_choices(adsl, c("ARM", "ARMCD")), - selected = "ARM" - ), - by_vars = choices_selected( - choices = variable_choices(adeg, c("PARAM", "AVISIT")), - selected = c("AVISIT") - ), - summarize_vars = choices_selected( - choices = variable_choices(adeg, c("AVAL", "CHG")), - selected = c("AVAL") - ), - useNA = "ifany", - paramcd = choices_selected( - choices = value_choices(adeg, "PARAMCD", "PARAM"), - selected = "HR" - ), - parallel_vars = TRUE - ) - ), - filter = list(ADEG = list(AVAL = list())) -) - -shinyApp(app$ui, app$server) -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ECG/egt02.qmd b/book/tables/ECG/egt02.qmd deleted file mode 100644 index addbda506f..0000000000 --- a/book/tables/ECG/egt02.qmd +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: EGT02 -subtitle: ECG Abnormalities (EGT02_1 & EGT02_2) ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(dplyr) -library(scda) -library(tern) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg) - -# Note: We keep only post-baseline for analysis. -adeg_f <- adeg %>% - filter(ONTRTFL == "Y") %>% - filter(PARAM %in% c("Heart Rate", "QT Duration", "RR Duration")) %>% - filter(ANRIND != "") %>% - var_relabel( - PARAM = "Assessment", - ANRIND = "Abnormality" - ) -``` - -## ECG Abnormalities Regardless
of Abnormality at Baseline - -```{r variant1, test = list(result_v1 = "result")} -split_fun <- drop_split_levels - -lyt <- basic_table(show_colcounts = TRUE) %>% - split_cols_by(var = "ACTARM") %>% - split_rows_by( - "PARAM", - split_fun = split_fun, - label_pos = "topleft", - split_label = obj_label(adeg_f$PARAM) - ) %>% - count_abnormal("ANRIND", abnormal = list(Low = "LOW", High = "HIGH"), exclude_base_abn = FALSE) %>% - append_varlabels(adeg_f, "ANRIND", indent = 1L) - -result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) -result -``` - -## ECG Abnormalities Among Subjects
Without Abnormality at Baseline - -```{r variant2, test = list(result_v2 = "result")} -split_fun <- drop_split_levels - -lyt <- basic_table(show_colcounts = TRUE) %>% - split_cols_by(var = "ACTARM") %>% - split_rows_by( - "PARAM", - split_fun = split_fun, - label_pos = "topleft", - split_label = obj_label(adeg_f$PARAM) - ) %>% - count_abnormal("ANRIND", abnormal = list(Low = "LOW", High = "HIGH"), exclude_base_abn = TRUE) %>% - append_varlabels(adeg_f, "ANRIND", indent = 1L) - -result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| screenshot.opts = list(delay = 18) - -library(scda) -library(teal.modules.clinical) -library(dplyr) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -app <- init( - data = cdisc_data( - cdisc_dataset("ADSL", adsl, code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl")'), - cdisc_dataset("ADEG", adeg, code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg")'), - check = TRUE - ), - modules = modules( - tm_t_abnormality( - label = "Abnormality Table", - dataname = "ADEG", - arm_var = choices_selected( - choices = variable_choices(adsl, subset = c("ARM", "ARMCD")), - selected = "ARM" - ), - by_vars = choices_selected( - choices = variable_choices(adeg, subset = c("EGCAT", "PARAM", "AVISIT")), - selected = c("PARAM"), - keep_order = TRUE - ), - grade = choices_selected( - choices = variable_choices(adeg, subset = "ANRIND"), - selected = "ANRIND", - fixed = TRUE - ), - abnormal = list(Low = "LOW", High = "HIGH"), - exclude_base_abn = FALSE - ) - ) -) - -shinyApp(app$ui, app$server) -``` - -{{< include ../../repro.qmd >}} -::: diff --git a/book/tables/ECG/egt03.qmd b/book/tables/ECG/egt03.qmd deleted file mode 100644 index 6d335eb12e..0000000000 --- a/book/tables/ECG/egt03.qmd +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: EGT03 -subtitle: Shift Table of ECG Interval Data -- Baseline Versus Minimum/Maximum Post-Baseline ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(scda) -library(tern) -library(dplyr) - -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adeg <- df_explicit_na(adeg) - -adeg_labels <- var_labels(adeg) - -adeg_f_pbmin <- subset( - adeg, - PARAMCD == "HR" & # Heart Rate - SAFFL == "Y" & # "Safety Population Flag" - ONTRTFL == "Y" & # "On Treatment Record Flag" - AVISIT == "POST-BASELINE MINIMUM" # "Analysis Visit" -) - -adeg_f_pbmax <- subset( - adeg, - PARAMCD == "HR" & # Heart Rate - SAFFL == "Y" & # "Safety Population Flag" - ONTRTFL == "Y" & # "On Treatment Record Flag" - AVISIT == "POST-BASELINE MAXIMUM" # "Analysis Visit" -) - -var_labels(adeg_f_pbmin) <- adeg_labels -var_labels(adeg_f_pbmax) <- adeg_labels -``` - -## Table of Baseline Versus
Minimum Post-Baseline - -For the EGT03 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. -For illustration purposes, missing data are added to the example dataset. - -```{r variant1, test = list(result_v1 = "result")} -set.seed(123, kind = "Mersenne-Twister") - -adeg_f_pbmin$BNRIND <- factor( - adeg_f_pbmin$BNRIND, - levels = c("LOW", "NORMAL", "HIGH", "Missing"), - labels = c("LOW", "NORMAL", "HIGH", "Missing") -) -adeg_f_pbmin$ANRIND <- factor( - adeg_f_pbmin$ANRIND, - levels = c("LOW", "NORMAL", "HIGH", "Missing"), - labels = c("LOW", "NORMAL", "HIGH", "Missing") -) - -adeg_f_pbmin$BNRIND[sample(1:nrow(adeg_f_pbmin), size = 5)] <- "Missing" -adeg_f_pbmin$ANRIND[sample(1:nrow(adeg_f_pbmin), size = 5)] <- "Missing" - -attr(adeg_f_pbmin$ANRIND, "label") <- "Analysis Reference Range Indicator" -attr(adeg_f_pbmin$BNRIND, "label") <- "Baseline Reference Range Indicator" - -# Temporary solution for overarching column -adeg_f_pbmin <- adeg_f_pbmin %>% mutate(min_label = "Minimum Post-Baseline Assessment") - -# Define the split function -split_fun <- drop_split_levels - -lyt <- basic_table() %>% - split_cols_by("min_label") %>% - split_cols_by("ANRIND") %>% - split_rows_by("ARMCD", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f_pbmin$ARMCD)) %>% - add_rowcounts() %>% - analyze_vars("BNRIND", denom = "N_row", .stats = "count_fraction") %>% - append_varlabels(adeg_f_pbmin, c("BNRIND"), indent = 1L) - -result <- build_table( - lyt = lyt, - df = adeg_f_pbmin -) - -result -``` - -## Table of Baseline Versus
Maximum Post-Baseline - -For the EGT03 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. -For illustration purpose, missing data are added to the example dataset. - -```{r variant2, test = list(result_v2 = "result")} -set.seed(123, kind = "Mersenne-Twister") - -adeg_f_pbmax$BNRIND <- factor( - adeg_f_pbmax$BNRIND, - levels = c("LOW", "NORMAL", "HIGH", "Missing"), - labels = c("LOW", "NORMAL", "HIGH", "Missing") -) -adeg_f_pbmax$ANRIND <- factor( - adeg_f_pbmax$ANRIND, - levels = c("LOW", "NORMAL", "HIGH", "Missing"), - labels = c("LOW", "NORMAL", "HIGH", "Missing") -) - -adeg_f_pbmax$BNRIND[sample(1:nrow(adeg_f_pbmax), size = 5)] <- "Missing" -adeg_f_pbmax$ANRIND[sample(1:nrow(adeg_f_pbmax), size = 5)] <- "Missing" - -attr(adeg_f_pbmax$ANRIND, "label") <- "Analysis Reference Range Indicator" -attr(adeg_f_pbmax$BNRIND, "label") <- "Baseline Reference Range Indicator" - -# Temporary solution for overarching column -adeg_f_pbmax <- adeg_f_pbmax %>% mutate(max_label = "Maximum Post-Baseline Assessment") - -# Define the split function -split_fun <- drop_split_levels - -lyt <- basic_table() %>% - split_cols_by("max_label") %>% - split_cols_by("ANRIND") %>% - split_rows_by("ARMCD", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f_pbmax$ARMCD)) %>% - add_rowcounts() %>% - analyze_vars("BNRIND", denom = "N_row", .stats = "count_fraction") %>% - append_varlabels(adeg_f_pbmax, c("BNRIND"), indent = 1L) - -result <- build_table( - lyt = lyt, - df = adeg_f_pbmax -) - -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| screenshot.opts = list(delay = 16) - -library(dplyr) -library(tern) -library(scda) -library(teal.modules.clinical) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -app <- init( - data = cdisc_data( - cdisc_dataset("ADSL", adsl, code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl")'), - cdisc_dataset("ADEG", adeg, code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg")'), - check = TRUE - ), - modules = modules( - tm_t_shift_by_arm( - label = "Shift by Arm Table", - dataname = "ADEG", - arm_var = choices_selected( - variable_choices(adsl, subset = c("ARM", "ARMCD")), - selected = "ARM" - ), - paramcd = choices_selected( - value_choices(adeg, "PARAMCD"), - selected = "HR" - ), - visit_var = choices_selected( - value_choices(adeg, "AVISIT"), - selected = "POST-BASELINE MINIMUM" - ), - aval_var = choices_selected( - variable_choices(adeg, subset = "ANRIND"), - selected = "ANRIND", fixed = TRUE - ), - base_var = choices_selected( - variable_choices(adeg, subset = "BNRIND"), - selected = "BNRIND", fixed = TRUE - ), - treatment_flag_var = choices_selected( - variable_choices(adeg, subset = "ONTRTFL"), - selected = "ONTRTFL", fixed = TRUE - ), - treatment_flag = choices_selected( - value_choices(adeg, "ONTRTFL"), - selected = "Y", fixed = TRUE - ) - ) - ), - filter = list(ADSL = list(SAFFL = "Y")) -) - -shinyApp(app$ui, app$server) -``` - -{{< include ../../repro.qmd >}} - -::: diff --git a/book/tables/ECG/egt04.qmd b/book/tables/ECG/egt04.qmd deleted file mode 100644 index fb960b9b2a..0000000000 --- a/book/tables/ECG/egt04.qmd +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: EGT04 -subtitle: Shift Table of Qualitative ECG Assessments ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -For the EGT04 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. -For illustration purposes, missing data are added to the example dataset. - -```{r setup, message=FALSE} -#| code-fold: show - -library(scda) -library(tern) -library(dplyr) -set.seed(123) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg, omit_columns = c("AVALC", "BASEC")) - -adeg_labels <- var_labels(adeg) - -adeg_f <- subset( - adeg, - PARAMCD == "ECGINTP" & # Analysis in terms of "NORMAL"/"ABNORMAL" (AVALC) - SAFFL == "Y" & # "Safety Population Flag" - ONTRTFL == "Y" & # "On Treatment Record Flag" - WORS02FL == "Y" # "Worst Post-Baseline Observation" -) - -adeg_f$AVALC[sample(1:nrow(adeg_f), size = 5)] <- "Missing" -adeg_f$BASEC[sample(1:nrow(adeg_f), size = 5)] <- "Missing" -adeg_f$AVALC <- factor( - adeg_f$AVALC, - levels = c("NORMAL", "ABNORMAL", "Missing"), - labels = c("Normal", "Abnormal", "Missing") -) -adeg_f$BASEC <- factor( - adeg_f$BASEC, - levels = c("NORMAL", "ABNORMAL", "Missing"), - labels = c("Normal", "Abnormal", "Missing") -) - -var_labels(adeg_f) <- adeg_labels -adeg_f <- adeg_f %>% - var_relabel(BASEC = "Baseline") - -# Temprary solution for over arching column -adeg_f <- adeg_f %>% mutate(postbaseline_label = "Post-Baseline") -``` - -## Standard Table - -The EGT04 template consists of a stacked list of contingency tables, one per group. -For each group, the n's across all cells must add up to the group N in the analysis, and percentages are calculated using N as the denominator. - -```{r variant1, test = list(result_v1 = "result")} -# Define the split function -split_fun <- drop_split_levels - -lyt <- basic_table() %>% - split_cols_by("postbaseline_label") %>% - split_cols_by("AVALC") %>% - split_rows_by("ARM", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$ARM)) %>% - add_rowcounts() %>% - analyze_vars( - "BASEC", - denom = "N_row", - .stats = "count_fraction", - na.rm = FALSE - ) %>% - append_varlabels(adeg_f, c("BASEC"), indent = 1L) - -result <- build_table(lyt, adeg_f) -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| code-fold: show - -# In progress -``` - -{{< include ../../repro.qmd >}} - -::: diff --git a/book/tables/ECG/egt05_qtcat.qmd b/book/tables/ECG/egt05_qtcat.qmd deleted file mode 100644 index db249bacc5..0000000000 --- a/book/tables/ECG/egt05_qtcat.qmd +++ /dev/null @@ -1,255 +0,0 @@ ---- -title: EGT05_QTCAT -subtitle: ECG Actual Values and Changes from Baseline by Visit ---- - ------------------------------------------------------------------------- - -{{< include ../../test-utils/envir_hook.qmd >}} - -::: panel-tabset -## Data Setup - -```{r setup, message=FALSE} -#| code-fold: show - -library(tern) -library(scda) -library(dplyr) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") - -# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg) - -adeg_labels <- var_labels(adeg) -adeg_f <- adeg %>% - filter( - PARAMCD == "QT", - ANL01FL == "Y" - ) %>% - mutate( - AVALCAT1 = case_when( - AVAL <= 450 ~ "<=450 msec", - AVAL <= 480 ~ ">450 to <=480 msec", - AVAL <= 500 ~ ">480 to <= 500 msec", - AVAL > 500 ~ ">500 msec", - is.na(AVAL) ~ "" - ), - CHGCAT1 = case_when( - CHG <= 30 ~ "<=30 msec", - CHG <= 60 ~ ">30 to <=60 msec", - CHG > 60 ~ ">60 msec", - is.na(CHG) ~ "" - ) - ) %>% - mutate( - AVALCAT1 = factor( - AVALCAT1, - levels = c( - "<=450 msec", - ">450 to <=480 msec", - ">480 to <= 500 msec", - ">500 msec", - "" - ) - ), - CHGCAT1 = factor( - CHGCAT1, - levels = c( - "<=30 msec", - ">30 to <=60 msec", - ">60 msec", - "" - ) - ) - ) %>% - var_relabel( - AVALCAT1 = "Value at Visit", - CHGCAT1 = "Change from Baseline" - ) -``` - -## Standard Table - -```{r variant1, test = list(result_v1 = "result")} -split_fun <- drop_split_levels - -lyt <- basic_table(show_colcounts = TRUE) %>% - split_cols_by("ARM") %>% - split_rows_by( - "PARAM", - split_label = obj_label(adeg_f$PARAM), - split_fun = split_fun, - label_pos = "topleft" - ) %>% - split_rows_by( - "AVISIT", - split_label = obj_label(adeg_f$AVISIT), - split_fun = split_fun, - label_pos = "topleft" - ) %>% - analyze_vars( - vars = c("AVALCAT1", "CHGCAT1"), - var_labels = c("Value at Visit", "Change from Baseline") - ) %>% - append_topleft(" Category") - -result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) %>% - prune_table() - -result -``` - -{{< include ../../test-utils/save_results.qmd >}} - -## `teal` App - -```{r teal, message=FALSE, opts.label='skip_if_testing'} -#| screenshot.opts = list(delay = 24) - -library(teal.modules.clinical) -library(scda) -library(dplyr) - -adsl <- synthetic_cdisc_dataset("latest", "adsl") -adeg <- synthetic_cdisc_dataset("latest", "adeg") -adsl <- df_explicit_na(adsl) -adeg <- df_explicit_na(adeg) -adeg_labels <- var_labels(adeg) - -adeg_f <- adeg %>% - filter( - ANL01FL == "Y" # no need to filter for PARAMCD here - ) %>% - mutate( - AVALCAT1 = case_when( - AVAL <= 450 ~ "<=450 msec", - AVAL <= 480 ~ ">450 to <=480 msec", - AVAL <= 500 ~ ">480 to <= 500 msec", - AVAL > 500 ~ ">500 msec", - is.na(AVAL) ~ "" - ), - CHGCAT1 = case_when( - CHG <= 30 ~ "<=30 msec", - CHG <= 60 ~ ">30 to <=60 msec", - CHG > 60 ~ ">60 msec", - is.na(CHG) ~ "" - ) - ) %>% - mutate( - AVALCAT1 = factor( - AVALCAT1, - levels = c( - "<=450 msec", - ">450 to <=480 msec", - ">480 to <= 500 msec", - ">500 msec", - "" - ) - ), - CHGCAT1 = factor( - CHGCAT1, - levels = c( - "<=30 msec", - ">30 to <=60 msec", - ">60 msec", - "" - ) - ) - ) -var_labels(adeg_f) <- c( - adeg_labels, - "AVALCAT1" = "Value at Visit", - "CHGCAT1" = "Change from Baseline" -) -app <- init( - data = cdisc_data( - cdisc_dataset("ADSL", - adsl, - code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl") - ADSL <- df_explicit_na(ADSL)' - ), - cdisc_dataset("ADEG", - adeg_f, - code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg") - ADEG <- df_explicit_na(ADEG) - ADEG_labels <- var_labels(ADEG) - - ADEG <- ADEG %>% - filter( - ANL01FL == "Y" - ) %>% - mutate( - AVALCAT1 = case_when( - AVAL <= 450 ~ "<=450 msec", - AVAL <= 480 ~ ">450 to <=480 msec", - AVAL <= 500 ~ ">480 to <= 500 msec", - AVAL > 500 ~ ">500 msec", - is.na(AVAL) ~ ""), - CHGCAT1 = case_when( - CHG <= 30 ~ "<=30 msec", - CHG <= 60 ~ ">30 to <=60 msec", - CHG > 60 ~ ">60 msec", - is.na(CHG) ~ "") - ) %>% mutate( - AVALCAT1 = factor( - AVALCAT1, - levels = c( - "<=450 msec", - ">450 to <=480 msec", - ">480 to <= 500 msec", - ">500 msec", - "" - ) - ), - CHGCAT1 = factor( - CHGCAT1, - levels = c( - "<=30 msec", - ">30 to <=60 msec", - ">60 msec", - "" - ) - ) - ) - var_labels(ADEG) <- c( - ADEG_labels, - "AVALCAT1" = "Value at Visit", - "CHGCAT1" = "Change from Baseline" - )' - ), - check = TRUE - ), - modules = modules( - tm_t_summary_by( - label = "ECG Actual Values and Changes from Baseline by Visit", - dataname = "ADEG", - arm_var = choices_selected( - choices = variable_choices(adsl, c("ARM", "ARMCD")), - selected = "ARM" - ), - by_vars = choices_selected( - choices = variable_choices(adeg_f, c("PARAM", "AVISIT")), - selected = c("AVISIT") - ), - summarize_vars = choices_selected( - choices = variable_choices(adeg_f, c("AVALCAT1", "CHGCAT1")), - selected = c("AVALCAT1", "CHGCAT1") - ), - useNA = "ifany", - paramcd = choices_selected( - choices = value_choices(adeg_f, "PARAMCD", "PARAM"), - selected = "QT" - ) - ) - ) -) - -shinyApp(app$ui, app$server) -``` - -{{< include ../../repro.qmd >}} -::: From cdf7d4847b96f9330f1fd5a9db35d30f8face93e Mon Sep 17 00:00:00 2001 From: Emily de la Rua Date: Thu, 21 Sep 2023 13:28:41 -0400 Subject: [PATCH 11/11] Restore deleted files, regenerate index --- book/listings/ADA/adal02.qmd | 131 ++++++++++++++++ book/listings/ECG/egl01.qmd | 89 +++++++++++ book/tables/ADA/adat01.qmd | 230 ++++++++++++++++++++++++++++ book/tables/ADA/adat02.qmd | 151 +++++++++++++++++++ book/tables/ADA/adat03.qmd | 131 ++++++++++++++++ book/tables/ADA/adat04a.qmd | 240 ++++++++++++++++++++++++++++++ book/tables/ADA/adat04b.qmd | 223 ++++++++++++++++++++++++++++ book/tables/ECG/egt01.qmd | 142 ++++++++++++++++++ book/tables/ECG/egt02.qmd | 126 ++++++++++++++++ book/tables/ECG/egt03.qmd | 204 +++++++++++++++++++++++++ book/tables/ECG/egt04.qmd | 100 +++++++++++++ book/tables/ECG/egt05_qtcat.qmd | 255 ++++++++++++++++++++++++++++++++ book/tlg-index.qmd | 62 ++++---- 13 files changed, 2053 insertions(+), 31 deletions(-) create mode 100644 book/listings/ADA/adal02.qmd create mode 100644 book/listings/ECG/egl01.qmd create mode 100644 book/tables/ADA/adat01.qmd create mode 100644 book/tables/ADA/adat02.qmd create mode 100644 book/tables/ADA/adat03.qmd create mode 100644 book/tables/ADA/adat04a.qmd create mode 100644 book/tables/ADA/adat04b.qmd create mode 100644 book/tables/ECG/egt01.qmd create mode 100644 book/tables/ECG/egt02.qmd create mode 100644 book/tables/ECG/egt03.qmd create mode 100644 book/tables/ECG/egt04.qmd create mode 100644 book/tables/ECG/egt05_qtcat.qmd diff --git a/book/listings/ADA/adal02.qmd b/book/listings/ADA/adal02.qmd new file mode 100644 index 0000000000..9ddcaf7f56 --- /dev/null +++ b/book/listings/ADA/adal02.qmd @@ -0,0 +1,131 @@ +--- +title: ADAL02 +subtitle: Listing of Anti-Drug Antibody Data for Treatment Emergent ADA Positive Patients +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(dplyr) +library(rlistings) +library(scda) + +adab <- synthetic_cdisc_dataset("latest", "adab") %>% + filter(NFRLT %% 1 == 0 & NFRLT > 0) + +trt <- "A: Drug X" +drug_a <- "A: Drug X Antibody" +drugcd <- unique(adab$PARAMCD[adab$PARAM == "Antibody titer units"])[1] +min_titer <- 1.10 + +adab_x <- adab %>% + filter( + ARM == trt, + PARCAT1 == drug_a, + ADPBLPFL == "Y" + ) %>% + select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% + unique() %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + filter(if_any(matches("Treatment Emergent - Positive"), ~ .x == 1)) %>% + # filter(`Treatment Emergent - Positive` == 1) %>% + mutate( + VISN = factor(paste0( + VISIT, "\n(Day ", + ifelse( + NFRLT %% 1 == 0, + NFRLT, + as.character(format(round(NFRLT, 2), nsmall = 2)) + ), + ")" + )), + PTES = ifelse( + ifelse("Treatment induced ADA" %in% names(.), `Treatment induced ADA` == 1, F), + ifelse( + "Transient ADA" %in% names(.) & `Transient ADA` == 1, + "Induced (Transient)", + "Induced (Persistent)" + ), + "Enhanced" + ) + ) %>% + mutate( + AVAL = paste0( + ifelse( + ifelse("ADA interpreted per sample result" %in% names(.), `ADA interpreted per sample result` == 0, F), + "NEGATIVE", + ifelse( + ifelse("Antibody titer units" %in% names(.), !is.na(`Antibody titer units`), F), + ifelse( + `Antibody titer units` < min_titer, + paste0("<", format(min_titer, nsmall = 2)), + as.character(format(round(`Antibody titer units`, 2), nsmall = 2)) + ), + "---" + ) + ), + ifelse( + ifelse("NAB interpreted per sample result" %in% names(.), `NAB interpreted per sample result` == 1, F), + "*", + "" + ) + ) + ) + +out <- adab_x %>% + select(USUBJID, VISN, AVAL, PTES) %>% + tidyr::pivot_wider( + names_from = VISN, + values_from = AVAL + ) %>% + select(USUBJID, unique(adab_x$VISN[order(adab_x$NFRLT)]), PTES) + +var_labels(out) <- names(out) + +out <- out %>% + var_relabel( + USUBJID = "Subject ID", + PTES = "Patient Treatment\nEmergent ADA Status" + ) +``` + +## Standard Listing + +```{r lsting, test = list(lsting = "lsting")} +lsting <- as_listing( + out, + key_cols = "USUBJID", + disp_cols = names(out), + main_title = paste0( + "Listing of Anti-", drugcd, " Antibody Data for Treatment Emergent ADA Positive Patients, PK Population", + "\nProtocol: ", unique(adab$PARCAT1)[1] + ), + subtitles = paste("\nTreatment Group:", trt), + main_footer = "Minimum reportable titer = 1.10 (example only) +--- = No sample evaluated +ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) +Number of patients positive for Treatment Emergent ADA = the number of post-baseline evaluable patients determined to have treatment-induced ADA or treatment-enhanced ADA during the study period. +Treatment-induced ADA = a patient with negative or missing baseline ADA result(s) and at least one positive post-baseline ADA result. +Treatment-enhanced ADA = a patient with positive ADA result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. +Transient ADA = ADA positive result detected (a) at only one post-baseline sampling timepoint (excluding last timepoint) OR (b) at 2 or more timepoints during treatment where the first and last ADA positive samples are separated by a period of < 16 weeks, irrespective of any negative samples in between. +Persistent ADA = ADA positive result detected (a) at the last post-baseline sampling timepoint, OR (b) at 2 or more time points during treatment where the first and last ADA positive samples are separated by a period ≥ 16 weeks, irrespective of any negative samples in between. +Asterisk denotes sample that tested positive for Neutralizing Antibodies." +) + +head(lsting, 20) +``` + +{{< include ../../test-utils/save_results.qmd >}} + +{{< include ../../repro.qmd >}} +::: diff --git a/book/listings/ECG/egl01.qmd b/book/listings/ECG/egl01.qmd new file mode 100644 index 0000000000..a595b864c9 --- /dev/null +++ b/book/listings/ECG/egl01.qmd @@ -0,0 +1,89 @@ +--- +title: EGL01 +subtitle: 'Listing of ECG Data: Safety-Evaluable Patients' +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(dplyr) +library(scda) +library(rlistings) + +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +get_param_unit_range <- function(dataset) { + u_rng <- lapply(unique(dataset$PARAMCD), function(p) { + dat <- dataset %>% filter(PARAMCD == p) + list( + unit = unique(dat$AVALU), + range = paste0(unique(dat$ANRLO), "-", unique(dat$ANRHI)) + ) + }) + names(u_rng) <- unique(dataset$PARAMCD) + u_rng +} + +eg_u_rng <- get_param_unit_range(adeg) + +adeg_sub <- adeg %>% + filter(!is.na(AVAL) & SAFFL == "Y" & ANL01FL == "Y" & !is.na(EGSEQ) & PARAMCD != "ECGINTP") %>% + mutate( + CRTNPT = paste(SITEID, sub("^.*-([[:alnum:]]+)$", "\\1", SUBJID), sep = "/"), + AGSXRC = paste(AGE, SEX, RACE, sep = "/"), + AVAL = format(round(AVAL, 2), nsmall = 2), + AVAL_ANRIND = ifelse(ANRIND %in% c("NORMAL", ""), AVAL, paste(AVAL, substr(ANRIND, 1, 1), sep = "/")), + CHG = format(round(CHG, 2), nsmall = 2) + ) + +anl_eg <- adeg_sub %>% + select(SUBJID, CRTNPT, AGSXRC, TRT01A, PARAMCD, AVAL_ANRIND, CHG, ADY, AVISIT, ADTM) %>% + tidyr::pivot_wider( + id_cols = c(SUBJID, CRTNPT, AGSXRC, TRT01A, ADY, AVISIT, ADTM), + names_from = PARAMCD, + values_from = c(AVAL_ANRIND, CHG) + ) + +out <- anl_eg %>% + select(CRTNPT, AGSXRC, TRT01A, AVISIT, ADY, AVAL_ANRIND_HR, CHG_HR, AVAL_ANRIND_QT, CHG_QT, AVAL_ANRIND_RR, CHG_RR) %>% + var_relabel( + CRTNPT = "Center/Subject ID", + AGSXRC = "Age/Sex/Race", + TRT01A = "Treatment", + AVISIT = "Visit", + ADY = "Study\nDay", + AVAL_ANRIND_HR = paste0("Heart Rate Result\n(", eg_u_rng$HR$unit, ");\nRange:(", eg_u_rng$HR$range, ")"), + CHG_HR = "Heart Rate\nChange from BL", + AVAL_ANRIND_QT = paste0("QT Duration Result\n(", eg_u_rng$QT$unit, ");\nRange:(", eg_u_rng$QT$range, ")"), + CHG_QT = "QT Duration\nChange from BL", + AVAL_ANRIND_RR = paste0("RR Duration Result\n(", eg_u_rng$RR$unit, ");\nRange:(", eg_u_rng$RR$range, ")"), + CHG_RR = "RR Duration\nChange from BL" + ) +``` + +## Standard Listing + +```{r lsting, test = list(lsting = "lsting")} +lsting <- as_listing( + out, + key_cols = c("CRTNPT", "AGSXRC", "TRT01A", "AVISIT", "ADY"), + disp_cols = names(out), + main_title = "Listing of ECG Data: Safety-Evaluable Patients", + main_footer = "Baseline is the patient's last observation prior to initiation of study drug. Abnormalities are flagged as high (H) or low (L) if + outside the Roche standard reference range." +) + +head(lsting, 20) +``` + +{{< include ../../test-utils/save_results.qmd >}} + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ADA/adat01.qmd b/book/tables/ADA/adat01.qmd new file mode 100644 index 0000000000..31a13bd819 --- /dev/null +++ b/book/tables/ADA/adat01.qmd @@ -0,0 +1,230 @@ +--- +title: ADAT01 +subtitle: Baseline Prevalence and Incidence of Treatment Emergent ADA +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(tern) +library(dplyr) +library(scda) +library(tibble) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adab <- synthetic_cdisc_dataset("latest", "adab") + +combodf <- tribble( + ~valname, ~label, ~levelcombo, ~exargs, + "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), + "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() +) + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adab <- adab %>% + filter(PARCAT1 == "A: Drug X Antibody") %>% + select(-ARRLT, -NRRLT) + +# Baseline Pts +adab_b <- df_explicit_na(adab) %>% + filter( + ABLFL == "Y", + ADABLPFL == "Y", + PARAM %in% c("ADA interpreted per sample result") + ) %>% + select(-PARAMCD, -AVALC, -AVALU) %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate_at( + c("ADA interpreted per sample result"), + as.logical + ) %>% + mutate( + ADABLPFL = ADABLPFL == "Y", + PADABLPFL = `ADA interpreted per sample result` == "TRUE", + NADABLPFL = `ADA interpreted per sample result` == "FALSE" + ) %>% + var_relabel( + ADABLPFL = "Baseline evaluable patients", + PADABLPFL = "Patient with a positive sample at baseline", + NADABLPFL = "Patient with no positive samples at baseline" + ) + +# Post Baseline Treatment Enhanced NAb positive Pts +adab_pb <- df_explicit_na(adab) %>% + filter( + ABLFL != "Y", + ADPBLPFL == "Y", + PARAM %in% c( + "ADA interpreted per sample result", + "Treatment Emergent - Positive", + "Treatment induced ADA", + "Treatment enhanced ADA", + "Treatment Emergent - Negative", + "Treatment unaffected" + ) + ) %>% + select(-PARAMCD, -AVALC, -AVALU) %>% + unique() %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate( + across( + any_of(c( + "ADA interpreted per sample result", "Treatment Emergent - Positive", + "Treatment induced ADA", "Treatment enhanced ADA", + "Treatment Emergent - Negative", "Treatment unaffected" + )), + as.logical + ) + ) %>% + mutate( + ADPBLPFL = ADPBLPFL == "Y", + PTEFL = if (exists("Treatment Emergent - Positive", where = .)) `Treatment Emergent - Positive` == "TRUE" else FALSE, + TIFL = if (exists("Treatment induced ADA", where = .)) `Treatment induced ADA` == "TRUE" else FALSE, + TEFL = if (exists("Treatment enhanced ADA", where = .)) `Treatment enhanced ADA` == "TRUE" else FALSE, + NTEFL = if (exists("Treatment Emergent - Negative", where = .)) `Treatment Emergent - Negative` == "TRUE" else FALSE, + TUFL = if (exists("Treatment unaffected", where = .)) `Treatment unaffected` == "TRUE" else FALSE + ) %>% + var_relabel( + ADPBLPFL = "Post-baseline evaluable patients", + PTEFL = "Patient positive for Treatment Emergent ADA", + TIFL = "Treatment-induced ADA", + TEFL = "Treatment-enhanced ADA", + NTEFL = "Patient negative for Treatment Emergent ADA", + TUFL = "Treatment unaffected" + ) +``` + +## Standard Table + +```{r variant1, test = list(result_v1 = "result")} +# Layout for Baseline Prevalence of NAbs +lyt_bl <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "ADABLPFL", + .stats = "count", + var_labels = "Baseline Prevalence of ADAs", + show_labels = "visible", + table_names = "t1" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "PADABLPFL", + table_names = "t2", + .indent_mods = 1L, + var_labels = "a", + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NADABLPFL", + .stats = "count", + show_labels = "hidden", + .indent_mods = 1L, + table_names = "t3" + ) + +# Layout for incidence of NAbs +lyt_pb <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "ADPBLPFL", + .stats = "count", + var_labels = "Incidence of Treatment Emergent ADAs", + show_labels = "visible", + table_names = "tb1" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "PTEFL", + table_names = "tb2", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("TIFL", "TEFL"), + .stats = "count", + table_names = "tb3", + .indent_mods = 2L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NTEFL", + table_names = "tb4", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "TUFL", + .stats = "count", + table_names = "tb5", + .indent_mods = 2L, + show_labels = "hidden" + ) + +result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) +result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) + +# Combine tables. +result_1@col_info <- result_2@col_info +result <- rbind(result_1, result_2) + +# Change the column order. +result <- cbind_rtables(result[, 1], result[, 3]) %>% + cbind_rtables(result[, 4]) %>% + cbind_rtables(result[, 2]) %>% + cbind_rtables(result[, 5]) + +main_title(result) <- paste( + "Baseline Prevalence and Incidence of Treatment Emergent ADA" +) +main_footer(result) <- paste( + "ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient = a patient with an ADA assay result from a baseline sample(s) + Post-baseline evaluable patient = a patient with an ADA assay result from at least one post-baseline sample Number of patients positive for Treatment Emergent + ADA = the number (and percentage) of post-baseline evaluable patients determined to have treatment-induced ADA or treatment-enhanced ADA during the study period. + Treatment-induced ADA = a patient with negative or missing baseline ADA result(s) and at least one positive post-baseline ADA result. + Treatment-enhanced ADA = a patient with positive ADA result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. + Number of patients negative for Treatment Emergent ADA = number of post-baseline evaluable patients with negative or missing baseline ADA result(s) and all negative post-baseline results, or a patient who is treatment unaffected. + Treatment unaffected = A post-baseline evaluable patient with a positive ADA result at baseline and (a) where all post-baseline titer results are less than 0.60 t.u. greater than the baseline titer result, OR (b) where all post-baseline results are negative or missing. + For any positive sample with titer result less than the minimum reportable titer or any positive sample where a titer cannot be obtained, titer value is imputed as equal to the minimum reportable titer." +) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ADA/adat02.qmd b/book/tables/ADA/adat02.qmd new file mode 100644 index 0000000000..630e8e817e --- /dev/null +++ b/book/tables/ADA/adat02.qmd @@ -0,0 +1,151 @@ +--- +title: ADAT02 +subtitle: Summary of Patients with Treatment-Induced ADA +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(tern) +library(dplyr) +library(scda) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adab <- synthetic_cdisc_dataset("latest", "adab") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adab <- df_explicit_na(adab) %>% + mutate(ADPBLPFL = "Y") %>% # temp fix + filter( + ADPBLPFL == "Y", + !PARAM %in% c( + "NAB interpreted per sample result", + "NAB Status of a patient", + "Treatment enhanced ADA" + ) + ) %>% + select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% + unique() %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate( + across( + any_of(c( + "Treatment induced ADA", + "Transient ADA", + "Persistent ADA" + )), + as.logical + ) + ) %>% + mutate( + ADPBLPFL = ADPBLPFL == "Y", + TI_ADA = if (exists("Treatment induced ADA", where = .)) `Treatment induced ADA` else FALSE + ) %>% + var_relabel( + ADPBLPFL = "Post-baseline evaluable patients", + TI_ADA = "Treatment-induced ADA patients" + ) + +adab_ti <- adab %>% + filter(TI_ADA) +``` + +## Standard Table + +```{r variant1, test = list(result_v1 = "result")} +# Layout for post-baseline evaluable patient variables from adab dataset. +lyt_adab <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = drop_split_levels + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "ADPBLPFL", + .stats = "count", + table_names = "post_baseline" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "TI_ADA" + ) + +# Layout for treatment-induced patient variables from adab dataset. +lyt_adab_ti <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = keep_split_levels(c("A: Drug X", "C: Combination", "")) # temp fix + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("Transient ADA", "Persistent ADA"), + var_labels = "Treatment-induced ADA patients with", + show_labels = "visible" + ) %>% + analyze_vars( + "Time to onset of ADA", + .stats = "median", + nested = FALSE, + .labels = c(median = "Median time to onset of ADA (weeks)") + ) %>% + analyze_vars( + "Antibody titer units", + .stats = "range", + nested = FALSE, + .labels = c(range = "ADA titer range (min - max)") + ) + +result_adab <- build_table(lyt_adab, df = adab, alt_counts_df = adsl) +result_adab_ti <- build_table(lyt_adab_ti, df = adab_ti, alt_counts_df = adsl) + +# Combine tables. +col_info(result_adab) <- col_info(result_adab_ti) +result <- rbind( + result_adab, + result_adab_ti +) + +main_title(result) <- paste( + "Summary of Patients with Treatment-Induced ADA, PK Population" +) +subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) +main_footer(result) <- paste( + "ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic + Antibodies) + Treatment-induced ADA = negative or missing baseline. + ADA result(s) and at least one positive post-baseline ADA result. + Transient ADA = ADA positive result detected (a) at only one post-baseline + sampling timepoint (excluding last timepoint) OR (b) at 2 or more timepoints + during treatment where the first and last ADA positive samples are separated + by a period of < 16 weeks, irrespective of any negative samples in between. + Persistent ADA = ADA positive result detected (a) at the last post-baseline + sampling timepoint, OR (b) at 2 or more time points during treatment where + the first and last ADA positive samples are separated by a period ≥ 16 + weeks, irrespective of any negative samples in between." +) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ADA/adat03.qmd b/book/tables/ADA/adat03.qmd new file mode 100644 index 0000000000..561c5ab1af --- /dev/null +++ b/book/tables/ADA/adat03.qmd @@ -0,0 +1,131 @@ +--- +title: ADAT03 +subtitle: Summary of Serum Concentrations at Timepoints Where ADA Samples Were Collected and Analyzed +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(dplyr) +library(scda) +library(tern) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adab <- synthetic_cdisc_dataset("latest", "adab") +adpc <- synthetic_cdisc_dataset("latest", "adpc") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adab <- df_explicit_na(adab) +adpc <- df_explicit_na(adpc) + +# Adjust zzz parameter +max_conc <- 15 + +adpc <- adpc %>% select(USUBJID, NFRLT, AVAL, AVALU, AVALCAT1) + +anl <- adab %>% + filter(., PARAM == "ADA interpreted per sample result") %>% + select(-AVAL, AVALC, AVALU) + +anl <- merge(anl, adpc, by = c("USUBJID", "NFRLT")) %>% + mutate(AVAL_LT = ifelse(AVAL <= max_conc, TRUE, FALSE)) +``` + +## Standard Table (μg/mL) + +```{r variant1, test = list(result_v1 = "result")} +# parameters in columns +adat03_stats <- c("n", "mean", "sd", "median", "min", "max", "cv", "geom_mean", "count_fraction") +adat03_lbls <- c( + n = "Total Number\nof Measurable\n Samples", + mean = "Mean", + sd = "SD", + median = "Median", + min = "Minimum", + max = "Maximum", + cv = "CV (%)", + geom_mean = "Geometric Mean", + count_fraction = paste0("Samples with\nConcentration\n≤ ", max_conc, "μg/mL") +) +adat03_fmts <- c( + n = "xx.", + mean = sprintf_format("%.3e"), + sd = sprintf_format("%.3e"), + median = sprintf_format("%.3e"), + min = sprintf_format("%.3e"), + max = sprintf_format("%.3e"), + cv = "xx.x", + geom_mean = sprintf_format("%.3e"), + count_fraction = format_count_fraction +) + +afun_list <- lapply( + 1:9, + function(i) make_afun(s_summary, .stats = adat03_stats[i], .formats = adat03_fmts[i], .labels = "Overall") +) + +# lyt creation +lyt <- basic_table() %>% + split_rows_by( + var = "ARM", + label_pos = "topleft", + split_label = "Treatment Group", + split_fun = drop_split_levels, + section_div = "" + ) %>% + add_rowcounts() %>% + split_rows_by( + var = "VISIT", + label_pos = "topleft", + split_label = "Visit", + split_fun = drop_split_levels, + child_labels = "hidden" + ) %>% + analyze_vars_in_cols( + vars = c(rep("AVAL", 8), "AVAL_LT"), + .stats = adat03_stats, + .labels = adat03_lbls, + .formats = adat03_fmts + ) %>% + analyze_colvars( + afun_list, + nested = FALSE, + extra_args = list(".labels" = "Overall") + ) + +result <- build_table(lyt, anl, alt_counts_df = adsl) + +main_title(result) <- paste( + "Summary of Serum Concentrations (μg/mL) at Timepoints Where ADA Samples Were Collected and Analyzed\n + Protocol:", unique(adab$PARCAT1)[1] +) +subtitles(result) <- paste("Analyte:", unique(adab$PARAMCD)[1]) +fnotes_at_path(result, rowpath = NULL, colpath = c("multivars", "AVAL")) <- "Refers to the total no. of measurable ADA samples that have a corresponding measurable drug concentration sample (i.e. results with +valid numeric values and LTRs). LTR results on post-dose samples are replaced by aaa µg/mL i.e. half of MQC value." +fnotes_at_path(result, rowpath = NULL, colpath = c("multivars", "AVAL_LT")) <- "In validation, the assay was able to detect yyy ng/mL of surrogate ADA in the presence of zzz µg/mL of [drug]. BLQ = Below Limit of +Quantitation, LTR = Lower than Reportable, MQC = Minimum Quantifiable Concentration, ADA = Anti-Drug Antibodies (is also referred to as ATA, +or Anti-Therapeutic Antibodies). RXXXXXXX is also known as [drug]" + +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ADA/adat04a.qmd b/book/tables/ADA/adat04a.qmd new file mode 100644 index 0000000000..3a3f56d998 --- /dev/null +++ b/book/tables/ADA/adat04a.qmd @@ -0,0 +1,240 @@ +--- +title: ADAT04A +subtitle: Baseline Prevalence and Incidence of Treatment Emergent NAbs +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(tern) +library(dplyr) +library(scda) +library(tibble) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adab <- synthetic_cdisc_dataset("latest", "adab") + +combodf <- tribble( + ~valname, ~label, ~levelcombo, ~exargs, + "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), + "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() +) + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) + +# Baseline Pts +adab_b <- df_explicit_na(adab) %>% + filter( + ABLFL == "Y", + ADABLPFL == "Y", + PARAM %in% c( + "ADA interpreted per sample result", + "NAB interpreted per sample result" + ) + ) %>% + select(-PARAMCD, -AVALC, -AVALU) %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate( + across( + any_of(c( + "ADA interpreted per sample result", + "NAB interpreted per sample result" + )), + as.logical + ) + ) %>% + mutate( + ADABLPFL = ADABLPFL == "Y", + PADABLPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, + PNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "TRUE" else FALSE, + NNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE + ) %>% + var_relabel( + ADABLPFL = "Baseline evaluable patients for ADA", + PADABLPFL = "Patients with a positive ADA sample at baseline", + PNABBLFL = "Patients with a positive NAb sample at baseline", + NNABBLFL = "Patient with no positive NAb samples at baseline" + ) + +# Post Baseline Treatment Enhanced NAb positive Pts +adab_pb <- df_explicit_na(adab) %>% + filter( + ABLFL != "Y", + ADPBLPFL == "Y", + PARAM %in% c( + "ADA interpreted per sample result", + "Treatment Emergent - Positive, Neutralizing Antibody", + "Treatment induced ADA, Neutralizing Antibody", + "Treatment enhanced ADA, Neutralizing Antibody", + "NAB interpreted per sample result", + "Treatment unaffected, Neutralizing Antibody" + ) + ) %>% + select(-PARAMCD, -AVALC, -AVALU, -ARRLT, -NRRLT) %>% + unique() %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate( + across( + any_of(c( + "ADA interpreted per sample result", "NAB interpreted per sample result", + "Treatment Emergent - Positive, Neutralizing Antibody", + "Treatment induced ADA, Neutralizing Antibody", + "Treatment enhanced ADA, Neutralizing Antibody", + "Treatment unaffected, Neutralizing Antibody" + )), + as.logical + ) + ) %>% + mutate( + ADPBLPFL = ADPBLPFL == "Y", + ADAPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, + TENABPFL = if (exists("Treatment Emergent - Positive, Neutralizing Antibody", where = .)) `Treatment Emergent - Positive, Neutralizing Antibody` == "TRUE" else FALSE, + TINPBFL = if (exists("Treatment induced ADA, Neutralizing Antibody", where = .)) `Treatment induced ADA, Neutralizing Antibody` == "TRUE" else FALSE, + TENPBFL = if (exists("Treatment enhanced ADA, Neutralizing Antibody", where = .)) `Treatment enhanced ADA, Neutralizing Antibody` == "TRUE" else FALSE, + NABNFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE, + TUNPBFL = if (exists("Treatment unaffected, Neutralizing Antibody", where = .)) `Treatment unaffected, Neutralizing Antibody` == "TRUE" else FALSE + ) %>% + var_relabel( + ADPBLPFL = "Post-baseline evaluable patients for ADA", + ADAPFL = "Patients positive for ADA", + TENABPFL = "Patients positive for Treatment Emergent NAb", + TINPBFL = "Treatment-induced NAb", + TENPBFL = "Treatment-enhanced NAb", + NABNFL = "Patients negative for NAb", + TUNPBFL = "Treatment unaffected" + ) +``` + +## Summary of Treatment Emergent NAbs + +```{r variant1, test = list(result_v1 = "result")} +# Layout for Baseline Prevalence of NAbs +lyt_bl <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("ADABLPFL", "PADABLPFL"), + table_names = "t1", + .stats = "count", + var_labels = "Baseline Prevalence of NAbs", + show_labels = "visible" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "PNABBLFL", + table_names = "t2", + .indent_mods = 1L + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NNABBLFL", + .stats = "count", + table_names = "t3", + .indent_mods = 1L, + show_labels = "hidden" + ) + +# Layout for incidence of NAbs +lyt_pb <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("ADPBLPFL", "ADAPFL"), + .stats = "count", + var_labels = "Incidence of Treatment Emergent NAbs", + show_labels = "visible", + table_names = "tb1" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "TENABPFL", + table_names = "tb2", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("TINPBFL", "TENPBFL"), + .stats = "count", + table_names = "tb3", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NABNFL", + table_names = "tb4", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "TUNPBFL", + .stats = "count", + table_names = "tb5", + .indent_mods = 1L, + show_labels = "hidden" + ) + +result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) +result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) + +# Combine tables +result <- rbind(result_1, result_2) + +# Change the column order +result <- cbind_rtables(result[, 1], result[, 3]) %>% + cbind_rtables(result[, 4]) %>% + cbind_rtables(result[, 2]) %>% + cbind_rtables(result[, 5]) + +main_title(result) <- paste( + "Baseline Prevalence and Incidence of Treatment Emergent NAbs" +) +subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) +main_footer(result) <- paste( + "NAb = Neutralizing Antibodies ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient for ADA = a patient with an ADA assay result from a baseline sample(s) + Baseline evaluable patient for NAb = a patient with a NAb assay result from a baseline sample(s) + Post-baseline evaluable patient for ADA = a patient with an ADA assay result from at least one post-baseline sample + Post-baseline evaluable patient for NAb = a patient with a NAb assay result from at least one post-baseline sample + Number of patients positive for ADA = the number of post-baseline evaluable patients for ADA determined to have Treatment Emergent ADA during the study period. +Number of patients positive for Treatment Emergent NAb = the number (and percentage) of post-baseline evaluable patients for ADA determined to have treatment-induced NAb or treatment-enhanced NAb during the study period. +Treatment-induced = a patient with negative or missing baseline result(s) and at least one positive post-baseline result. Treatment-enhanced = a patient with positive result at baseline who has one or more post-baseline titer results that are at least 0.60 t.u. greater than the baseline titer result. +Number of patients negative for Treatment Emergent NAb = number of post-baseline evaluable patients with negative or missing baseline NAb result(s) and all negative post-baseline NAb results, or a patient who is NAb treatment unaffected. +Treatment unaffected = A post-baseline evaluable patient with a positive result at baseline and (a) where all post-baseline titer results are less than 0.60 t.u. greater than the baseline titer result, OR (b) where all post-baseline results are negative or missing. For any positive sample with titer result less than the minimum reportable titer or any positive sample where a titer cannot be obtained, titer value is imputed as equal to the minimum reportable titer." +) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ADA/adat04b.qmd b/book/tables/ADA/adat04b.qmd new file mode 100644 index 0000000000..5994f04002 --- /dev/null +++ b/book/tables/ADA/adat04b.qmd @@ -0,0 +1,223 @@ +--- +title: ADAT04B +subtitle: Baseline Prevalence and Incidence of NAbs +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(tern) +library(dplyr) +library(scda) +library(tibble) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adab <- synthetic_cdisc_dataset("latest", "adab") + +combodf <- tribble( + ~valname, ~label, ~levelcombo, ~exargs, + "all_X", "All Drug X", c("A: Drug X", "C: Combination"), list(), + "all_pt", "All Patients", c("A: Drug X", "B: Placebo", "C: Combination"), list() +) + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) + +# Baseline Pts +adab_b <- df_explicit_na(adab) %>% + filter( + ABLFL == "Y", + ADABLPFL == "Y", + PARAM %in% c( + "ADA interpreted per sample result", + "NAB interpreted per sample result" + ) + ) %>% + select(-PARAMCD, -AVALC, -AVALU) %>% + tidyr::pivot_wider( + names_from = PARAM, + values_from = AVAL + ) %>% + mutate( + across( + any_of(c( + "ADA interpreted per sample result", + "NAB interpreted per sample result" + )), + as.logical + ) + ) %>% + mutate( + ADABLPFL = ADABLPFL == "Y", + PADABLPFL = if (exists("ADA interpreted per sample result", where = .)) `ADA interpreted per sample result` == "TRUE" else FALSE, + PNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "TRUE" else FALSE, + NNABBLFL = if (exists("NAB interpreted per sample result", where = .)) `NAB interpreted per sample result` == "FALSE" else FALSE + ) %>% + var_relabel( + ADABLPFL = "Baseline evaluable patients for ADA", + PADABLPFL = "Patients with a positive ADA sample at baseline", + PNABBLFL = "Patients with a positive NAb sample at baseline", + NNABBLFL = "Patients with no positive NAb sample at baseline" + ) + +# Post-Baseline Evaluable Pts +adab_pb_ada <- df_explicit_na(adab) %>% + filter(ADPBLPFL == "Y") %>% + select(STUDYID, USUBJID, ARM, ACTARM, ADPBLPFL) %>% + mutate(ADPBLPFL = ADPBLPFL == "Y") %>% + distinct() + +# Post-Baseline ADA Positive Pts +adab_pb_adap <- df_explicit_na(adab) %>% + filter( + ABLFL != "Y", + PARAM == "ADA interpreted per sample result", + AVALC == "POSITIVE" + ) %>% + mutate(ADAPFL = AVALC == "POSITIVE") %>% + select(STUDYID, USUBJID, ARM, ACTARM, ADAPFL) %>% + distinct() + +# Post-Baseline NAb Positive Pts +adab_pb_nabp <- df_explicit_na(adab) %>% + filter( + ABLFL != "Y", + PARAM == "NAb interpreted per sample result", + AVALC == "POSITIVE" + ) %>% + mutate(NABPFL = AVALC == "POSITIVE") %>% + select(STUDYID, USUBJID, ARM, ACTARM, NABPFL) %>% + distinct() + +# Post-Baseline NAb Negative Pts +adab_pb_nabn <- df_explicit_na(adab) %>% + filter( + ABLFL != "Y", + PARAM == "NAb interpreted per sample result", + AVALC == "NEGATIVE" + ) %>% + rename(NABNFL = AVALC) %>% + select(STUDYID, USUBJID, ARM, ACTARM, NABNFL) %>% + distinct() + +mergecol <- c("STUDYID", "USUBJID", "ARM", "ACTARM") + +adab_pb <- left_join(adab_pb_ada, adab_pb_adap, by = mergecol) %>% + left_join(adab_pb_nabp, by = mergecol) %>% + mutate( + NABNFL = ifelse(is.na(NABPFL), "TRUE", "FALSE"), + NABNFL = NABNFL == "TRUE" + ) %>% + var_relabel( + ADPBLPFL = "Post-baseline evaluable patients for ADA", + ADAPFL = "Patients positive for ADA", + NABPFL = "Patients positive for NAb", + NABNFL = "Patients negative for NAb" + ) +``` + +## Standard Table + +```{r variant1, test = list(result_v1 = "result")} +# Layout for Baseline Prevalence of NAbs +lyt_bl <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("ADABLPFL", "PADABLPFL"), + .stats = "count", + var_labels = "Baseline Prevalence of NAbs", + show_labels = "visible", + table_names = "t1" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "PNABBLFL", + table_names = "t2", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NNABBLFL", + .stats = "count", + table_names = "t3", + .indent_mods = 1L, + show_labels = "hidden" + ) + +# Layout for incidence of NAbs +lyt_pb <- basic_table(show_colcounts = TRUE) %>% + split_cols_by( + "ACTARM", + split_fun = add_combo_levels(combodf) + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = c("ADPBLPFL", "ADAPFL"), + .stats = "count", + var_labels = "Incidence of NAbs", + show_labels = "visible", + table_names = "tb1" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NABPFL", + table_names = "tb2", + .indent_mods = 1L, + show_labels = "hidden" + ) %>% + count_patients_with_flags( + "USUBJID", + flag_variables = "NABNFL", + .stats = "count", + table_names = "tb3", + .indent_mods = 1L, + show_labels = "hidden" + ) + +result_1 <- build_table(lyt_bl, df = adab_b, alt_counts_df = adsl) +result_2 <- build_table(lyt_pb, df = adab_pb, alt_counts_df = adsl) + +# Combine tables. +result <- rbind(result_1, result_2) + +# Change the column order. +result <- cbind_rtables(result[, 1], result[, 3]) %>% + cbind_rtables(result[, 4]) %>% + cbind_rtables(result[, 2]) %>% + cbind_rtables(result[, 5]) + +main_title(result) <- paste( + "Baseline Prevalence and Incidence of Neutralizing Antibodies (NAbs)" +) +subtitles(result) <- paste("Protocol:", unique(adab$PARCAT1)[1]) +main_footer(result) <- paste( + "NAb = Neutralizing Antibodies ADA = Anti-Drug Antibodies (is also referred to as ATA, or Anti-Therapeutic Antibodies) Baseline evaluable patient for ADA = a patient with an ADA assay result from a baseline sample(s) Baseline evaluable patient for NAb = a patient with a NAb assay result from a baseline sample(s) Post-baseline evaluable patient for ADA = a patient with an ADA assay result from at least one post-baseline sample Post-baseline evaluable patient for NAb = a patient with a NAb assay result from at least one post-baseline sample Number of patients positive for ADA = the number of post-baseline evaluable patients for ADA determined to have Treatment Emergent ADA during the study period. +Number of patients positive for NAb = the number (and percentage) of post-baseline evaluable patients for ADA determined to have at least one positive post-baseline NAb result during the study period. Number of patients negative for NAb = number of post-baseline evaluable patients with all negative post-baseline NAb results." +) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ECG/egt01.qmd b/book/tables/ECG/egt01.qmd new file mode 100644 index 0000000000..017188e635 --- /dev/null +++ b/book/tables/ECG/egt01.qmd @@ -0,0 +1,142 @@ +--- +title: EGT01 +subtitle: ECG Results and Change from Baseline by Visit +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(dplyr) +library(tern) +library(scda) + +# Data should be filtered for the studied Parameter (`PARAM`) and the +# Analysis Visit (`AVISIT`). According to the GDSR template, the values for +# the `AVISIT` reported in the EGT01 standard may be: +# 'POST-BASELINE MAXIMUM', 'POST-BASELINE MINIMUM', 'POST-BASELINE LAST'. + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg) + +adeg_f <- adeg %>% + filter(ANL01FL == "Y") %>% + filter(PARAM %in% c("Heart Rate", "QT Duration", "RR Duration")) +``` + +## Standard Table + +```{r variant1, test = list(result_v1 = "result")} +# Define the split function +split_fun <- drop_split_levels + +afun <- function(x, .var, .spl_context, ...) { + n_fun <- sum(!is.na(x), na.rm = TRUE) + if (n_fun == 0) { + mean_sd_fun <- c(NA, NA) + median_fun <- NA + min_max_fun <- c(NA, NA) + } else { + mean_sd_fun <- c(mean(x, na.rm = TRUE), sd(x, na.rm = TRUE)) + median_fun <- median(x, na.rm = TRUE) + min_max_fun <- c(min(x), max(x)) + } + is_chg <- .var == "CHG" + is_baseline <- .spl_context$value[which(.spl_context$split == "AVISIT")] == "BASELINE" + if (is_baseline && is_chg) n_fun <- mean_sd_fun <- median_fun <- min_max_fun <- NULL + + in_rows( + "n" = n_fun, + "Mean (SD)" = mean_sd_fun, + "Median" = median_fun, + "Min - Max" = min_max_fun, + .formats = list("n" = "xx", "Mean (SD)" = "xx.xx (xx.xx)", "Median" = "xx.xx", "Min - Max" = "xx.xx - xx.xx"), + .format_na_strs = list("n" = "NE", "Mean (SD)" = "NE (NE)", "Median" = "NE", "Min - Max" = "NE - NE") + ) +} + +lyt <- basic_table(show_colcounts = TRUE) %>% + split_cols_by("ACTARM") %>% + split_rows_by("PARAM", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$PARAM)) %>% + split_rows_by("AVISIT", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$AVISIT)) %>% + split_cols_by_multivar( + vars = c("AVAL", "CHG"), + varlabels = c("Value at Visit", "Change from\nBaseline") + ) %>% + analyze_colvars(afun = afun) + +result <- build_table(lyt, adeg_f, alt_counts_df = adsl) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| screenshot.opts = list(delay = 16) + +library(teal.modules.clinical) +library(scda) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg) + +app <- init( + data = cdisc_data( + cdisc_dataset("ADSL", + adsl, + code = 'ADSL <- df_explicit_na(synthetic_cdisc_dataset("latest", "adsl"))' + ), + cdisc_dataset("ADEG", + adeg, + code = 'ADEG <- df_explicit_na(synthetic_cdisc_dataset("latest", "adeg"))' + ), + check = TRUE + ), + modules = modules( + tm_t_summary_by( + label = "ECG Results and Change from Baseline by Visit", + dataname = "ADEG", + arm_var = choices_selected( + choices = variable_choices(adsl, c("ARM", "ARMCD")), + selected = "ARM" + ), + by_vars = choices_selected( + choices = variable_choices(adeg, c("PARAM", "AVISIT")), + selected = c("AVISIT") + ), + summarize_vars = choices_selected( + choices = variable_choices(adeg, c("AVAL", "CHG")), + selected = c("AVAL") + ), + useNA = "ifany", + paramcd = choices_selected( + choices = value_choices(adeg, "PARAMCD", "PARAM"), + selected = "HR" + ), + parallel_vars = TRUE + ) + ), + filter = list(ADEG = list(AVAL = list())) +) + +shinyApp(app$ui, app$server) +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ECG/egt02.qmd b/book/tables/ECG/egt02.qmd new file mode 100644 index 0000000000..addbda506f --- /dev/null +++ b/book/tables/ECG/egt02.qmd @@ -0,0 +1,126 @@ +--- +title: EGT02 +subtitle: ECG Abnormalities (EGT02_1 & EGT02_2) +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(dplyr) +library(scda) +library(tern) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg) + +# Note: We keep only post-baseline for analysis. +adeg_f <- adeg %>% + filter(ONTRTFL == "Y") %>% + filter(PARAM %in% c("Heart Rate", "QT Duration", "RR Duration")) %>% + filter(ANRIND != "") %>% + var_relabel( + PARAM = "Assessment", + ANRIND = "Abnormality" + ) +``` + +## ECG Abnormalities Regardless
of Abnormality at Baseline + +```{r variant1, test = list(result_v1 = "result")} +split_fun <- drop_split_levels + +lyt <- basic_table(show_colcounts = TRUE) %>% + split_cols_by(var = "ACTARM") %>% + split_rows_by( + "PARAM", + split_fun = split_fun, + label_pos = "topleft", + split_label = obj_label(adeg_f$PARAM) + ) %>% + count_abnormal("ANRIND", abnormal = list(Low = "LOW", High = "HIGH"), exclude_base_abn = FALSE) %>% + append_varlabels(adeg_f, "ANRIND", indent = 1L) + +result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) +result +``` + +## ECG Abnormalities Among Subjects
Without Abnormality at Baseline + +```{r variant2, test = list(result_v2 = "result")} +split_fun <- drop_split_levels + +lyt <- basic_table(show_colcounts = TRUE) %>% + split_cols_by(var = "ACTARM") %>% + split_rows_by( + "PARAM", + split_fun = split_fun, + label_pos = "topleft", + split_label = obj_label(adeg_f$PARAM) + ) %>% + count_abnormal("ANRIND", abnormal = list(Low = "LOW", High = "HIGH"), exclude_base_abn = TRUE) %>% + append_varlabels(adeg_f, "ANRIND", indent = 1L) + +result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| screenshot.opts = list(delay = 18) + +library(scda) +library(teal.modules.clinical) +library(dplyr) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +app <- init( + data = cdisc_data( + cdisc_dataset("ADSL", adsl, code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl")'), + cdisc_dataset("ADEG", adeg, code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg")'), + check = TRUE + ), + modules = modules( + tm_t_abnormality( + label = "Abnormality Table", + dataname = "ADEG", + arm_var = choices_selected( + choices = variable_choices(adsl, subset = c("ARM", "ARMCD")), + selected = "ARM" + ), + by_vars = choices_selected( + choices = variable_choices(adeg, subset = c("EGCAT", "PARAM", "AVISIT")), + selected = c("PARAM"), + keep_order = TRUE + ), + grade = choices_selected( + choices = variable_choices(adeg, subset = "ANRIND"), + selected = "ANRIND", + fixed = TRUE + ), + abnormal = list(Low = "LOW", High = "HIGH"), + exclude_base_abn = FALSE + ) + ) +) + +shinyApp(app$ui, app$server) +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tables/ECG/egt03.qmd b/book/tables/ECG/egt03.qmd new file mode 100644 index 0000000000..6d335eb12e --- /dev/null +++ b/book/tables/ECG/egt03.qmd @@ -0,0 +1,204 @@ +--- +title: EGT03 +subtitle: Shift Table of ECG Interval Data -- Baseline Versus Minimum/Maximum Post-Baseline +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(scda) +library(tern) +library(dplyr) + +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adeg <- df_explicit_na(adeg) + +adeg_labels <- var_labels(adeg) + +adeg_f_pbmin <- subset( + adeg, + PARAMCD == "HR" & # Heart Rate + SAFFL == "Y" & # "Safety Population Flag" + ONTRTFL == "Y" & # "On Treatment Record Flag" + AVISIT == "POST-BASELINE MINIMUM" # "Analysis Visit" +) + +adeg_f_pbmax <- subset( + adeg, + PARAMCD == "HR" & # Heart Rate + SAFFL == "Y" & # "Safety Population Flag" + ONTRTFL == "Y" & # "On Treatment Record Flag" + AVISIT == "POST-BASELINE MAXIMUM" # "Analysis Visit" +) + +var_labels(adeg_f_pbmin) <- adeg_labels +var_labels(adeg_f_pbmax) <- adeg_labels +``` + +## Table of Baseline Versus
Minimum Post-Baseline + +For the EGT03 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. +For illustration purposes, missing data are added to the example dataset. + +```{r variant1, test = list(result_v1 = "result")} +set.seed(123, kind = "Mersenne-Twister") + +adeg_f_pbmin$BNRIND <- factor( + adeg_f_pbmin$BNRIND, + levels = c("LOW", "NORMAL", "HIGH", "Missing"), + labels = c("LOW", "NORMAL", "HIGH", "Missing") +) +adeg_f_pbmin$ANRIND <- factor( + adeg_f_pbmin$ANRIND, + levels = c("LOW", "NORMAL", "HIGH", "Missing"), + labels = c("LOW", "NORMAL", "HIGH", "Missing") +) + +adeg_f_pbmin$BNRIND[sample(1:nrow(adeg_f_pbmin), size = 5)] <- "Missing" +adeg_f_pbmin$ANRIND[sample(1:nrow(adeg_f_pbmin), size = 5)] <- "Missing" + +attr(adeg_f_pbmin$ANRIND, "label") <- "Analysis Reference Range Indicator" +attr(adeg_f_pbmin$BNRIND, "label") <- "Baseline Reference Range Indicator" + +# Temporary solution for overarching column +adeg_f_pbmin <- adeg_f_pbmin %>% mutate(min_label = "Minimum Post-Baseline Assessment") + +# Define the split function +split_fun <- drop_split_levels + +lyt <- basic_table() %>% + split_cols_by("min_label") %>% + split_cols_by("ANRIND") %>% + split_rows_by("ARMCD", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f_pbmin$ARMCD)) %>% + add_rowcounts() %>% + analyze_vars("BNRIND", denom = "N_row", .stats = "count_fraction") %>% + append_varlabels(adeg_f_pbmin, c("BNRIND"), indent = 1L) + +result <- build_table( + lyt = lyt, + df = adeg_f_pbmin +) + +result +``` + +## Table of Baseline Versus
Maximum Post-Baseline + +For the EGT03 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. +For illustration purpose, missing data are added to the example dataset. + +```{r variant2, test = list(result_v2 = "result")} +set.seed(123, kind = "Mersenne-Twister") + +adeg_f_pbmax$BNRIND <- factor( + adeg_f_pbmax$BNRIND, + levels = c("LOW", "NORMAL", "HIGH", "Missing"), + labels = c("LOW", "NORMAL", "HIGH", "Missing") +) +adeg_f_pbmax$ANRIND <- factor( + adeg_f_pbmax$ANRIND, + levels = c("LOW", "NORMAL", "HIGH", "Missing"), + labels = c("LOW", "NORMAL", "HIGH", "Missing") +) + +adeg_f_pbmax$BNRIND[sample(1:nrow(adeg_f_pbmax), size = 5)] <- "Missing" +adeg_f_pbmax$ANRIND[sample(1:nrow(adeg_f_pbmax), size = 5)] <- "Missing" + +attr(adeg_f_pbmax$ANRIND, "label") <- "Analysis Reference Range Indicator" +attr(adeg_f_pbmax$BNRIND, "label") <- "Baseline Reference Range Indicator" + +# Temporary solution for overarching column +adeg_f_pbmax <- adeg_f_pbmax %>% mutate(max_label = "Maximum Post-Baseline Assessment") + +# Define the split function +split_fun <- drop_split_levels + +lyt <- basic_table() %>% + split_cols_by("max_label") %>% + split_cols_by("ANRIND") %>% + split_rows_by("ARMCD", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f_pbmax$ARMCD)) %>% + add_rowcounts() %>% + analyze_vars("BNRIND", denom = "N_row", .stats = "count_fraction") %>% + append_varlabels(adeg_f_pbmax, c("BNRIND"), indent = 1L) + +result <- build_table( + lyt = lyt, + df = adeg_f_pbmax +) + +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| screenshot.opts = list(delay = 16) + +library(dplyr) +library(tern) +library(scda) +library(teal.modules.clinical) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +app <- init( + data = cdisc_data( + cdisc_dataset("ADSL", adsl, code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl")'), + cdisc_dataset("ADEG", adeg, code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg")'), + check = TRUE + ), + modules = modules( + tm_t_shift_by_arm( + label = "Shift by Arm Table", + dataname = "ADEG", + arm_var = choices_selected( + variable_choices(adsl, subset = c("ARM", "ARMCD")), + selected = "ARM" + ), + paramcd = choices_selected( + value_choices(adeg, "PARAMCD"), + selected = "HR" + ), + visit_var = choices_selected( + value_choices(adeg, "AVISIT"), + selected = "POST-BASELINE MINIMUM" + ), + aval_var = choices_selected( + variable_choices(adeg, subset = "ANRIND"), + selected = "ANRIND", fixed = TRUE + ), + base_var = choices_selected( + variable_choices(adeg, subset = "BNRIND"), + selected = "BNRIND", fixed = TRUE + ), + treatment_flag_var = choices_selected( + variable_choices(adeg, subset = "ONTRTFL"), + selected = "ONTRTFL", fixed = TRUE + ), + treatment_flag = choices_selected( + value_choices(adeg, "ONTRTFL"), + selected = "Y", fixed = TRUE + ) + ) + ), + filter = list(ADSL = list(SAFFL = "Y")) +) + +shinyApp(app$ui, app$server) +``` + +{{< include ../../repro.qmd >}} + +::: diff --git a/book/tables/ECG/egt04.qmd b/book/tables/ECG/egt04.qmd new file mode 100644 index 0000000000..fb960b9b2a --- /dev/null +++ b/book/tables/ECG/egt04.qmd @@ -0,0 +1,100 @@ +--- +title: EGT04 +subtitle: Shift Table of Qualitative ECG Assessments +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +For the EGT04 template, data imputation should be avoided, and missing data explicit and accounted for, so the contingency table sum adds up to the group N. +For illustration purposes, missing data are added to the example dataset. + +```{r setup, message=FALSE} +#| code-fold: show + +library(scda) +library(tern) +library(dplyr) +set.seed(123) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg, omit_columns = c("AVALC", "BASEC")) + +adeg_labels <- var_labels(adeg) + +adeg_f <- subset( + adeg, + PARAMCD == "ECGINTP" & # Analysis in terms of "NORMAL"/"ABNORMAL" (AVALC) + SAFFL == "Y" & # "Safety Population Flag" + ONTRTFL == "Y" & # "On Treatment Record Flag" + WORS02FL == "Y" # "Worst Post-Baseline Observation" +) + +adeg_f$AVALC[sample(1:nrow(adeg_f), size = 5)] <- "Missing" +adeg_f$BASEC[sample(1:nrow(adeg_f), size = 5)] <- "Missing" +adeg_f$AVALC <- factor( + adeg_f$AVALC, + levels = c("NORMAL", "ABNORMAL", "Missing"), + labels = c("Normal", "Abnormal", "Missing") +) +adeg_f$BASEC <- factor( + adeg_f$BASEC, + levels = c("NORMAL", "ABNORMAL", "Missing"), + labels = c("Normal", "Abnormal", "Missing") +) + +var_labels(adeg_f) <- adeg_labels +adeg_f <- adeg_f %>% + var_relabel(BASEC = "Baseline") + +# Temprary solution for over arching column +adeg_f <- adeg_f %>% mutate(postbaseline_label = "Post-Baseline") +``` + +## Standard Table + +The EGT04 template consists of a stacked list of contingency tables, one per group. +For each group, the n's across all cells must add up to the group N in the analysis, and percentages are calculated using N as the denominator. + +```{r variant1, test = list(result_v1 = "result")} +# Define the split function +split_fun <- drop_split_levels + +lyt <- basic_table() %>% + split_cols_by("postbaseline_label") %>% + split_cols_by("AVALC") %>% + split_rows_by("ARM", split_fun = split_fun, label_pos = "topleft", split_label = obj_label(adeg_f$ARM)) %>% + add_rowcounts() %>% + analyze_vars( + "BASEC", + denom = "N_row", + .stats = "count_fraction", + na.rm = FALSE + ) %>% + append_varlabels(adeg_f, c("BASEC"), indent = 1L) + +result <- build_table(lyt, adeg_f) +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| code-fold: show + +# In progress +``` + +{{< include ../../repro.qmd >}} + +::: diff --git a/book/tables/ECG/egt05_qtcat.qmd b/book/tables/ECG/egt05_qtcat.qmd new file mode 100644 index 0000000000..db249bacc5 --- /dev/null +++ b/book/tables/ECG/egt05_qtcat.qmd @@ -0,0 +1,255 @@ +--- +title: EGT05_QTCAT +subtitle: ECG Actual Values and Changes from Baseline by Visit +--- + +------------------------------------------------------------------------ + +{{< include ../../test-utils/envir_hook.qmd >}} + +::: panel-tabset +## Data Setup + +```{r setup, message=FALSE} +#| code-fold: show + +library(tern) +library(scda) +library(dplyr) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") + +# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg) + +adeg_labels <- var_labels(adeg) +adeg_f <- adeg %>% + filter( + PARAMCD == "QT", + ANL01FL == "Y" + ) %>% + mutate( + AVALCAT1 = case_when( + AVAL <= 450 ~ "<=450 msec", + AVAL <= 480 ~ ">450 to <=480 msec", + AVAL <= 500 ~ ">480 to <= 500 msec", + AVAL > 500 ~ ">500 msec", + is.na(AVAL) ~ "" + ), + CHGCAT1 = case_when( + CHG <= 30 ~ "<=30 msec", + CHG <= 60 ~ ">30 to <=60 msec", + CHG > 60 ~ ">60 msec", + is.na(CHG) ~ "" + ) + ) %>% + mutate( + AVALCAT1 = factor( + AVALCAT1, + levels = c( + "<=450 msec", + ">450 to <=480 msec", + ">480 to <= 500 msec", + ">500 msec", + "" + ) + ), + CHGCAT1 = factor( + CHGCAT1, + levels = c( + "<=30 msec", + ">30 to <=60 msec", + ">60 msec", + "" + ) + ) + ) %>% + var_relabel( + AVALCAT1 = "Value at Visit", + CHGCAT1 = "Change from Baseline" + ) +``` + +## Standard Table + +```{r variant1, test = list(result_v1 = "result")} +split_fun <- drop_split_levels + +lyt <- basic_table(show_colcounts = TRUE) %>% + split_cols_by("ARM") %>% + split_rows_by( + "PARAM", + split_label = obj_label(adeg_f$PARAM), + split_fun = split_fun, + label_pos = "topleft" + ) %>% + split_rows_by( + "AVISIT", + split_label = obj_label(adeg_f$AVISIT), + split_fun = split_fun, + label_pos = "topleft" + ) %>% + analyze_vars( + vars = c("AVALCAT1", "CHGCAT1"), + var_labels = c("Value at Visit", "Change from Baseline") + ) %>% + append_topleft(" Category") + +result <- build_table(lyt = lyt, df = adeg_f, alt_counts_df = adsl) %>% + prune_table() + +result +``` + +{{< include ../../test-utils/save_results.qmd >}} + +## `teal` App + +```{r teal, message=FALSE, opts.label='skip_if_testing'} +#| screenshot.opts = list(delay = 24) + +library(teal.modules.clinical) +library(scda) +library(dplyr) + +adsl <- synthetic_cdisc_dataset("latest", "adsl") +adeg <- synthetic_cdisc_dataset("latest", "adeg") +adsl <- df_explicit_na(adsl) +adeg <- df_explicit_na(adeg) +adeg_labels <- var_labels(adeg) + +adeg_f <- adeg %>% + filter( + ANL01FL == "Y" # no need to filter for PARAMCD here + ) %>% + mutate( + AVALCAT1 = case_when( + AVAL <= 450 ~ "<=450 msec", + AVAL <= 480 ~ ">450 to <=480 msec", + AVAL <= 500 ~ ">480 to <= 500 msec", + AVAL > 500 ~ ">500 msec", + is.na(AVAL) ~ "" + ), + CHGCAT1 = case_when( + CHG <= 30 ~ "<=30 msec", + CHG <= 60 ~ ">30 to <=60 msec", + CHG > 60 ~ ">60 msec", + is.na(CHG) ~ "" + ) + ) %>% + mutate( + AVALCAT1 = factor( + AVALCAT1, + levels = c( + "<=450 msec", + ">450 to <=480 msec", + ">480 to <= 500 msec", + ">500 msec", + "" + ) + ), + CHGCAT1 = factor( + CHGCAT1, + levels = c( + "<=30 msec", + ">30 to <=60 msec", + ">60 msec", + "" + ) + ) + ) +var_labels(adeg_f) <- c( + adeg_labels, + "AVALCAT1" = "Value at Visit", + "CHGCAT1" = "Change from Baseline" +) +app <- init( + data = cdisc_data( + cdisc_dataset("ADSL", + adsl, + code = 'ADSL <- synthetic_cdisc_dataset("latest", "adsl") + ADSL <- df_explicit_na(ADSL)' + ), + cdisc_dataset("ADEG", + adeg_f, + code = 'ADEG <- synthetic_cdisc_dataset("latest", "adeg") + ADEG <- df_explicit_na(ADEG) + ADEG_labels <- var_labels(ADEG) + + ADEG <- ADEG %>% + filter( + ANL01FL == "Y" + ) %>% + mutate( + AVALCAT1 = case_when( + AVAL <= 450 ~ "<=450 msec", + AVAL <= 480 ~ ">450 to <=480 msec", + AVAL <= 500 ~ ">480 to <= 500 msec", + AVAL > 500 ~ ">500 msec", + is.na(AVAL) ~ ""), + CHGCAT1 = case_when( + CHG <= 30 ~ "<=30 msec", + CHG <= 60 ~ ">30 to <=60 msec", + CHG > 60 ~ ">60 msec", + is.na(CHG) ~ "") + ) %>% mutate( + AVALCAT1 = factor( + AVALCAT1, + levels = c( + "<=450 msec", + ">450 to <=480 msec", + ">480 to <= 500 msec", + ">500 msec", + "" + ) + ), + CHGCAT1 = factor( + CHGCAT1, + levels = c( + "<=30 msec", + ">30 to <=60 msec", + ">60 msec", + "" + ) + ) + ) + var_labels(ADEG) <- c( + ADEG_labels, + "AVALCAT1" = "Value at Visit", + "CHGCAT1" = "Change from Baseline" + )' + ), + check = TRUE + ), + modules = modules( + tm_t_summary_by( + label = "ECG Actual Values and Changes from Baseline by Visit", + dataname = "ADEG", + arm_var = choices_selected( + choices = variable_choices(adsl, c("ARM", "ARMCD")), + selected = "ARM" + ), + by_vars = choices_selected( + choices = variable_choices(adeg_f, c("PARAM", "AVISIT")), + selected = c("AVISIT") + ), + summarize_vars = choices_selected( + choices = variable_choices(adeg_f, c("AVALCAT1", "CHGCAT1")), + selected = c("AVALCAT1", "CHGCAT1") + ), + useNA = "ifany", + paramcd = choices_selected( + choices = value_choices(adeg_f, "PARAMCD", "PARAM"), + selected = "QT" + ) + ) + ) +) + +shinyApp(app$ui, app$server) +``` + +{{< include ../../repro.qmd >}} +::: diff --git a/book/tlg-index.qmd b/book/tlg-index.qmd index 19a704936b..8d0efa650c 100644 --- a/book/tlg-index.qmd +++ b/book/tlg-index.qmd @@ -10,47 +10,47 @@ toc-depth: 4 #### ADA -        [ADAT01 -- Baseline Prevalence and Incidence of Treatment Emergent ADA](./tables/ada/adat01.qmd) +        [ADAT01 -- Baseline Prevalence and Incidence of Treatment Emergent ADA](./tables/ADA/adat01.qmd) -        [ADAT02 -- Summary of Patients with Treatment-Induced ADA](./tables/ada/adat02.qmd) +        [ADAT02 -- Summary of Patients with Treatment-Induced ADA](./tables/ADA/adat02.qmd) -        [ADAT03 -- Summary of Serum Concentrations at Timepoints Where ADA Samples Were Collected and Analyzed](./tables/ada/adat03.qmd) +        [ADAT03 -- Summary of Serum Concentrations at Timepoints Where ADA Samples Were Collected and Analyzed](./tables/ADA/adat03.qmd) -        [ADAT04A -- Baseline Prevalence and Incidence of Treatment Emergent NAbs](./tables/ada/adat04a.qmd) +        [ADAT04A -- Baseline Prevalence and Incidence of Treatment Emergent NAbs](./tables/ADA/adat04a.qmd) -        [ADAT04B -- Baseline Prevalence and Incidence of NAbs](./tables/ada/adat04b.qmd) +        [ADAT04B -- Baseline Prevalence and Incidence of NAbs](./tables/ADA/adat04b.qmd) #### Adverse Events -        [AET01_AESI -- Safety Summary (Adverse Events of Special Interest)](./tables/adverse-events/aet01_aesi.qmd) -         [AET01 -- Safety Summary](./tables/adverse-events/aet01.qmd) -        [AET02_SMQ -- Adverse Events by Standardized MedDRA Query](./tables/adverse-events/aet02_smq.qmd) +        [AET01_AESI -- Safety Summary (Adverse Events of Special Interest)](./tables/adverse-events/aet01_aesi.qmd)         [AET02 -- Adverse Events](./tables/adverse-events/aet02.qmd) -        [AET03 -- Adverse Events by Greatest Intensity](./tables/adverse-events/aet03.qmd) +        [AET02_SMQ -- Adverse Events by Standardized MedDRA Query](./tables/adverse-events/aet02_smq.qmd) -        [AET04_PI -- Adverse Events Reported in $\geq$ 10% of Patients by Highest NCI CTCAE Grade](./tables/adverse-events/aet04_pi.qmd) +        [AET03 -- Adverse Events by Greatest Intensity](./tables/adverse-events/aet03.qmd)         [AET04 -- Adverse Events by Highest NCI CTCAE Grade](./tables/adverse-events/aet04.qmd) -        [AET05_ALL -- Adverse Event Rate Adjusted for Patient-Years at Risk -- All Occurrences](./tables/adverse-events/aet05_all.qmd) +        [AET04_PI -- Adverse Events Reported in $\geq$ 10% of Patients by Highest NCI CTCAE Grade](./tables/adverse-events/aet04_pi.qmd)         [AET05 -- Adverse Event Rate Adjusted for Patient-Years at Risk -- First Occurrence](./tables/adverse-events/aet05.qmd) -        [AET06_SMQ -- Adverse Events by Baseline Characteristic, by SMQ and Preferred Term](./tables/adverse-events/aet06_smq.qmd) +        [AET05_ALL -- Adverse Event Rate Adjusted for Patient-Years at Risk -- All Occurrences](./tables/adverse-events/aet05_all.qmd)         [AET06 -- Adverse Events by Baseline Characteristic](./tables/adverse-events/aet06.qmd) -        [AET07 -- Adverse Events Resulting in Death](./tables/adverse-events/aet07.qmd) +        [AET06_SMQ -- Adverse Events by Baseline Characteristic, by SMQ and Preferred Term](./tables/adverse-events/aet06_smq.qmd) -        [AET09_SMQ -- Adverse Events Related to Study Drug by Standardized MedDRA Query](./tables/adverse-events/aet09_smq.qmd) +        [AET07 -- Adverse Events Resulting in Death](./tables/adverse-events/aet07.qmd)         [AET09 -- Adverse Events Related to Study Drug](./tables/adverse-events/aet09.qmd) +        [AET09_SMQ -- Adverse Events Related to Study Drug by Standardized MedDRA Query](./tables/adverse-events/aet09_smq.qmd) +         [AET10 -- Most Common ($\geq$ 5%) Adverse Events](./tables/adverse-events/aet10.qmd) @@ -95,15 +95,15 @@ toc-depth: 4 #### ECG -        [EGT01 -- ECG Results and Change from Baseline by Visit](./tables/ecg/egt01.qmd) +        [EGT01 -- ECG Results and Change from Baseline by Visit](./tables/ECG/egt01.qmd) -        [EGT02 -- ECG Abnormalities (EGT02_1 & EGT02_2)](./tables/ecg/egt02.qmd) +        [EGT02 -- ECG Abnormalities (EGT02_1 & EGT02_2)](./tables/ECG/egt02.qmd) -        [EGT03 -- Shift Table of ECG Interval Data -- Baseline Versus Minimum/Maximum Post-Baseline](./tables/ecg/egt03.qmd) +        [EGT03 -- Shift Table of ECG Interval Data -- Baseline Versus Minimum/Maximum Post-Baseline](./tables/ECG/egt03.qmd) -        [EGT04 -- Shift Table of Qualitative ECG Assessments](./tables/ecg/egt04.qmd) +        [EGT04 -- Shift Table of Qualitative ECG Assessments](./tables/ECG/egt04.qmd) -        [EGT05_QTCAT -- ECG Actual Values and Changes from Baseline by Visit](./tables/ecg/egt05_qtcat.qmd) +        [EGT05_QTCAT -- ECG Actual Values and Changes from Baseline by Visit](./tables/ECG/egt05_qtcat.qmd) #### Efficacy @@ -164,18 +164,18 @@ toc-depth: 4         [LBT09 -- Liver Laboratory Tests -- Patients with Elevated Post-Baseline AST or ALT Levels](./tables/lab-results/lbt09.qmd) -        [LBT10_BL -- Liver Laboratory Tests -- Patients with Elevated Post-Baseline AST or ALT Levels at Two Consecutive Visits (with Respect to Baseline)](./tables/lab-results/lbt10_bl.qmd) -         [LBT10 -- Liver Laboratory Tests -- Patients with Elevated Post-Baseline AST or ALT Levels at Two Consecutive Visits (with Respect to ULN)](./tables/lab-results/lbt10.qmd) -        [LBT11_BL -- Time to First Increase in Liver Laboratory Test Result Meeting Hy's Law Laboratory Critieria (with Respect to Baseline)](./tables/lab-results/lbt11_bl.qmd) +        [LBT10_BL -- Liver Laboratory Tests -- Patients with Elevated Post-Baseline AST or ALT Levels at Two Consecutive Visits (with Respect to Baseline)](./tables/lab-results/lbt10_bl.qmd)         [LBT11 -- Time to First Increase in Liver Laboratory Test Result Meeting Hy's Law Laboratory Critieria (with Respect to ULN)](./tables/lab-results/lbt11.qmd) -        [LBT12_BL -- Liver Laboratory Tests by Time on Treatment -- Patients with Elevated Post-Baseline AST or ALT Levels (with Respect to Baseline)](./tables/lab-results/lbt12_bl.qmd) +        [LBT11_BL -- Time to First Increase in Liver Laboratory Test Result Meeting Hy's Law Laboratory Critieria (with Respect to Baseline)](./tables/lab-results/lbt11_bl.qmd)         [LBT12 -- Liver Laboratory Tests by Time on Treatment -- Patients with Elevated Post-Baseline AST or ALT Levels (with Respect to ULN)](./tables/lab-results/lbt12.qmd) +        [LBT12_BL -- Liver Laboratory Tests by Time on Treatment -- Patients with Elevated Post-Baseline AST or ALT Levels (with Respect to Baseline)](./tables/lab-results/lbt12_bl.qmd) +         [LBT13 -- NCI CTCAE Grade Laboratory Abnormalities by Visit and Baseline Grade](./tables/lab-results/lbt13.qmd)         [LBT14 -- Laboratory Test Results Shift Table -- Highest NCI CTCAE Grade Post-Baseline by Baseline NCI CTCAE Grade](./tables/lab-results/lbt14.qmd) @@ -240,19 +240,19 @@ toc-depth: 4 #### ADA -        [ADAL02 -- Listing of Anti-Drug Antibody Data for Treatment Emergent ADA Positive Patients](./listings/ada/adal02.qmd) +        [ADAL02 -- Listing of Anti-Drug Antibody Data for Treatment Emergent ADA Positive Patients](./listings/ADA/adal02.qmd) #### Adverse Events -        [AEL01_NOLLT -- Listing of Preferred Terms and Investigator-Specified Adverse Event Terms](./listings/adverse-events/ael01_nollt.qmd) -         [AEL01 -- Listing of Preferred Terms, Lowest Level Terms, and Investigator-Specified Adverse Event Terms](./listings/adverse-events/ael01.qmd) -        [AEL02_ED -- Listing of Adverse Events (for Early Development Studies)](./listings/adverse-events/ael02_ed.qmd) +        [AEL01_NOLLT -- Listing of Preferred Terms and Investigator-Specified Adverse Event Terms](./listings/adverse-events/ael01_nollt.qmd)         [AEL02 -- Listing of Adverse Events](./listings/adverse-events/ael02.qmd) +        [AEL02_ED -- Listing of Adverse Events (for Early Development Studies)](./listings/adverse-events/ael02_ed.qmd) +         [AEL03 -- Listing of Serious Adverse Events](./listings/adverse-events/ael03.qmd)         [AEL04 -- Listing of Patient Deaths](./listings/adverse-events/ael04.qmd) @@ -281,7 +281,7 @@ toc-depth: 4 #### ECG -        [EGL01 -- 'Listing of ECG Data: Safety-Evaluable Patients'](./listings/ecg/egl01.qmd) +        [EGL01 -- 'Listing of ECG Data: Safety-Evaluable Patients'](./listings/ECG/egl01.qmd) #### Exposure @@ -291,14 +291,14 @@ toc-depth: 4 #### Lab Results -        [LBL01_RLS -- Listing of Laboratory Test Results Using Roche Safety Lab Standardization](./listings/lab-results/lbl01_rls.qmd) -         [LBL01 -- Listing of Laboratory Test Results](./listings/lab-results/lbl01.qmd) -        [LBL02A_RLS -- Listing of Laboratory Abnormalities Defined by Roche Safety Lab Standardization](./listings/lab-results/lbl02a_rls.qmd) +        [LBL01_RLS -- Listing of Laboratory Test Results Using Roche Safety Lab Standardization](./listings/lab-results/lbl01_rls.qmd)         [LBL02A -- Listing of Laboratory Abnormalities (constant units)](./listings/lab-results/lbl02a.qmd) +        [LBL02A_RLS -- Listing of Laboratory Abnormalities Defined by Roche Safety Lab Standardization](./listings/lab-results/lbl02a_rls.qmd) +         [LBL02B -- Listing of Laboratory Abnormalities (variable units)](./listings/lab-results/lbl02b.qmd)