Skip to content

Commit 98e8f28

Browse files
committed
Version: 0.0.2.49
1 parent 9e551d3 commit 98e8f28

File tree

11 files changed

+203
-1320
lines changed

11 files changed

+203
-1320
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Type: Package
22
Package: ClinicoPathDescriptives
33
Title: Descriptive Analysis Tools for Clinicopathological Research
4-
Version: 0.0.2.48
5-
Date: 2025-01-15
4+
Version: 0.0.2.49
5+
Date: 2025-01-16
66
Authors@R:
77
person(given = "Serdar",
88
family = "Balci",

R/waterfall.b.R

Lines changed: 106 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ waterfallClass <- if (requireNamespace('jmvcore')) R6::R6Class(
223223
.calculateMetrics = function(df) {
224224
## Calculate response rates ----
225225
cats <- c("CR", "PR", "SD", "PD")
226+
226227
summary_table <- data.frame(
227228
category = cats,
228229
n = sapply(cats, function(x) sum(df$category == x, na.rm = TRUE)),
@@ -427,19 +428,46 @@ waterfallClass <- if (requireNamespace('jmvcore')) R6::R6Class(
427428

428429
## Update results tables ----
429430
for(i in seq_len(nrow(metrics$summary))) {
430-
self$results$summary$addRow(rowKey=i, values=list(
431+
self$results$summaryTable$addRow(rowKey=i, values=list(
431432
category = metrics$summary$category[i],
432433
n = metrics$summary$n[i],
433-
percent = metrics$summary$percent[i]/100
434+
percent = paste0(metrics$summary$percent[i], "%")
434435
))
435436
}
436437

437-
self$results$clinicalMetrics$addRow(rowKey=1, values=list(
438+
439+
440+
self$results$summaryTable$addFootnote(
441+
rowNo = 1,
442+
col = "category",
443+
"Complete Response (CR): Complete disappearance of all target lesions."
444+
)
445+
446+
self$results$summaryTable$addFootnote(
447+
rowNo = 2,
448+
col = "category",
449+
"Partial Response (PR): At least 30% decrease in sum of target lesions."
450+
)
451+
452+
self$results$summaryTable$addFootnote(
453+
rowNo = 3,
454+
col = "category",
455+
"Stable Disease (SD): Neither PR nor PD criteria met."
456+
)
457+
458+
self$results$summaryTable$addFootnote(
459+
rowNo = 4,
460+
col = "category",
461+
"Progressive Disease (PD): At least 20% increase in sum of target lesions."
462+
)
463+
464+
465+
self$results$clinicalMetrics$addRow(rowKey = 1, values = list(
438466
metric = "Objective Response Rate (CR+PR)",
439467
value = paste0(metrics$ORR, "%")
440468
))
441469

442-
self$results$clinicalMetrics$addRow(rowKey=2, values=list(
470+
self$results$clinicalMetrics$addRow(rowKey = 2, values = list(
443471
metric = "Disease Control Rate (CR+PR+SD)",
444472
value = paste0(metrics$DCR, "%")
445473
))
@@ -450,26 +478,53 @@ waterfallClass <- if (requireNamespace('jmvcore')) R6::R6Class(
450478

451479
# mydataview ----
452480

453-
# self$results$mydataview$setContent(
454-
# list(
455-
# "data" = processed_data,
456-
# options = list(
457-
# "patientID" = self$options$patientID,
458-
# "response" = self$options$responseVar,
459-
# "timeVar" = self$options$timeVar,
460-
# "sortBy" = self$options$sortBy,
461-
# "showThresholds" = self$options$showThresholds,
462-
# "labelOutliers" = self$options$labelOutliers,
463-
# "colorScheme" = self$options$colorScheme,
464-
# "barWidth" = self$options$barWidth,
465-
# "barAlpha" = self$options$barAlpha,
466-
# "showMedian" = self$options$showMedian,
467-
# "showCI" = self$options$showCI,
468-
# "minResponseForLabel" = self$options$minResponseForLabel
469-
# ),
470-
# "metrics" = metrics
471-
# )
472-
# )
481+
self$results$mydataview$setContent(
482+
list(
483+
"data" = processed_data,
484+
"data_waterfall" = processed_data$waterfall,
485+
"data_spider" = processed_data$spider,
486+
options = list(
487+
"patientID" = self$options$patientID,
488+
"response" = self$options$responseVar,
489+
"timeVar" = self$options$timeVar,
490+
"sortBy" = self$options$sortBy,
491+
"showThresholds" = self$options$showThresholds,
492+
"labelOutliers" = self$options$labelOutliers,
493+
"colorScheme" = self$options$colorScheme,
494+
"barWidth" = self$options$barWidth,
495+
"barAlpha" = self$options$barAlpha,
496+
"showMedian" = self$options$showMedian,
497+
"showCI" = self$options$showCI,
498+
"minResponseForLabel" = self$options$minResponseForLabel
499+
),
500+
"metrics" = metrics
501+
)
502+
)
503+
504+
505+
## Add response category to data ----
506+
507+
if (is.null(self$options$timeVar) && self$options$addResponseCategory && self$results$addResponseCategory$isNotFilled()) {
508+
df <- processed_data$waterfall
509+
self$results$addResponseCategory$setRowNums(rownames(df))
510+
self$results$addResponseCategory$setValues(df$category)
511+
}
512+
513+
if (!is.null(self$options$timeVar) && self$options$addResponseCategory && self$results$addResponseCategory$isNotFilled()) {
514+
# Get waterfall data and extract unique patient categories
515+
df <- processed_data$waterfall %>%
516+
dplyr::select(!!rlang::sym(self$options$patientID), category) %>%
517+
dplyr::distinct()
518+
519+
# Join with original data
520+
df2 <- self$data %>%
521+
dplyr::left_join(df, by = self$options$patientID)
522+
523+
# Update response category output
524+
self$results$addResponseCategory$setRowNums(rownames(df2))
525+
self$results$addResponseCategory$setValues(df2$category)
526+
}
527+
473528

474529

475530
## Prepare plot data ----
@@ -695,46 +750,46 @@ waterfallClass <- if (requireNamespace('jmvcore')) R6::R6Class(
695750
# Create an informative message with improved formatting for readability
696751
text_warning <- paste0(
697752
"Spider Plot Requirements and Guidelines",
698-
"<br><br>",
753+
"\n\n",
699754
"This visualization requires two key elements:",
700-
"<br>",
755+
"\n",
701756
"1. A time variable to show response trajectories",
702-
"<br>",
757+
"\n",
703758
"2. The 'Show Spider Plot' option to be enabled",
704-
"<br><br>",
759+
"\n\n",
705760
"Understanding Spider Plots:",
706-
"<br>",
707-
"A spider plot helps visualize how each patient's response changes over time. ",
708-
"Each line represents one patient's treatment journey, making it easy to see ",
761+
"\n",
762+
"A spider plot helps visualize how each patient's response changes over time. \n",
763+
"Each line represents one patient's treatment journey, making it easy to see \n",
709764
"patterns in response and identify different types of outcomes.",
710-
"<br><br>",
765+
"\n\n",
711766
"To Generate the Plot:",
712-
"<br>",
767+
"\n",
713768
"• Add a time variable (such as months from baseline)",
714-
"<br>",
769+
"\n",
715770
"• Enable 'Show Spider Plot' in the options panel",
716-
"<br><br>",
717-
"The resulting visualization will help you track response patterns ",
718-
"and compare outcomes across different patients over time.",
771+
"\n\n",
772+
"The resulting visualization will help you track response patterns \n",
773+
"and compare outcomes across different patients over time.\n\n",
719774
sep = ""
720775
)
721776

722777
text_warning <- paste0(text_warning,
723778
"Time Variable Requirement:",
724-
"<br><br>A time variable is required to create visualizations when using raw measurements.",
725-
"<br><br>Why is this important?",
726-
"<br>• Baseline identification: Marks the starting point (time = 0)",
727-
"<br>• Response calculation: Computes changes from baseline",
728-
"<br>• Progression tracking: Shows how response changes over time",
729-
"<br><br>How to proceed:",
730-
"<br>1. Add a time variable to your data",
731-
"<br>2. Time should start at 0 (baseline)",
732-
"<br>3. Use consistent time units (e.g., months or weeks)",
733-
"<br><br>Example time variable format:",
734-
"<br>PatientID. Time Measurement",
735-
"<br>PT1 0 50 (baseline)",
736-
"<br>PT1 2 25 (2 months)",
737-
"<br>PT1 4 10 (4 months)",
779+
"\n\nA time variable is required to create visualizations when using raw measurements.",
780+
"\n\nWhy is this important?",
781+
"\n• Baseline identification: Marks the starting point (time = 0)",
782+
"\n• Response calculation: Computes changes from baseline",
783+
"\n• Progression tracking: Shows how response changes over time",
784+
"\n\nHow to proceed:",
785+
"\n1. Add a time variable to your data",
786+
"\n2. Time should start at 0 (baseline)",
787+
"\n3. Use consistent time units (e.g., months or weeks)",
788+
"\n\nExample time variable format:",
789+
"\nPatientID. Time Measurement",
790+
"\nPT1 0 50 (baseline)",
791+
"\nPT1 2 25 (2 months)",
792+
"\nPT1 4 10 (4 months)",
738793
sep = ""
739794
)
740795

R/waterfall.h.R

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ waterfallOptions <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
2020
barAlpha = 1,
2121
barWidth = 0.7,
2222
showWaterfallPlot = FALSE,
23-
showSpiderPlot = FALSE,
24-
addResponseCategory = FALSE, ...) {
23+
showSpiderPlot = FALSE, ...) {
2524

2625
super$initialize(
2726
package="ClinicoPathDescriptives",
@@ -116,10 +115,8 @@ waterfallOptions <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
116115
"showSpiderPlot",
117116
showSpiderPlot,
118117
default=FALSE)
119-
private$..addResponseCategory <- jmvcore::OptionBool$new(
120-
"addResponseCategory",
121-
addResponseCategory,
122-
default=FALSE)
118+
private$..addResponseCategory <- jmvcore::OptionOutput$new(
119+
"addResponseCategory")
123120

124121
self$.addOption(private$..patientID)
125122
self$.addOption(private$..responseVar)
@@ -180,11 +177,12 @@ waterfallResults <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
180177
active = list(
181178
todo = function() private$.items[["todo"]],
182179
todo2 = function() private$.items[["todo2"]],
183-
summary = function() private$.items[["summary"]],
180+
summaryTable = function() private$.items[["summaryTable"]],
184181
clinicalMetrics = function() private$.items[["clinicalMetrics"]],
185182
waterfallplot = function() private$.items[["waterfallplot"]],
186183
spiderplot = function() private$.items[["spiderplot"]],
187-
responseCategory = function() private$.items[["responseCategory"]]),
184+
addResponseCategory = function() private$.items[["addResponseCategory"]],
185+
mydataview = function() private$.items[["mydataview"]]),
188186
private = list(),
189187
public=list(
190188
initialize=function(options) {
@@ -215,23 +213,28 @@ waterfallResults <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
215213
"inputType")))
216214
self$add(jmvcore::Table$new(
217215
options=options,
218-
name="summary",
219-
title="Response Summary",
216+
name="summaryTable",
217+
title="Response Categories Based on RECIST v1.1 Criteria",
220218
rows=0,
221219
columns=list(
222220
list(
223221
`name`="category",
224-
`title`="Response Category",
222+
`title`="Category",
225223
`type`="text"),
226224
list(
227225
`name`="n",
228-
`title`="n",
226+
`title`="Number of Patients",
229227
`type`="integer"),
230228
list(
231229
`name`="percent",
232-
`title`="%",
230+
`title`="Percentage",
233231
`type`="number",
234-
`format`="percent"))))
232+
`format`="percent")),
233+
clearWith=list(
234+
"patientID",
235+
"responseVar",
236+
"timeVar",
237+
"inputType")))
235238
self$add(jmvcore::Table$new(
236239
options=options,
237240
name="clinicalMetrics",
@@ -245,7 +248,12 @@ waterfallResults <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
245248
list(
246249
`name`="value",
247250
`title`="Value",
248-
`type`="text"))))
251+
`type`="text")),
252+
clearWith=list(
253+
"patientID",
254+
"responseVar",
255+
"timeVar",
256+
"inputType")))
249257
self$add(jmvcore::Image$new(
250258
options=options,
251259
name="waterfallplot",
@@ -267,7 +275,7 @@ waterfallResults <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
267275
self$add(jmvcore::Image$new(
268276
options=options,
269277
name="spiderplot",
270-
title="Response Over Time",
278+
title="Spider Plot - Response Over Time",
271279
width=800,
272280
height=500,
273281
renderFun=".spiderplot",
@@ -281,13 +289,19 @@ waterfallResults <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
281289
"sortBy")))
282290
self$add(jmvcore::Output$new(
283291
options=options,
284-
name="responseCategory",
285-
title="Response Category",
286-
varTitle="`Calculated Response Category`",
292+
name="addResponseCategory",
293+
title="Add Response Category to Data",
294+
varTitle="RECIST",
287295
varDescription="Calculated response category based on RECIST criteria.",
288296
clearWith=list(
289297
"patientID",
290-
"response")))}))
298+
"responseVar",
299+
"timeVar",
300+
"inputType")))
301+
self$add(jmvcore::Preformatted$new(
302+
options=options,
303+
name="mydataview",
304+
title="mydataview"))}))
291305

