Skip to content

Commit 0001694

Browse files
committed
submodules v0.0.33 for jamovi library
Multiple bug fixes and enhancements across modules This update includes bug fixes and improvements for agreement clustering (better error handling and input validation), categorical advanced analysis (option and result table renaming for consistency), Bayesian meta-analysis (model type handling, covariate effect extraction, and table row addition), and assay optimization (requiresData set to TRUE, improved data marshalling). Several test files were added or removed, and documentation was updated. Minor changes were made to function signatures and option defaults for improved robustness.
1 parent c7359f6 commit 0001694

File tree

203 files changed

+11365
-3510
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

203 files changed

+11365
-3510
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: ClinicoPath
33
Title: Comprehensive Analysis for Clinicopathological Research
4-
Version: 0.0.32.77
5-
Date: 2026-01-09
4+
Version: 0.0.33
5+
Date: 2026-01-17
66
Authors@R: person(given = "Serdar", family = "Balci", role = c("aut", "cre"), email = "serdarbalci@serdarbalci.com", comment = c(ORCID = "0000-0002-7852-3851"))
77
Maintainer: Serdar Balci <serdarbalci@serdarbalci.com>
88
Description: ClinicoPath is a comprehensive jamovi module designed specifically

R/agreement.b.R

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4390,8 +4390,8 @@ agreementClass <- if (requireNamespace("jmvcore")) R6::R6Class("agreementClass",
43904390
case_ids <- paste0("Case_", 1:n_cases)
43914391
}
43924392

