R/decisionpanel.h.R

Defines functions decisionpanel

Documented in decisionpanel

# This file is automatically generated, you probably don't want to edit this

decisionpanelOptions <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
    "decisionpanelOptions",
    inherit = jmvcore::Options,
    public = list(
        initialize = function(
            tests = NULL,
            testLevels = "",
            gold = NULL,
            goldPositive = NULL,
            useCosts = FALSE,
            testCosts = "",
            fpCost = 100,
            fnCost = 1000,
            strategies = "all",
            parallelRules = "any",
            customThreshold = 2,
            maxTests = 3,
            sequentialStop = "positive",
            optimizationCriteria = "accuracy",
            minSensitivity = 0.8,
            minSpecificity = 0.8,
            createTree = FALSE,
            treeMethod = "costSensitive",
            maxDepth = 5,
            minSplit = 20,
            showAllCombinations = FALSE,
            topN = 10,
            compareStrategies = TRUE,
            bootstrap = FALSE,
            bootReps = 1000,
            plotTree = TRUE,
            plotComparison = TRUE,
            plotCostEffect = TRUE,
            plotROC = FALSE,
            prevalence = 0,
            crossValidate = FALSE,
            nFolds = 5,
            seed = 12345, ...) {

            super$initialize(
                package="ClinicoPath",
                name="decisionpanel",
                requiresData=TRUE,
                ...)

            private$..tests <- jmvcore::OptionVariables$new(
                "tests",
                tests,
                suggested=list(
                    "nominal"),
                permitted=list(
                    "factor"),
                rejectUnusedLevels=TRUE)
            private$..testLevels <- jmvcore::OptionString$new(
                "testLevels",
                testLevels,
                default="")
            private$..gold <- jmvcore::OptionVariable$new(
                "gold",
                gold,
                suggested=list(
                    "nominal"),
                permitted=list(
                    "factor"))
            private$..goldPositive <- jmvcore::OptionLevel$new(
                "goldPositive",
                goldPositive,
                variable="(gold)")
            private$..useCosts <- jmvcore::OptionBool$new(
                "useCosts",
                useCosts,
                default=FALSE)
            private$..testCosts <- jmvcore::OptionString$new(
                "testCosts",
                testCosts,
                default="")
            private$..fpCost <- jmvcore::OptionNumber$new(
                "fpCost",
                fpCost,
                default=100,
                min=0)
            private$..fnCost <- jmvcore::OptionNumber$new(
                "fnCost",
                fnCost,
                default=1000,
                min=0)
            private$..strategies <- jmvcore::OptionList$new(
                "strategies",
                strategies,
                options=list(
                    "all",
                    "single",
                    "parallel",
                    "sequential",
                    "custom"),
                default="all")
            private$..parallelRules <- jmvcore::OptionList$new(
                "parallelRules",
                parallelRules,
                options=list(
                    "any",
                    "all",
                    "majority",
                    "custom"),
                default="any")
            private$..customThreshold <- jmvcore::OptionNumber$new(
                "customThreshold",
                customThreshold,
                default=2,
                min=1)
            private$..maxTests <- jmvcore::OptionNumber$new(
                "maxTests",
                maxTests,
                default=3,
                min=2,
                max=10)
            private$..sequentialStop <- jmvcore::OptionList$new(
                "sequentialStop",
                sequentialStop,
                options=list(
                    "positive",
                    "negative",
                    "confirmatory",
                    "exclusion"),
                default="positive")
            private$..optimizationCriteria <- jmvcore::OptionList$new(
                "optimizationCriteria",
                optimizationCriteria,
                options=list(
                    "accuracy",
                    "sensitivity",
                    "specificity",
                    "ppv",
                    "npv",
                    "youden",
                    "utility",
                    "efficiency"),
                default="accuracy")
            private$..minSensitivity <- jmvcore::OptionNumber$new(
                "minSensitivity",
                minSensitivity,
                default=0.8,
                min=0,
                max=1)
            private$..minSpecificity <- jmvcore::OptionNumber$new(
                "minSpecificity",
                minSpecificity,
                default=0.8,
                min=0,
                max=1)
            private$..createTree <- jmvcore::OptionBool$new(
                "createTree",
                createTree,
                default=FALSE)
            private$..treeMethod <- jmvcore::OptionList$new(
                "treeMethod",
                treeMethod,
                options=list(
                    "cart",
                    "conditional",
                    "costSensitive",
                    "ensemble"),
                default="costSensitive")
            private$..maxDepth <- jmvcore::OptionNumber$new(
                "maxDepth",
                maxDepth,
                default=5,
                min=1,
                max=10)
            private$..minSplit <- jmvcore::OptionNumber$new(
                "minSplit",
                minSplit,
                default=20,
                min=5)
            private$..showAllCombinations <- jmvcore::OptionBool$new(
                "showAllCombinations",
                showAllCombinations,
                default=FALSE)
            private$..topN <- jmvcore::OptionNumber$new(
                "topN",
                topN,
                default=10,
                min=1,
                max=50)
            private$..compareStrategies <- jmvcore::OptionBool$new(
                "compareStrategies",
                compareStrategies,
                default=TRUE)
            private$..bootstrap <- jmvcore::OptionBool$new(
                "bootstrap",
                bootstrap,
                default=FALSE)
            private$..bootReps <- jmvcore::OptionNumber$new(
                "bootReps",
                bootReps,
                default=1000,
                min=100,
                max=10000)
            private$..plotTree <- jmvcore::OptionBool$new(
                "plotTree",
                plotTree,
                default=TRUE)
            private$..plotComparison <- jmvcore::OptionBool$new(
                "plotComparison",
                plotComparison,
                default=TRUE)
            private$..plotCostEffect <- jmvcore::OptionBool$new(
                "plotCostEffect",
                plotCostEffect,
                default=TRUE)
            private$..plotROC <- jmvcore::OptionBool$new(
                "plotROC",
                plotROC,
                default=FALSE)
            private$..prevalence <- jmvcore::OptionNumber$new(
                "prevalence",
                prevalence,
                default=0,
                min=0,
                max=1)
            private$..crossValidate <- jmvcore::OptionBool$new(
                "crossValidate",
                crossValidate,
                default=FALSE)
            private$..nFolds <- jmvcore::OptionNumber$new(
                "nFolds",
                nFolds,
                default=5,
                min=2,
                max=10)
            private$..seed <- jmvcore::OptionNumber$new(
                "seed",
                seed,
                default=12345)

            self$.addOption(private$..tests)
            self$.addOption(private$..testLevels)
            self$.addOption(private$..gold)
            self$.addOption(private$..goldPositive)
            self$.addOption(private$..useCosts)
            self$.addOption(private$..testCosts)
            self$.addOption(private$..fpCost)
            self$.addOption(private$..fnCost)
            self$.addOption(private$..strategies)
            self$.addOption(private$..parallelRules)
            self$.addOption(private$..customThreshold)
            self$.addOption(private$..maxTests)
            self$.addOption(private$..sequentialStop)
            self$.addOption(private$..optimizationCriteria)
            self$.addOption(private$..minSensitivity)
            self$.addOption(private$..minSpecificity)
            self$.addOption(private$..createTree)
            self$.addOption(private$..treeMethod)
            self$.addOption(private$..maxDepth)
            self$.addOption(private$..minSplit)
            self$.addOption(private$..showAllCombinations)
            self$.addOption(private$..topN)
            self$.addOption(private$..compareStrategies)
            self$.addOption(private$..bootstrap)
            self$.addOption(private$..bootReps)
            self$.addOption(private$..plotTree)
            self$.addOption(private$..plotComparison)
            self$.addOption(private$..plotCostEffect)
            self$.addOption(private$..plotROC)
            self$.addOption(private$..prevalence)
            self$.addOption(private$..crossValidate)
            self$.addOption(private$..nFolds)
            self$.addOption(private$..seed)
        }),
    active = list(
        tests = function() private$..tests$value,
        testLevels = function() private$..testLevels$value,
        gold = function() private$..gold$value,
        goldPositive = function() private$..goldPositive$value,
        useCosts = function() private$..useCosts$value,
        testCosts = function() private$..testCosts$value,
        fpCost = function() private$..fpCost$value,
        fnCost = function() private$..fnCost$value,
        strategies = function() private$..strategies$value,
        parallelRules = function() private$..parallelRules$value,
        customThreshold = function() private$..customThreshold$value,
        maxTests = function() private$..maxTests$value,
        sequentialStop = function() private$..sequentialStop$value,
        optimizationCriteria = function() private$..optimizationCriteria$value,
        minSensitivity = function() private$..minSensitivity$value,
        minSpecificity = function() private$..minSpecificity$value,
        createTree = function() private$..createTree$value,
        treeMethod = function() private$..treeMethod$value,
        maxDepth = function() private$..maxDepth$value,
        minSplit = function() private$..minSplit$value,
        showAllCombinations = function() private$..showAllCombinations$value,
        topN = function() private$..topN$value,
        compareStrategies = function() private$..compareStrategies$value,
        bootstrap = function() private$..bootstrap$value,
        bootReps = function() private$..bootReps$value,
        plotTree = function() private$..plotTree$value,
        plotComparison = function() private$..plotComparison$value,
        plotCostEffect = function() private$..plotCostEffect$value,
        plotROC = function() private$..plotROC$value,
        prevalence = function() private$..prevalence$value,
        crossValidate = function() private$..crossValidate$value,
        nFolds = function() private$..nFolds$value,
        seed = function() private$..seed$value),
    private = list(
        ..tests = NA,
        ..testLevels = NA,
        ..gold = NA,
        ..goldPositive = NA,
        ..useCosts = NA,
        ..testCosts = NA,
        ..fpCost = NA,
        ..fnCost = NA,
        ..strategies = NA,
        ..parallelRules = NA,
        ..customThreshold = NA,
        ..maxTests = NA,
        ..sequentialStop = NA,
        ..optimizationCriteria = NA,
        ..minSensitivity = NA,
        ..minSpecificity = NA,
        ..createTree = NA,
        ..treeMethod = NA,
        ..maxDepth = NA,
        ..minSplit = NA,
        ..showAllCombinations = NA,
        ..topN = NA,
        ..compareStrategies = NA,
        ..bootstrap = NA,
        ..bootReps = NA,
        ..plotTree = NA,
        ..plotComparison = NA,
        ..plotCostEffect = NA,
        ..plotROC = NA,
        ..prevalence = NA,
        ..crossValidate = NA,
        ..nFolds = NA,
        ..seed = NA)
)