292306
waterfallBase <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
293307
"waterfallBase",
@@ -307,7 +321,7 @@ waterfallBase <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
307321
pause = NULL,
308322
completeWhenFilled = FALSE,
309323
requiresMissings = FALSE,
310-
weightsSupport = 'auto')
324+
weightsSupport = 'none')
311325
}))
312326

313327
#' Treatment Response Analysis
@@ -348,24 +362,23 @@ waterfallBase <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
348362
#' @param showWaterfallPlot .
349363
#' @param showSpiderPlot Create an additional spider plot showing response
350364
#' over time if longitudinal data available
351-
#' @param addResponseCategory Add a new variable to the data frame indicating
352-
#' response category.
353365
#' @return A results object containing:
354366
#' \tabular{llllll}{
355367
#' \code{results$todo} \tab \tab \tab \tab \tab a html \cr
356368
#' \code{results$todo2} \tab \tab \tab \tab \tab a html \cr
357-
#' \code{results$summary} \tab \tab \tab \tab \tab a table \cr
369+
#' \code{results$summaryTable} \tab \tab \tab \tab \tab a table \cr
358370
#' \code{results$clinicalMetrics} \tab \tab \tab \tab \tab a table \cr
359371
#' \code{results$waterfallplot} \tab \tab \tab \tab \tab an image \cr
360372
#' \code{results$spiderplot} \tab \tab \tab \tab \tab an image \cr
361-
#' \code{results$responseCategory} \tab \tab \tab \tab \tab an output \cr
373+
#' \code{results$addResponseCategory} \tab \tab \tab \tab \tab an output \cr
374+
#' \code{results$mydataview} \tab \tab \tab \tab \tab a preformatted \cr
362375
#' }
363376
#'
364377
#' Tables can be converted to data frames with \code{asDF} or \code{\link{as.data.frame}}. For example:
365378
#'
366-
#' \code{results$summary$asDF}
379+
#' \code{results$summaryTable$asDF}
367380
#'
368-
#' \code{as.data.frame(results$summary)}
381+
#' \code{as.data.frame(results$summaryTable)}
369382
#'
370383
#' @export
371384
waterfall <- function(
@@ -384,8 +397,7 @@ waterfall <- function(
384397
barAlpha = 1,
385398
barWidth = 0.7,
386399
showWaterfallPlot = FALSE,
387-
showSpiderPlot = FALSE,
388-
addResponseCategory = FALSE) {
400+
showSpiderPlot = FALSE) {
389401

390402
if ( ! requireNamespace("jmvcore", quietly=TRUE))
391403
stop("waterfall requires jmvcore to be installed (restart may be required)")
@@ -416,8 +428,7 @@ waterfall <- function(
416428
barAlpha = barAlpha,
417429
barWidth = barWidth,
418430
showWaterfallPlot = showWaterfallPlot,
419-
showSpiderPlot = showSpiderPlot,
420-
addResponseCategory = addResponseCategory)
431+
showSpiderPlot = showSpiderPlot)
421432

422433
analysis <- waterfallClass$new(
423434
options = options,

data/percent_with_time.omv

-115 KB
Binary file not shown.

0 commit comments

Comments
 (0)