4393-
if (n_cases < 3) {
4394-
self$results$caseClusterTable$setNote("error", "Clustering requires at least 3 cases")
4393+
if (n_cases < 3 || n_raters < 2) {
4394+
self$results$caseClusterTable$setNote("error", "Clustering requires at least 3 cases and 2 raters")
43954395
return()
43964396
}
43974397

@@ -4421,7 +4421,12 @@ agreementClass <- if (requireNamespace("jmvcore")) R6::R6Class("agreementClass",
44214421
# For continuous: use correlation or Euclidean
44224422
if (distance_metric == "correlation") {
44234423
# Correlation between rating vectors across raters
4424-
cor_matrix <- cor(t(ratings), use = "pairwise.complete.obs")
4424+
cor_matrix <- tryCatch({
4425+
stats::cor(t(as.matrix(ratings)), use = "pairwise.complete.obs")
4426+
}, error = function(e) {
4427+
matrix(0, n_cases, n_cases)
4428+
})
4429+
cor_matrix[is.na(cor_matrix)] <- 0
44254430
dist_matrix <- 1 - cor_matrix
44264431
dist_obj <- as.dist(dist_matrix)
44274432
} else if (distance_metric == "euclidean") {
@@ -4446,6 +4451,11 @@ agreementClass <- if (requireNamespace("jmvcore")) R6::R6Class("agreementClass",
44464451
# Cut tree to get cluster assignments
44474452
cluster_assign <- cutree(hc, k = k)
44484453

4454+
if (any(is.na(cluster_assign))) {
4455+
self$results$caseClusterTable$setNote("error", "Error: Missing values in cluster assignments. Try fewer clusters or check data.")
4456+
return()
4457+
}
4458+
44494459
# Store dendrogram state
44504460
if (self$options$showCaseDendrogram) {
44514461
dendro <- self$results$caseDendrogram
@@ -4508,7 +4518,7 @@ agreementClass <- if (requireNamespace("jmvcore")) R6::R6Class("agreementClass",
45084518
for (cl in unique(cluster_assign)) {
45094519
cl_idx <- which(cluster_assign == cl)
45104520
n_sample <- min(length(cl_idx), ceiling(200 * length(cl_idx) / n_cases))
4511-
sample_idx <- c(sample_idx, sample(cl_idx, n_sample))
4521+
sample_idx <- c(sample_idx, cl_idx[sample.int(length(cl_idx), n_sample)])
45124522
}
45134523

45144524
heatmap$setState(list(
@@ -7842,17 +7852,25 @@ agreementClass <- if (requireNamespace("jmvcore")) R6::R6Class("agreementClass",
78427852

78437853

78447854
# irr::kappa2 ----
7845-
result2 <- irr::kappa2(ratings = ratings, weight = wght)
7855+
if (nrow(na.omit(ratings)) > 0) {
7856+
result2 <- irr::kappa2(ratings = ratings, weight = wght)
7857+
} else {
7858+
result2 <- list(value = NA, stat.name = "Kappa", statistic = NA, p.value = NA)
7859+
}
78467860

78477861
# >=3 raters: Fleiss kappa ----
78487862
} else if (length(self$options$vars) >= 3) {
7849-
result2 <- irr::kappam.fleiss(ratings = ratings, exact = exct, detail = TRUE)
7863+
if (nrow(na.omit(ratings)) > 0) {
7864+
result2 <- irr::kappam.fleiss(ratings = ratings, exact = exct, detail = TRUE)
7865+
} else {
7866+
result2 <- list(value = NA, stat.name = "Kappa", statistic = NA, p.value = NA)
7867+
}
78507868
}
78517869

78527870

78537871
# Percentage agreement ----
78547872
result1 <- irr::agree(ratings)
7855-
if (result1[["value"]] > 100) {
7873+
if (!is.na(result1[["value"]]) && result1[["value"]] > 100) {
78567874
result1[["value"]] <- "Please check the data. It seems that observers do not agree on any cases"
78577875
}
78587876

R/agreement.h.R

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ agreementOptions <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
356356
"nominal"),
357357
permitted=list(
358358
"factor",
359-
"numeric"))
359+
"numeric"),
360+
default=NULL)
360361
private$..rankRaters <- jmvcore::OptionBool$new(
361362
"rankRaters",
362363
rankRaters,
@@ -373,7 +374,8 @@ agreementOptions <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
373374
"ordinal"),
374375
permitted=list(
375376
"factor",
376-
"numeric"))
377+
"numeric"),
378+
default=NULL)
377379
private$..iccHierarchical <- jmvcore::OptionBool$new(
378380
"iccHierarchical",
379381
iccHierarchical,
@@ -525,7 +527,8 @@ agreementOptions <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
525527
"nominal",
526528
"ordinal"),
527529
permitted=list(
528-
"factor"))
530+
"factor"),
531+
default=NULL)
529532
private$..subgroupForestPlot <- jmvcore::OptionBool$new(
530533
"subgroupForestPlot",
531534
subgroupForestPlot,
@@ -3198,10 +3201,10 @@ agreement <- function(
31983201
interIntraSeparator = "_",
31993202
showInterIntraRaterGuide = FALSE,
32003203
pairwiseKappa = FALSE,
3201-
referenceRater,
3204+
referenceRater = NULL,
32023205
rankRaters = FALSE,
32033206
hierarchicalKappa = FALSE,
3204-
clusterVariable,
3207+
clusterVariable = NULL,
32053208
iccHierarchical = FALSE,
32063209
clusterSpecificKappa = TRUE,
32073210
varianceDecomposition = TRUE,
@@ -3231,7 +3234,7 @@ agreement <- function(
32313234
raterProfileShowPoints = FALSE,
32323235
showRaterProfileGuide = FALSE,
32333236
agreementBySubgroup = FALSE,
3234-
subgroupVariable,
3237+
subgroupVariable = NULL,
32353238
subgroupForestPlot = TRUE,
32363239
subgroupMinCases = 10,
32373240
showSubgroupGuide = FALSE,

R/aivalidation.h.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ aivalidationOptions <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Clas
4141
"ordinal",
4242
"nominal"),
4343
permitted=list(
44-
"factor"))
44+
"factor"),
45+
default=NULL)
4546
private$..positiveLevel <- jmvcore::OptionLevel$new(
4647
"positiveLevel",
4748
positiveLevel,
@@ -407,7 +408,7 @@ aivalidationBase <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
407408
aivalidation <- function(
408409
data,
409410
predictorVars,
410-
outcomeVar,
411+
outcomeVar = NULL,
411412
positiveLevel,
412413
compareModels = FALSE,
413414
youdensJ = FALSE,

R/assayoptimization.h.R

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ assayoptimizationOptions <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R
3232
super$initialize(
3333
package="ClinicoPath",
3434
name="assayoptimization",
35-
requiresData=FALSE,
35+
requiresData=TRUE,
3636
...)
3737

3838
private$..response_var <- jmvcore::OptionVariable$new(
@@ -421,7 +421,7 @@ assayoptimizationBase <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Cl
421421
pause = NULL,
422422
completeWhenFilled = FALSE,
423423
requiresMissings = FALSE,
424-
weightsSupport = 'na')
424+
weightsSupport = 'auto')
425425
}))
426426