decisionpanelResults <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
    "decisionpanelResults",
    inherit = jmvcore::Group,
    active = list(
        summary = function() private$.items[["summary"]],
        optimalPanel = function() private$.items[["optimalPanel"]],
        strategyComparison = function() private$.items[["strategyComparison"]],
        individualTests = function() private$.items[["individualTests"]],
        allCombinations = function() private$.items[["allCombinations"]],
        treeStructure = function() private$.items[["treeStructure"]],
        treePerformance = function() private$.items[["treePerformance"]],
        crossValidation = function() private$.items[["crossValidation"]],
        bootstrapResults = function() private$.items[["bootstrapResults"]],
        treeVisualization = function() private$.items[["treeVisualization"]],
        strategyComparisonPlot = function() private$.items[["strategyComparisonPlot"]],
        costEffectivenessPlot = function() private$.items[["costEffectivenessPlot"]],
        rocCurvesPlot = function() private$.items[["rocCurvesPlot"]],
        recommendations = function() private$.items[["recommendations"]]),
    private = list(),
    public=list(
        initialize=function(options) {
            super$initialize(
                options=options,
                name="",
                title="Decision Panel Optimization",
                refs=list(
                    "rpart",
                    "partykit",
                    "DiagrammeR",
                    "ROCR",
                    "ClinicoPathJamoviModule"))
            self$add(jmvcore::Html$new(
                options=options,
                name="summary",
                title="Summary",
                visible=TRUE))
            self$add(jmvcore::Table$new(
                options=options,
                name="optimalPanel",
                title="Optimal Test Panel",
                visible=TRUE,
                columns=list(
                    list(
                        `name`="rank", 
                        `title`="Rank", 
                        `type`="integer"),
                    list(
                        `name`="tests", 
                        `title`="Test Combination", 
                        `type`="text"),
                    list(
                        `name`="strategy", 
                        `title`="Strategy", 
                        `type`="text"),
                    list(
                        `name`="sensitivity", 
                        `title`="Sensitivity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="specificity", 
                        `title`="Specificity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="accuracy", 
                        `title`="Accuracy", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="ppv", 
                        `title`="PPV", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="npv", 
                        `title`="NPV", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="youden", 
                        `title`="Youden's J", 
                        `type`="number", 
                        `format`="zto"),
                    list(
                        `name`="cost", 
                        `title`="Cost", 
                        `type`="number", 
                        `format`="zto", 
                        `visible`="(useCosts)"),
                    list(
                        `name`="utility", 
                        `title`="Utility", 
                        `type`="number", 
                        `format`="zto", 
                        `visible`="(useCosts)"),
                    list(
                        `name`="efficiency", 
                        `title`="Efficiency", 
                        `type`="number", 
                        `format`="zto", 
                        `visible`="(useCosts)"))))
            self$add(jmvcore::Table$new(
                options=options,
                name="strategyComparison",
                title="Testing Strategy Comparison",
                visible="(compareStrategies)",
                columns=list(
                    list(
                        `name`="strategy", 
                        `title`="Strategy", 
                        `type`="text"),
                    list(
                        `name`="nTests", 
                        `title`="Tests Used", 
                        `type`="integer"),
                    list(
                        `name`="avgSens", 
                        `title`="Avg Sensitivity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="avgSpec", 
                        `title`="Avg Specificity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="avgAccuracy", 
                        `title`="Avg Accuracy", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="avgCost", 
                        `title`="Avg Cost", 
                        `type`="number", 
                        `format`="zto", 
                        `visible`="(useCosts)"),
                    list(
                        `name`="bestPanel", 
                        `title`="Best Panel", 
                        `type`="text"),
                    list(
                        `name`="bestPerformance", 
                        `title`="Best Performance", 
                        `type`="number", 
                        `format`="zto"))))
            self$add(jmvcore::Table$new(
                options=options,
                name="individualTests",
                title="Individual Test Performance",
                visible=TRUE,
                columns=list(
                    list(
                        `name`="test", 
                        `title`="Test", 
                        `type`="text"),
                    list(
                        `name`="sensitivity", 
                        `title`="Sensitivity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="specificity", 
                        `title`="Specificity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="accuracy", 
                        `title`="Accuracy", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="ppv", 
                        `title`="PPV", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="npv", 
                        `title`="NPV", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="plr", 
                        `title`="+LR", 
                        `type`="number", 
                        `format`="zto"),
                    list(
                        `name`="nlr", 
                        `title`="-LR", 
                        `type`="number", 
                        `format`="zto"),
                    list(
                        `name`="cost", 
                        `title`="Cost", 
                        `type`="number", 
                        `format`="zto", 
                        `visible`="(useCosts)"))))
            self$add(jmvcore::Table$new(
                options=options,
                name="allCombinations",
                title="All Test Combinations",
                visible="(showAllCombinations)",
                columns=list(
                    list(
                        `name`="tests", 
                        `title`="Tests", 
                        `type`="text"),
                    list(
                        `name`="strategy", 
                        `title`="Strategy", 
                        `type`="text"),
                    list(
                        `name`="nTests", 
                        `title`="N Tests", 
                        `type`="integer"),
                    list(
                        `name`="sensitivity", 
                        `title`="Sensitivity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="specificity", 
                        `title`="Specificity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="accuracy", 
                        `title`="Accuracy", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="ppv", 
                        `title`="PPV", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="npv", 
                        `title`="NPV", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="cost", 
                        `title`="Cost", 
                        `type`="number", 
                        `format`="zto", 
                        `visible`="(useCosts)"),
                    list(
                        `name`="utility", 
                        `title`="Utility", 
                        `type`="number", 
                        `format`="zto", 
                        `visible`="(useCosts)"))))
            self$add(jmvcore::Html$new(
                options=options,
                name="treeStructure",
                title="Decision Tree Structure",
                visible="(createTree)"))
            self$add(jmvcore::Table$new(
                options=options,
                name="treePerformance",
                title="Decision Tree Performance",
                visible="(createTree)",
                columns=list(
                    list(
                        `name`="node", 
                        `title`="Node", 
                        `type`="text"),
                    list(
                        `name`="condition", 
                        `title`="Condition", 
                        `type`="text"),
                    list(
                        `name`="nCases", 
                        `title`="N Cases", 
                        `type`="integer"),
                    list(
                        `name`="probPositive", 
                        `title`="P(Disease+)", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="decision", 
                        `title`="Decision", 
                        `type`="text"),
                    list(
                        `name`="accuracy", 
                        `title`="Node Accuracy", 
                        `type`="number", 
                        `format`="pc"))))
            self$add(jmvcore::Table$new(
                options=options,
                name="crossValidation",
                title="Cross-Validation Results",
                visible="(crossValidate)",
                columns=list(
                    list(
                        `name`="panel", 
                        `title`="Test Panel", 
                        `type`="text"),
                    list(
                        `name`="strategy", 
                        `title`="Strategy", 
                        `type`="text"),
                    list(
                        `name`="cvSensitivity", 
                        `title`="CV Sensitivity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="cvSensitivitySD", 
                        `title`="SD", 
                        `type`="number", 
                        `format`="zto"),
                    list(
                        `name`="cvSpecificity", 
                        `title`="CV Specificity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="cvSpecificitySD", 
                        `title`="SD", 
                        `type`="number", 
                        `format`="zto"),
                    list(
                        `name`="cvAccuracy", 
                        `title`="CV Accuracy", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="cvAccuracySD", 
                        `title`="SD", 
                        `type`="number", 
                        `format`="zto"))))
            self$add(jmvcore::Table$new(
                options=options,
                name="bootstrapResults",
                title="Bootstrap Confidence Intervals",
                visible="(bootstrap)",
                columns=list(
                    list(
                        `name`="panel", 
                        `title`="Test Panel", 
                        `type`="text"),
                    list(
                        `name`="metric", 
                        `title`="Metric", 
                        `type`="text"),
                    list(
                        `name`="estimate", 
                        `title`="Estimate", 
                        `type`="number", 
                        `format`="zto"),
                    list(
                        `name`="lower", 
                        `title`="2.5%", 
                        `type`="number", 
                        `format`="zto"),
                    list(
                        `name`="upper", 
                        `title`="97.5%", 
                        `type`="number", 
                        `format`="zto"),
                    list(
                        `name`="se", 
                        `title`="SE", 
                        `type`="number", 
                        `format`="zto"))))
            self$add(jmvcore::Image$new(
                options=options,
                name="treeVisualization",
                title="Decision Tree",
                width=800,
                height=600,
                renderFun=".plotTree",
                visible="(plotTree && createTree)",
                clearWith=list(
                    "tests",
                    "gold",
                    "goldPositive",
                    "treeMethod",
                    "maxDepth",
                    "minSplit")))
            self$add(jmvcore::Image$new(
                options=options,
                name="strategyComparisonPlot",
                title="Strategy Comparison",
                width=700,
                height=500,
                renderFun=".plotStrategyComparison",
                visible="(plotComparison && compareStrategies)",
                clearWith=list(
                    "tests",
                    "strategies",
                    "optimizationCriteria")))
            self$add(jmvcore::Image$new(
                options=options,
                name="costEffectivenessPlot",
                title="Cost-Effectiveness Frontier",
                width=700,
                height=500,
                renderFun=".plotCostEffectiveness",
                visible="(plotCostEffect && useCosts)",
                clearWith=list(
                    "tests",
                    "testCosts",
                    "fpCost",
                    "fnCost")))
            self$add(jmvcore::Image$new(
                options=options,
                name="rocCurvesPlot",
                title="ROC Curves for Top Panels",
                width=700,
                height=500,
                renderFun=".plotROCCurves",
                visible="(plotROC)",
                clearWith=list(
                    "tests",
                    "topN")))
            self$add(jmvcore::Html$new(
                options=options,
                name="recommendations",
                title="Recommendations",
                visible=TRUE))}))

