# Program Name: tsfae19d.R# Prep Environmentlibrary(envsetup)library(tern)library(dplyr)library(rtables)library(junco)# Define script level parameters:# - Define output ID and file locationtblid <-"TSFAE19d"fileid <- tblidtab_titles <-get_titles_from_file(input_path ='../../_data/', tblid)string_map <- default_str_maptrtvar <-"TRT01A"popfl <-"SAFFL"sex <-"F"ocmqclass <-"Broad"ocmqflag <-"GENSPFFL"ocmqnam_list <-c("Abnormal Uterine Bleeding","Amenorrhea","Bacterial Vaginosis","Decreased Menstrual Bleeding","Excessive Menstrual Bleeding")combined_colspan_trt <-FALSErisk_diff <-TRUErr_method <-"wald"ctrl_grp <-"Placebo"if (combined_colspan_trt ==TRUE) {# Set up levels and label for the required combined columns add_combo <-add_combo_facet("Combined",label ="Combined",levels =c("Xanomeline High Dose", "Xanomeline Low Dose") )# choose if any facets need to be removed - e.g remove the combined column for placebo rm_combo_from_placebo <-cond_rm_facets(facets ="Combined",ancestor_pos =NA,value =" ",split ="colspan_trt" ) mysplit <-make_split_fun(post =list(add_combo, rm_combo_from_placebo))}# Process Data:adsl <- pharmaverseadamjnj::adsl %>%filter(!!rlang::sym(popfl) =="Y"& SEX == sex) %>%select(STUDYID, USUBJID, all_of(trtvar), all_of(popfl))adae <- pharmaverseadamjnj::adaeocmq %>%filter( TRTEMFL =="Y"& OCMQCLSS == ocmqclass & (!!rlang::sym(ocmqflag) =="Y") ) %>%select(USUBJID, TRTEMFL, OCMQNAM, AEDECOD, !!rlang::sym(ocmqflag)) %>%mutate(OCMQNAM =factor(OCMQNAM, levels =union(levels(OCMQNAM), ocmqnam_list)), )adsl$colspan_trt <-factor(ifelse(adsl[[trtvar]] =="Placebo", " ", "Active Study Agent"),levels =c("Active Study Agent", " "))if (risk_diff ==TRUE) { adsl$rrisk_header <-"Risk Difference (%) (95% CI)"### to avoid problems with level of trtvar not observed in main domain adsl$rrisk_label <-factor(paste(adsl[[trtvar]], paste("vs", ctrl_grp)),levels =paste(levels(adsl[[trtvar]]), paste("vs", ctrl_grp)) )}# join data togetheradae <- adae %>%inner_join(., adsl, by =intersect(names(adae), names(adsl)))colspan_trt_map <-create_colspan_map( adsl,non_active_grp = ctrl_grp,non_active_grp_span_lbl =" ",active_grp_span_lbl ="Active Study Agent",colspan_var ="colspan_trt",trt_var = trtvar)# Define layout and build table:# new approach to prevent label problems when treatment group not available in domain datasetctrl_grp2 <-paste(ctrl_grp, "vs", ctrl_grp)ref_path <-c("colspan_trt", " ", "rrisk_label", ctrl_grp2)extra_args_rr <-list(method = rr_method,ref_path = ref_path,.stats =c("count_unique_fraction"))lyt <-basic_table(top_level_section_div =" ",show_colcounts =TRUE,colcount_format ="N=xx") %>%split_cols_by("colspan_trt",split_fun =trim_levels_to_map(map = colspan_trt_map) )if (combined_colspan_trt ==TRUE) { lyt <- lyt %>%split_cols_by(trtvar, split_fun = mysplit)} else { lyt <- lyt %>%split_cols_by(trtvar)}if (risk_diff ==TRUE) { lyt <- lyt %>%split_cols_by("rrisk_header", nested =FALSE) %>%# split_cols_by(trtvar, labels_var = "rrisk_label", split_fun = remove_split_levels("Placebo"))### do not use labels_var, but rrisk_label as variable### note updated level in remove_split_levelssplit_cols_by("rrisk_label", split_fun =remove_split_levels(ctrl_grp2))}lyt <- lyt %>%split_rows_by("OCMQNAM",split_label =paste0("OCMQ (", ocmqclass, ")"),split_fun =keep_split_levels(ocmqnam_list),label_pos ="topleft",section_div =c(" "),child_labels ="hidden",nested =FALSE ) %>%summarize_row_groups("OCMQNAM",cfun = a_freq_j,extra_args = extra_args_rr ) %>%analyze("AEDECOD",afun = a_freq_j,extra_args =c(extra_args_rr, list(drop_levels =TRUE)) ) %>%append_topleft(" Preferred Term, n (%)")result <-build_table(lyt, adae, alt_counts_df = adsl)# If there is no data display "No data to display" textif (nrow(adae) ==0) { result <-safe_prune_table(result)}# Post-Processing step to sort by descending count on chosen active treatment columns.if (nrow(adae) !=0) {# result <- sort_at_path(result, c("OCMQNAM"), scorefun = jj_complex_scorefun()) result <-sort_at_path( result,c("OCMQNAM", "*", "AEDECOD"),scorefun =jj_complex_scorefun() )}## note : perform this step after sorting, otherwise can result in errors (unable to find children AEDECOD)## extra step : to remove lines with No data to report: note usage of trim_rows rather than prune_table## this to ensure the content rows with empty levels are keptprune_empty_level_tablerow <-function(tt) {if (is(tt, "ContentRow")) {return(FALSE) }if (is(tt, "TableRow")) {return(all_zero_or_na(tt)) } kids <-tree_children(tt)length(kids) ==0}result <- result %>%trim_rows(prune_empty_level_tablerow)## Remove the N=xx column headers for the risk difference columnsresult <-remove_col_count(result)# Add titles and footnotes:result <-set_titles(result, tab_titles)# Convert to tbl file and output tablett_to_tlgrtf(string_map = string_map, tt = result, file = fileid, orientation ="landscape")
TSFAE19d:Subjects With Treatment-emergent Adverse Events by Female-specific FDA Medical Query (Broad) and Preferred Term; Female-specific Safety Analysis Set (Study jjcs - core)
Active Study Agent
Risk Difference (%) (95% CI)
OCMQ (Broad)
Xanomeline High Dose
Xanomeline Low Dose
Placebo
Xanomeline High Dose vs Placebo
Xanomeline Low Dose vs Placebo
Preferred Term, n (%)
N=24
N=39
N=36
Abnormal Uterine Bleeding
0
1 (2.6%)
1 (2.8%)
-2.8 (-8.1, 2.6)
-0.2 (-7.5, 7.1)
BLEEDING ANOVULATORY
0
1 (2.6%)
1 (2.8%)
-2.8 (-8.1, 2.6)
-0.2 (-7.5, 7.1)
Amenorrhea
0
0
0
0.0 (0.0, 0.0)
0.0 (0.0, 0.0)
Bacterial Vaginosis
0
0
0
0.0 (0.0, 0.0)
0.0 (0.0, 0.0)
Decreased Menstrual Bleeding
0
0
0
0.0 (0.0, 0.0)
0.0 (0.0, 0.0)
Excessive Menstrual Bleeding
0
0
0
0.0 (0.0, 0.0)
0.0 (0.0, 0.0)
Key: FMQ=FDA Medical Query
Note: Adverse events are coded using MedDRA version 26.0.