427427
#' Assay Optimization & Experimental Design
@@ -443,6 +443,7 @@ assayoptimizationBase <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Cl
443443
#' design_type = "factorial"
444444
#' )
445445
#'
446+
#' @param data .
446447
#' @param response_var Primary assay response variable for optimization
447448
#' @param factors List of experimental factors for optimization
448449
#' @param blocking_vars Variables for experimental blocking
@@ -486,6 +487,7 @@ assayoptimizationBase <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Cl
486487
#'
487488
#' @export
488489
assayoptimization <- function(
490+
data,
489491
response_var,
490492
factors,
491493
blocking_vars = NULL,
@@ -516,6 +518,15 @@ assayoptimization <- function(
516518
if ( ! missing(factors)) factors <- jmvcore::resolveQuo(jmvcore::enquo(factors))
517519
if ( ! missing(blocking_vars)) blocking_vars <- jmvcore::resolveQuo(jmvcore::enquo(blocking_vars))
518520
if ( ! missing(covariates)) covariates <- jmvcore::resolveQuo(jmvcore::enquo(covariates))
521+
if (missing(data))
522+
data <- jmvcore::marshalData(
523+
parent.frame(),
524+
`if`( ! missing(response_var), response_var, NULL),
525+
`if`( ! missing(factors), factors, NULL),
526+
`if`( ! missing(blocking_vars), blocking_vars, NULL),
527+
`if`( ! missing(covariates), covariates, NULL))
528+
529+
for (v in blocking_vars) if (v %in% names(data)) data[[v]] <- as.factor(data[[v]])
519530

520531
options <- assayoptimizationOptions$new(
521532
response_var = response_var,

R/bayesianci.b.R

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ bayesianciClass <- R6::R6Class(
123123
stringsAsFactors = FALSE
124124
)
125125

126-
self$results$dataInfo$setData(info_data)
126+
for (i in 1:nrow(info_data)) {
127+
self$results$dataInfo$addRow(rowKey = i, values = info_data[i, ])
128+
}
127129
},
128130

129131
.performBayesianCI = function(outcome_data) {
@@ -214,7 +216,9 @@ bayesianciClass <- R6::R6Class(
214216
)
215217
}
216218

217-
self$results$priorSpecification$setData(prior_data)
219+
for (i in 1:nrow(prior_data)) {
220+
self$results$priorSpecification$addRow(rowKey = i, values = prior_data[i, ])
221+
}
218222
},
219223

220224
.analyzeBinaryOutcome = function(outcome_clean, n) {
@@ -270,7 +274,9 @@ bayesianciClass <- R6::R6Class(
270274
stringsAsFactors = FALSE
271275
)
272276

273-
self$results$posteriorSummary$setData(summary_data)
277+
for (i in 1:nrow(summary_data)) {
278+
self$results$posteriorSummary$addRow(rowKey = i, values = summary_data[i, ])
279+
}
274280

275281
# Calculate credible intervals
276282
private$.calculateCredibleIntervals("Proportion", alpha_post, beta_post, "beta")
@@ -329,7 +335,9 @@ bayesianciClass <- R6::R6Class(
329335
stringsAsFactors = FALSE
330336
)
331337

332-
self$results$posteriorSummary$setData(summary_data)
338+
for (i in 1:nrow(summary_data)) {
339+
self$results$posteriorSummary$addRow(rowKey = i, values = summary_data[i, ])
340+
}
333341

334342
# Calculate credible intervals (normal approximation)
335343
private$.calculateCredibleIntervalsNormal("Mean", posterior_mean, posterior_sd)
@@ -383,7 +391,9 @@ bayesianciClass <- R6::R6Class(
383391
stringsAsFactors = FALSE
384392
)
385393

386-
self$results$posteriorSummary$setData(summary_data)
394+
for (i in 1:nrow(summary_data)) {
395+
self$results$posteriorSummary$addRow(rowKey = i, values = summary_data[i, ])
396+
}
387397

388398
# Calculate credible intervals
389399
private$.calculateCredibleIntervals("Rate", alpha_post, beta_post, "gamma")
@@ -433,7 +443,9 @@ bayesianciClass <- R6::R6Class(
433443
ci_data <- rbind(ci_data, ci_row)
434444
}
435445

436-
self$results$credibleIntervals$setData(ci_data)
446+
for (i in 1:nrow(ci_data)) {
447+
self$results$credibleIntervals$addRow(rowKey = i, values = ci_data[i, ])
448+
}
437449
},
438450

439451
.calculateCredibleIntervalsNormal = function(param_name, mean, sd) {
@@ -474,7 +486,9 @@ bayesianciClass <- R6::R6Class(
474486
ci_data <- rbind(ci_data, ci_row)
475487
}
476488

477-
self$results$credibleIntervals$setData(ci_data)
489+
for (i in 1:nrow(ci_data)) {
490+
self$results$credibleIntervals$addRow(rowKey = i, values = ci_data[i, ])
491+
}
478492
},
479493

480494
.calculateHPDIntervals = function(param_name, shape_param, scale_param, distribution) {
@@ -505,7 +519,9 @@ bayesianciClass <- R6::R6Class(
505519
stringsAsFactors = FALSE
506520
)
507521

508-
self$results$hpdIntervals$setData(hpd_data)
522+
for (i in 1:nrow(hpd_data)) {
523+
self$results$hpdIntervals$addRow(rowKey = i, values = hpd_data[i, ])
524+
}
509525
},
510526

511527
.compareWithFrequentist = function(param_name, successes, n, alpha_post, beta_post, distribution) {
@@ -551,7 +567,9 @@ bayesianciClass <- R6::R6Class(
551567
stringsAsFactors = FALSE
552568
)
553569

554-
self$results$comparisonTable$setData(comparison_data)
570+
for (i in 1:nrow(comparison_data)) {
571+
self$results$comparisonTable$addRow(rowKey = i, values = comparison_data[i, ])
572+
}
555573
},
556574

557575
.compareWithFrequentistNormal = function(param_name, sample_mean, sample_sd, n, post_mean, post_sd) {
@@ -591,7 +609,9 @@ bayesianciClass <- R6::R6Class(
591609
stringsAsFactors = FALSE
592610
)
593611

594-
self$results$comparisonTable$setData(comparison_data)
612+
for (i in 1:nrow(comparison_data)) {
613+
self$results$comparisonTable$addRow(rowKey = i, values = comparison_data[i, ])
614+
}
595615
},
596616

597617
.performSensitivityAnalysis = function(outcome_clean) {
@@ -652,7 +672,9 @@ bayesianciClass <- R6::R6Class(
652672
sens_data <- rbind(sens_data, sens_row)
653673
}
654674

655-
self$results$sensitivityAnalysis$setData(sens_data)
675+
for (i in 1:nrow(sens_data)) {
676+
self$results$sensitivityAnalysis$addRow(rowKey = i, values = sens_data[i, ])
677+
}
656678
}
657679
},
658680

@@ -743,7 +765,9 @@ bayesianciClass <- R6::R6Class(
743765
interpretation_data <- rbind(interpretation_data, interp_row)
744766
}
745767

746-
self$results$clinicalInterpretation$setData(interpretation_data)
768+
for (i in 1:nrow(interpretation_data)) {
769+
self$results$clinicalInterpretation$addRow(rowKey = i, values = interpretation_data[i, ])
770+
}
747771
},
748772

749773
.setMethodExplanation = function() {

0 commit comments

Comments
 (0)