decisionpanelBase <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
    "decisionpanelBase",
    inherit = jmvcore::Analysis,
    public = list(
        initialize = function(options, data=NULL, datasetId="", analysisId="", revision=0) {
            super$initialize(
                package = "ClinicoPath",
                name = "decisionpanel",
                version = c(0,0,3),
                options = options,
                results = decisionpanelResults$new(options=options),
                data = data,
                datasetId = datasetId,
                analysisId = analysisId,
                revision = revision,
                pause = NULL,
                completeWhenFilled = FALSE,
                requiresMissings = FALSE,
                weightsSupport = 'auto')
        }))

#' Decision Panel Optimization
#'
#' Optimize diagnostic test panels by evaluating various combination 
#' strategies including parallel testing (cotest), sequential testing, and 
#' repeated tests. Creates decision trees to minimize cost while maximizing 
#' accuracy.
#' 
#'
#' @examples
#' \donttest{
#' # example will be added
#'}
#' @param data The data as a data frame.
#' @param tests Variables representing different diagnostic tests.  Can select
#'   multiple tests (up to 10) for panel optimization.
#' @param testLevels String specifying positive test levels. Can be: - Single
#'   value (used for all tests): "Positive" - Multiple values (comma-separated):
#'   "Positive,Yes,1"   - Empty string (auto-detection): ""
#' @param gold The gold standard variable for disease classification.
#' @param goldPositive The level of the gold standard variable that indicates
#'   disease presence.
#' @param useCosts Include cost considerations in the optimization process.
#' @param testCosts Comma-separated costs for each test in the same order as
#'   selected tests. Example: "10,25,50" for three tests.
#' @param fpCost Cost or harm associated with a false positive result.
#' @param fnCost Cost or harm associated with a false negative result.
#' @param strategies Which testing strategies to evaluate in the analysis.
#' @param parallelRules Rule for combining results in parallel testing.
#' @param customThreshold Number of positive tests required for overall
#'   positive result (when using custom rule).
#' @param maxTests Maximum number of tests to combine in any strategy.
#' @param sequentialStop When to stop testing in sequential strategies.
#' @param optimizationCriteria Primary criterion for optimizing test panels.
#' @param minSensitivity Minimum sensitivity constraint for panel selection.
#' @param minSpecificity Minimum specificity constraint for panel selection.
#' @param createTree Generate an optimal decision tree for test sequencing.
#' @param treeMethod Method for constructing the decision tree.
#' @param maxDepth Maximum depth of the decision tree.
#' @param minSplit Minimum number of observations required to split a node.
#' @param showAllCombinations Display performance metrics for all possible
#'   test combinations.
#' @param topN Number of best-performing panels to display in results.
#' @param compareStrategies Show comparative analysis of different testing
#'   strategies.
#' @param bootstrap Calculate bootstrap confidence intervals for performance
#'   metrics.
#' @param bootReps Number of bootstrap replications for confidence intervals.
#' @param plotTree Display visual representation of the optimal decision tree.
#' @param plotComparison Create comparison plots for different testing
#'   strategies.
#' @param plotCostEffect Create cost-effectiveness frontier plot.
#' @param plotROC Display ROC curves for top performing panels.
#' @param prevalence Known disease prevalence (0 = use sample prevalence).
#' @param crossValidate Perform k-fold cross-validation for panel performance.
#' @param nFolds Number of folds for cross-validation.
#' @param seed Random seed for reproducibility in bootstrap and
#'   cross-validation.
#' @return A results object containing:
#' \tabular{llllll}{
#'   \code{results$summary} \tab \tab \tab \tab \tab a html \cr
#'   \code{results$optimalPanel} \tab \tab \tab \tab \tab a table \cr
#'   \code{results$strategyComparison} \tab \tab \tab \tab \tab a table \cr
#'   \code{results$individualTests} \tab \tab \tab \tab \tab a table \cr
#'   \code{results$allCombinations} \tab \tab \tab \tab \tab a table \cr
#'   \code{results$treeStructure} \tab \tab \tab \tab \tab a html \cr
#'   \code{results$treePerformance} \tab \tab \tab \tab \tab a table \cr
#'   \code{results$crossValidation} \tab \tab \tab \tab \tab a table \cr
#'   \code{results$bootstrapResults} \tab \tab \tab \tab \tab a table \cr
#'   \code{results$treeVisualization} \tab \tab \tab \tab \tab an image \cr
#'   \code{results$strategyComparisonPlot} \tab \tab \tab \tab \tab an image \cr
#'   \code{results$costEffectivenessPlot} \tab \tab \tab \tab \tab an image \cr
#'   \code{results$rocCurvesPlot} \tab \tab \tab \tab \tab an image \cr
#'   \code{results$recommendations} \tab \tab \tab \tab \tab a html \cr
#' }
#'
#' Tables can be converted to data frames with \code{asDF} or \code{\link{as.data.frame}}. For example:
#'
#' \code{results$optimalPanel$asDF}
#'
#' \code{as.data.frame(results$optimalPanel)}
#'
#' @export
decisionpanel <- function(
    data,
    tests,
    testLevels = "",
    gold,
    goldPositive,
    useCosts = FALSE,
    testCosts = "",
    fpCost = 100,
    fnCost = 1000,
    strategies = "all",
    parallelRules = "any",
    customThreshold = 2,
    maxTests = 3,
    sequentialStop = "positive",
    optimizationCriteria = "accuracy",
    minSensitivity = 0.8,
    minSpecificity = 0.8,
    createTree = FALSE,
    treeMethod = "costSensitive",
    maxDepth = 5,
    minSplit = 20,
    showAllCombinations = FALSE,
    topN = 10,
    compareStrategies = TRUE,
    bootstrap = FALSE,
    bootReps = 1000,
    plotTree = TRUE,
    plotComparison = TRUE,
    plotCostEffect = TRUE,
    plotROC = FALSE,
    prevalence = 0,
    crossValidate = FALSE,
    nFolds = 5,
    seed = 12345) {

    if ( ! requireNamespace("jmvcore", quietly=TRUE))
        stop("decisionpanel requires jmvcore to be installed (restart may be required)")

    if ( ! missing(tests)) tests <- jmvcore::resolveQuo(jmvcore::enquo(tests))
    if ( ! missing(gold)) gold <- jmvcore::resolveQuo(jmvcore::enquo(gold))
    if (missing(data))
        data <- jmvcore::marshalData(
            parent.frame(),
            `if`( ! missing(tests), tests, NULL),
            `if`( ! missing(gold), gold, NULL))

    for (v in tests) if (v %in% names(data)) data[[v]] <- as.factor(data[[v]])
    for (v in gold) if (v %in% names(data)) data[[v]] <- as.factor(data[[v]])

    options <- decisionpanelOptions$new(
        tests = tests,
        testLevels = testLevels,
        gold = gold,
        goldPositive = goldPositive,
        useCosts = useCosts,
        testCosts = testCosts,
        fpCost = fpCost,
        fnCost = fnCost,
        strategies = strategies,
        parallelRules = parallelRules,
        customThreshold = customThreshold,
        maxTests = maxTests,
        sequentialStop = sequentialStop,
        optimizationCriteria = optimizationCriteria,
        minSensitivity = minSensitivity,
        minSpecificity = minSpecificity,
        createTree = createTree,
        treeMethod = treeMethod,
        maxDepth = maxDepth,
        minSplit = minSplit,
        showAllCombinations = showAllCombinations,
        topN = topN,
        compareStrategies = compareStrategies,
        bootstrap = bootstrap,
        bootReps = bootReps,
        plotTree = plotTree,
        plotComparison = plotComparison,
        plotCostEffect = plotCostEffect,
        plotROC = plotROC,
        prevalence = prevalence,
        crossValidate = crossValidate,
        nFolds = nFolds,
        seed = seed)

    analysis <- decisionpanelClass$new(
        options = options,
        data = data)

    analysis$run()

    analysis$results
}
sbalci/ClinicoPathJamoviModule documentation built on June 13, 2025, 9:34 a.m.