|
| 1 | +--- |
| 2 | +title: "Module Customization" |
| 3 | +output: rmarkdown::html_vignette |
| 4 | +vignette: > |
| 5 | + %\VignetteIndexEntry{Module Customization} |
| 6 | + %\VignetteEngine{knitr::rmarkdown} |
| 7 | + %\VignetteEncoding{UTF-8} |
| 8 | +--- |
| 9 | + |
| 10 | +```{r, include = FALSE} |
| 11 | +knitr::opts_chunk$set( |
| 12 | + collapse = TRUE, |
| 13 | + comment = "#>", |
| 14 | + eval = FALSE |
| 15 | +) |
| 16 | +``` |
| 17 | + |
| 18 | +This vignette covers the customization options available in `dv.swimmerplot`. Examples build on the data prepared in the [Swimmer Plot Module](dv-swimmerplot.html) vignette. |
| 19 | + |
| 20 | +## Data Setup |
| 21 | + |
| 22 | +```{r setup} |
| 23 | +library(dv.swimmerplot) |
| 24 | +
|
| 25 | +dm <- pharmaversesdtm::dm |> |
| 26 | + dplyr::filter(ARM != "Screen Failure") |> |
| 27 | + dplyr::select(USUBJID, AGE, SEX, RACE, ARM, RFSTDTC, RFENDTC) |
| 28 | +
|
| 29 | +ex <- dplyr::left_join(pharmaversesdtm::ex, dm, by = "USUBJID") |> |
| 30 | + dplyr::mutate( |
| 31 | + ex_trt = paste(EXTRT, EXDOSE, EXDOSU), |
| 32 | + ex_ongoing = is.na(EXENDY), |
| 33 | + ex_end = ifelse(ex_ongoing, EXSTDY + 10, EXENDY) |
| 34 | + ) |
| 35 | +
|
| 36 | +rs <- dplyr::left_join(pharmaversesdtm::rs_onco, dm, by = "USUBJID") |> |
| 37 | + dplyr::filter(RSTEST == "Overall Response", RSEVAL == "INVESTIGATOR", !is.na(RSDY)) |
| 38 | +
|
| 39 | +sdtm_datasets <- list(dm = dm, ex = ex, rs = rs) |
| 40 | +``` |
| 41 | + |
| 42 | +--- |
| 43 | + |
| 44 | +## Color Palette |
| 45 | + |
| 46 | +Use `color_palette` to assign specific colors to exposure groups. Supply a **named character vector** where names match values of `trt_group_var`. |
| 47 | + |
| 48 | +```{r color-palette} |
| 49 | +mod_swimmerplot( |
| 50 | + module_id = "swimmer_colors", |
| 51 | + subject_level_dataset_name = "dm", |
| 52 | + exposure_dataset_name = "ex", |
| 53 | + response_dataset_name = "rs", |
| 54 | + subjid_var = "USUBJID", |
| 55 | + trt_start_day_var = "EXSTDY", |
| 56 | + trt_end_day_var = "ex_end", |
| 57 | + trt_group_var = "ex_trt", |
| 58 | + trt_ongoing_var = "ex_ongoing", |
| 59 | + result_study_day_var = "RSDY", |
| 60 | + result_cat_var = "RSORRES", |
| 61 | + color_palette = c( |
| 62 | + "PLACEBO 0 mg" = "#AAAAAA", # grey for placebo |
| 63 | + "XANOMELINE 54 mg" = "#4E79A7", # blue |
| 64 | + "XANOMELINE 81 mg" = "#F28E2B" # orange |
| 65 | + ) |
| 66 | +) |
| 67 | +``` |
| 68 | + |
| 69 | +When `color_palette` is `NULL` (the default), ggplot2 automatically assigns colors. |
| 70 | + |
| 71 | +--- |
| 72 | + |
| 73 | +## Shape Mapping for Response Points |
| 74 | + |
| 75 | +Use `shape_mapping` to control the point shape for each response category. Supply a **named numeric vector** where names match values of `result_cat_var` and values are R `pch` codes. |
| 76 | + |
| 77 | +```{r shape-mapping} |
| 78 | +mod_swimmerplot( |
| 79 | + module_id = "swimmer_shapes", |
| 80 | + subject_level_dataset_name = "dm", |
| 81 | + exposure_dataset_name = "ex", |
| 82 | + response_dataset_name = "rs", |
| 83 | + subjid_var = "USUBJID", |
| 84 | + trt_start_day_var = "EXSTDY", |
| 85 | + trt_end_day_var = "ex_end", |
| 86 | + trt_group_var = "ex_trt", |
| 87 | + trt_ongoing_var = "ex_ongoing", |
| 88 | + result_study_day_var = "RSDY", |
| 89 | + result_cat_var = "RSORRES", |
| 90 | + shape_mapping = c( |
| 91 | + "CR" = 16, # filled circle — Complete Response |
| 92 | + "PR" = 17, # filled triangle — Partial Response |
| 93 | + "SD" = 15, # filled square — Stable Disease |
| 94 | + "PD" = 18 # filled diamond — Progressive Disease |
| 95 | + ) |
| 96 | +) |
| 97 | +``` |
| 98 | + |
| 99 | +--- |
| 100 | + |
| 101 | +## Tooltips |
| 102 | + |
| 103 | +Both exposure bars and response points support interactive tooltips. Pass a **named character vector** where names are the label text and values are column names. Labels appear before the value in the tooltip (e.g., `"Dose: 54"`). |
| 104 | + |
| 105 | +```{r tooltips} |
| 106 | +mod_swimmerplot( |
| 107 | + module_id = "swimmer_tooltips", |
| 108 | + subject_level_dataset_name = "dm", |
| 109 | + exposure_dataset_name = "ex", |
| 110 | + response_dataset_name = "rs", |
| 111 | + subjid_var = "USUBJID", |
| 112 | + trt_start_day_var = "EXSTDY", |
| 113 | + trt_end_day_var = "ex_end", |
| 114 | + trt_group_var = "ex_trt", |
| 115 | + trt_ongoing_var = "ex_ongoing", |
| 116 | + trt_tooltip_vars = c( |
| 117 | + "Subject: " = "USUBJID", |
| 118 | + "Treatment: " = "ex_trt", |
| 119 | + "Start Day: " = "EXSTDY", |
| 120 | + "End Day: " = "EXENDY" |
| 121 | + ), |
| 122 | + result_study_day_var = "RSDY", |
| 123 | + result_cat_var = "RSORRES", |
| 124 | + result_tooltip_vars = c( |
| 125 | + "Subject: " = "USUBJID", |
| 126 | + "Study Day: " = "RSDY", |
| 127 | + "Response: " = "RSORRES" |
| 128 | + ) |
| 129 | +) |
| 130 | +``` |
| 131 | + |
| 132 | +Omit `trt_tooltip_vars` or `result_tooltip_vars` (or set them to `NULL`) to disable tooltips for that layer. |
| 133 | + |
| 134 | +--- |
| 135 | + |
| 136 | +## Bar Annotations |
| 137 | + |
| 138 | +`trt_annotation_vars` adds text labels directly on the plot, next to the end of each subject's last exposure bar. This is useful for annotating treatment summaries or end-of-study status. |
| 139 | + |
| 140 | +```{r annotations-trailing} |
| 141 | +# Annotation placed at the end of each subject's last exposure bar (default) |
| 142 | +mod_swimmerplot( |
| 143 | + module_id = "swimmer_annot_trail", |
| 144 | + subject_level_dataset_name = "dm", |
| 145 | + exposure_dataset_name = "ex", |
| 146 | + subjid_var = "USUBJID", |
| 147 | + trt_start_day_var = "EXSTDY", |
| 148 | + trt_end_day_var = "ex_end", |
| 149 | + trt_group_var = "ex_trt", |
| 150 | + trt_ongoing_var = "ex_ongoing", |
| 151 | + trt_annotation_vars = c("ARM"), # column(s) to concatenate as annotation text |
| 152 | + trt_annotation_x = NULL # NULL = place annotation after bar end |
| 153 | +) |
| 154 | +``` |
| 155 | + |
| 156 | +Use `trt_annotation_x` to pin all annotations to a fixed x position, creating an aligned column: |
| 157 | + |
| 158 | +```{r annotations-fixed} |
| 159 | +mod_swimmerplot( |
| 160 | + module_id = "swimmer_annot_fixed", |
| 161 | + subject_level_dataset_name = "dm", |
| 162 | + exposure_dataset_name = "ex", |
| 163 | + subjid_var = "USUBJID", |
| 164 | + trt_start_day_var = "EXSTDY", |
| 165 | + trt_end_day_var = "ex_end", |
| 166 | + trt_group_var = "ex_trt", |
| 167 | + trt_ongoing_var = "ex_ongoing", |
| 168 | + trt_annotation_vars = c("ARM"), |
| 169 | + trt_annotation_x = 200 # fixed x position for all annotation labels |
| 170 | +) |
| 171 | +``` |
| 172 | + |
| 173 | +--- |
| 174 | + |
| 175 | +## Sorting |
| 176 | + |
| 177 | +Control subject ordering with `sort_by_vars` and `sort_direction`. Multiple variables are supported and applied in order. |
| 178 | + |
| 179 | +```{r sorting} |
| 180 | +mod_swimmerplot( |
| 181 | + module_id = "swimmer_sort", |
| 182 | + subject_level_dataset_name = "dm", |
| 183 | + exposure_dataset_name = "ex", |
| 184 | + subjid_var = "USUBJID", |
| 185 | + trt_start_day_var = "EXSTDY", |
| 186 | + trt_end_day_var = "ex_end", |
| 187 | + trt_group_var = "ex_trt", |
| 188 | + trt_ongoing_var = "ex_ongoing", |
| 189 | + sort_by_vars = c("ARM", "AGE"), # primary sort: ARM, secondary: AGE |
| 190 | + sort_direction = "desc" # "asc" or "desc" |
| 191 | +) |
| 192 | +``` |
| 193 | + |
| 194 | +Users can also change sorting interactively at runtime via the **Plot Options** dropdown. The `sort_by_vars` and `sort_direction` arguments set the initial defaults. |
| 195 | + |
| 196 | +--- |
| 197 | + |
| 198 | +## Grouping (Faceting) |
| 199 | + |
| 200 | +`group_by_vars` splits the plot into facets by one or more categorical variables. Each combination gets its own panel with a free y-axis scale. |
| 201 | + |
| 202 | +```{r grouping} |
| 203 | +mod_swimmerplot( |
| 204 | + module_id = "swimmer_group", |
| 205 | + subject_level_dataset_name = "dm", |
| 206 | + exposure_dataset_name = "ex", |
| 207 | + subjid_var = "USUBJID", |
| 208 | + trt_start_day_var = "EXSTDY", |
| 209 | + trt_end_day_var = "ex_end", |
| 210 | + trt_group_var = "ex_trt", |
| 211 | + trt_ongoing_var = "ex_ongoing", |
| 212 | + group_by_vars = c("SEX", "RACE") # facet by sex and race |
| 213 | +) |
| 214 | +``` |
| 215 | + |
| 216 | +Set `group_by_vars = NULL` to display all subjects in a single unfaceted panel. |
| 217 | + |
| 218 | +--- |
| 219 | + |
| 220 | +## Filter Control |
| 221 | + |
| 222 | +The module includes a built-in filter dropdown. Use `filter_var` to choose which variable drives the filter and `filter_values` to restrict the selectable choices. |
| 223 | + |
| 224 | +```{r filter-basic} |
| 225 | +mod_swimmerplot( |
| 226 | + module_id = "swimmer_filter", |
| 227 | + subject_level_dataset_name = "dm", |
| 228 | + exposure_dataset_name = "ex", |
| 229 | + response_dataset_name = "rs", |
| 230 | + subjid_var = "USUBJID", |
| 231 | + trt_start_day_var = "EXSTDY", |
| 232 | + trt_end_day_var = "ex_end", |
| 233 | + trt_group_var = "ex_trt", |
| 234 | + trt_ongoing_var = "ex_ongoing", |
| 235 | + result_study_day_var = "RSDY", |
| 236 | + result_cat_var = "RSORRES", |
| 237 | + filter_var = "ARM", # variable to filter on |
| 238 | + filter_values = c("Xanomeline High Dose", "Xanomeline Low Dose") |
| 239 | +) |
| 240 | +``` |
| 241 | + |
| 242 | +### Filtering from a Different Dataset |
| 243 | + |
| 244 | +By default the filter is drawn from the subject-level dataset. Set `filter_data` to the name of any dataset in your app (e.g. the response dataset) to populate filter choices from there instead: |
| 245 | + |
| 246 | +```{r filter-source} |
| 247 | +mod_swimmerplot( |
| 248 | + module_id = "swimmer_filter_rs", |
| 249 | + subject_level_dataset_name = "dm", |
| 250 | + exposure_dataset_name = "ex", |
| 251 | + response_dataset_name = "rs", |
| 252 | + subjid_var = "USUBJID", |
| 253 | + trt_start_day_var = "EXSTDY", |
| 254 | + trt_end_day_var = "ex_end", |
| 255 | + trt_group_var = "ex_trt", |
| 256 | + trt_ongoing_var = "ex_ongoing", |
| 257 | + result_study_day_var = "RSDY", |
| 258 | + result_cat_var = "RSORRES", |
| 259 | + filter_data = "rs", # draw filter choices from rs |
| 260 | + filter_var = "RSORRES", # filter variable in rs |
| 261 | + filter_values = c("CR", "SD"), # restrict available choices |
| 262 | + filter_default_vals = c("CR", "SD") # pre-select these on startup |
| 263 | +) |
| 264 | +``` |
| 265 | + |
| 266 | +--- |
| 267 | + |
| 268 | +## Axis Labels and Plot Titles |
| 269 | + |
| 270 | +All text labels on the plot are configurable: |
| 271 | + |
| 272 | +```{r labels} |
| 273 | +mod_swimmerplot( |
| 274 | + module_id = "swimmer_labels", |
| 275 | + subject_level_dataset_name = "dm", |
| 276 | + exposure_dataset_name = "ex", |
| 277 | + subjid_var = "USUBJID", |
| 278 | + trt_start_day_var = "EXSTDY", |
| 279 | + trt_end_day_var = "ex_end", |
| 280 | + trt_group_var = "ex_trt", |
| 281 | + trt_ongoing_var = "ex_ongoing", |
| 282 | + trt_legend_label = "Treatment Arm", |
| 283 | + plot_title = "Subject-Level Exposure Timeline", |
| 284 | + plot_subtitle = "Arrows indicate ongoing treatment", |
| 285 | + plot_x_label = "Days from First Dose", |
| 286 | + plot_y_label = "Patient ID" |
| 287 | +) |
| 288 | +``` |
| 289 | + |
| 290 | +--- |
| 291 | + |
| 292 | +## Plot Dimensions |
| 293 | + |
| 294 | +Control the initial plot size (in inches). `plot_height = NULL` auto-scales height based on the number of subjects (approximately 0.3 inches per subject, minimum 6 inches). |
| 295 | + |
| 296 | +```{r dimensions} |
| 297 | +mod_swimmerplot( |
| 298 | + module_id = "swimmer_size", |
| 299 | + subject_level_dataset_name = "dm", |
| 300 | + exposure_dataset_name = "ex", |
| 301 | + subjid_var = "USUBJID", |
| 302 | + trt_start_day_var = "EXSTDY", |
| 303 | + trt_end_day_var = "ex_end", |
| 304 | + trt_group_var = "ex_trt", |
| 305 | + trt_ongoing_var = "ex_ongoing", |
| 306 | + plot_width = 14, # width in inches |
| 307 | + plot_height = NULL # auto-calculated from subject count |
| 308 | +) |
| 309 | +``` |
| 310 | + |
| 311 | +--- |
0 commit comments