R/sequentialtests.h.R

Defines functions sequentialtests

Documented in sequentialtests

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

sequentialtestsOptions <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
    "sequentialtestsOptions",
    inherit = jmvcore::Options,
    public = list(
        initialize = function(
            test1_name = "Screening Test",
            test1_sens = 0.95,
            test1_spec = 0.7,
            test2_name = "Confirmatory Test",
            test2_sens = 0.8,
            test2_spec = 0.98,
            strategy = "serial_positive",
            prevalence = 0.1,
            show_explanation = TRUE,
            show_formulas = FALSE,
            show_nomogram = FALSE, ...) {

            super$initialize(
                package="ClinicoPath",
                name="sequentialtests",
                requiresData=FALSE,
                ...)

            private$..test1_name <- jmvcore::OptionString$new(
                "test1_name",
                test1_name,
                default="Screening Test")
            private$..test1_sens <- jmvcore::OptionNumber$new(
                "test1_sens",
                test1_sens,
                default=0.95,
                min=0.01,
                max=0.99)
            private$..test1_spec <- jmvcore::OptionNumber$new(
                "test1_spec",
                test1_spec,
                default=0.7,
                min=0.01,
                max=0.99)
            private$..test2_name <- jmvcore::OptionString$new(
                "test2_name",
                test2_name,
                default="Confirmatory Test")
            private$..test2_sens <- jmvcore::OptionNumber$new(
                "test2_sens",
                test2_sens,
                default=0.8,
                min=0.01,
                max=0.99)
            private$..test2_spec <- jmvcore::OptionNumber$new(
                "test2_spec",
                test2_spec,
                default=0.98,
                min=0.01,
                max=0.99)
            private$..strategy <- jmvcore::OptionList$new(
                "strategy",
                strategy,
                options=list(
                    "serial_positive",
                    "serial_negative",
                    "parallel"),
                default="serial_positive")
            private$..prevalence <- jmvcore::OptionNumber$new(
                "prevalence",
                prevalence,
                default=0.1,
                min=0.001,
                max=0.999)
            private$..show_explanation <- jmvcore::OptionBool$new(
                "show_explanation",
                show_explanation,
                default=TRUE)
            private$..show_formulas <- jmvcore::OptionBool$new(
                "show_formulas",
                show_formulas,
                default=FALSE)
            private$..show_nomogram <- jmvcore::OptionBool$new(
                "show_nomogram",
                show_nomogram,
                default=FALSE)

            self$.addOption(private$..test1_name)
            self$.addOption(private$..test1_sens)
            self$.addOption(private$..test1_spec)
            self$.addOption(private$..test2_name)
            self$.addOption(private$..test2_sens)
            self$.addOption(private$..test2_spec)
            self$.addOption(private$..strategy)
            self$.addOption(private$..prevalence)
            self$.addOption(private$..show_explanation)
            self$.addOption(private$..show_formulas)
            self$.addOption(private$..show_nomogram)
        }),
    active = list(
        test1_name = function() private$..test1_name$value,
        test1_sens = function() private$..test1_sens$value,
        test1_spec = function() private$..test1_spec$value,
        test2_name = function() private$..test2_name$value,
        test2_sens = function() private$..test2_sens$value,
        test2_spec = function() private$..test2_spec$value,
        strategy = function() private$..strategy$value,
        prevalence = function() private$..prevalence$value,
        show_explanation = function() private$..show_explanation$value,
        show_formulas = function() private$..show_formulas$value,
        show_nomogram = function() private$..show_nomogram$value),
    private = list(
        ..test1_name = NA,
        ..test1_sens = NA,
        ..test1_spec = NA,
        ..test2_name = NA,
        ..test2_sens = NA,
        ..test2_spec = NA,
        ..strategy = NA,
        ..prevalence = NA,
        ..show_explanation = NA,
        ..show_formulas = NA,
        ..show_nomogram = NA)
)

sequentialtestsResults <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
    "sequentialtestsResults",
    inherit = jmvcore::Group,
    active = list(
        summary_table = function() private$.items[["summary_table"]],
        individual_tests_table = function() private$.items[["individual_tests_table"]],
        population_flow_table = function() private$.items[["population_flow_table"]],
        explanation_text = function() private$.items[["explanation_text"]],
        formulas_text = function() private$.items[["formulas_text"]],
        plot_nomogram = function() private$.items[["plot_nomogram"]]),
    private = list(),
    public=list(
        initialize=function(options) {
            super$initialize(
                options=options,
                name="",
                title="Sequential Testing Analysis",
                refs=list(
                    "DiagnosticTests",
                    "Fagan",
                    "Fagan2",
                    "sensspecwiki",
                    "ClinicoPathJamoviModule"))
            self$add(jmvcore::Table$new(
                options=options,
                name="summary_table",
                title="Summary of Testing Strategy",
                rows=1,
                columns=list(
                    list(
                        `name`="strategy_name", 
                        `title`="Testing Strategy", 
                        `type`="text"),
                    list(
                        `name`="prevalence", 
                        `title`="Disease Prevalence", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="first_test", 
                        `title`="First Test", 
                        `type`="text"),
                    list(
                        `name`="second_test", 
                        `title`="Second Test", 
                        `type`="text"),
                    list(
                        `name`="combined_sens", 
                        `title`="Combined Sensitivity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="combined_spec", 
                        `title`="Combined Specificity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="combined_ppv", 
                        `title`="Combined PPV", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="combined_npv", 
                        `title`="Combined NPV", 
                        `type`="number", 
                        `format`="pc"))))
            self$add(jmvcore::Table$new(
                options=options,
                name="individual_tests_table",
                title="Individual Test Performance",
                rows=0,
                columns=list(
                    list(
                        `name`="test_name", 
                        `title`="Test", 
                        `type`="text"),
                    list(
                        `name`="sensitivity", 
                        `title`="Sensitivity", 
                        `type`="number", 
                        `format`="pc"),
                    list(
                        `name`="specificity", 
                        `title`="Specificity", 
                        `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`="Positive LR", 
                        `type`="number"),
                    list(
                        `name`="nlr", 
                        `title`="Negative LR", 
                        `type`="number"))))
            self$add(jmvcore::Table$new(
                options=options,
                name="population_flow_table",
                title="Population Flow Analysis",
                rows=0,
                columns=list(
                    list(
                        `name`="stage", 
                        `title`="Testing Stage", 
                        `type`="text"),
                    list(
                        `name`="total_n", 
                        `title`="Total Subjects", 
                        `type`="number"),
                    list(
                        `name`="disease_pos", 
                        `title`="Disease Positive", 
                        `type`="number"),
                    list(
                        `name`="disease_neg", 
                        `title`="Disease Negative", 
                        `type`="number"),
                    list(
                        `name`="test_pos", 
                        `title`="Test Positive", 
                        `type`="number"),
                    list(
                        `name`="test_neg", 
                        `title`="Test Negative", 
                        `type`="number"),
                    list(
                        `name`="true_pos", 
                        `title`="True Positives", 
                        `type`="number"),
                    list(
                        `name`="false_pos", 
                        `title`="False Positives", 
                        `type`="number"),
                    list(
                        `name`="false_neg", 
                        `title`="False Negatives", 
                        `type`="number"),
                    list(
                        `name`="true_neg", 
                        `title`="True Negatives", 
                        `type`="number"))))
            self$add(jmvcore::Html$new(
                options=options,
                name="explanation_text",
                title="Explanation",
                visible="(show_explanation)"))
            self$add(jmvcore::Html$new(
                options=options,
                name="formulas_text",
                title="Formulas Used",
                visible="(show_formulas)"))
            self$add(jmvcore::Image$new(
                options=options,
                name="plot_nomogram",
                title="Sequential Testing Nomogram",
                width=900,
                height=600,
                renderFun=".plot_nomogram",
                visible="(show_nomogram)"))}))

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

#' Sequential Testing Analysis
#'
#' Function for Sequential Testing Analysis. Analyzes how diagnostic accuracy 
#' changes when applying two tests in sequence (screening followed by 
#' confirmation).
#' 
#'
#' @examples
#' \donttest{
#' # example will be added
#'}
#' @param test1_name .
#' @param test1_sens .
#' @param test1_spec .
#' @param test2_name .
#' @param test2_sens .
#' @param test2_spec .
#' @param strategy .
#' @param prevalence .
#' @param show_explanation .
#' @param show_formulas .
#' @param show_nomogram .
#' @return A results object containing:
#' \tabular{llllll}{
#'   \code{results$summary_table} \tab \tab \tab \tab \tab a table \cr
#'   \code{results$individual_tests_table} \tab \tab \tab \tab \tab a table \cr
#'   \code{results$population_flow_table} \tab \tab \tab \tab \tab a table \cr
#'   \code{results$explanation_text} \tab \tab \tab \tab \tab a html \cr
#'   \code{results$formulas_text} \tab \tab \tab \tab \tab a html \cr
#'   \code{results$plot_nomogram} \tab \tab \tab \tab \tab an image \cr
#' }
#'
#' Tables can be converted to data frames with \code{asDF} or \code{\link{as.data.frame}}. For example:
#'
#' \code{results$summary_table$asDF}
#'
#' \code{as.data.frame(results$summary_table)}
#'
#' @export
sequentialtests <- function(
    test1_name = "Screening Test",
    test1_sens = 0.95,
    test1_spec = 0.7,
    test2_name = "Confirmatory Test",
    test2_sens = 0.8,
    test2_spec = 0.98,
    strategy = "serial_positive",
    prevalence = 0.1,
    show_explanation = TRUE,
    show_formulas = FALSE,
    show_nomogram = FALSE) {

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


    options <- sequentialtestsOptions$new(
        test1_name = test1_name,
        test1_sens = test1_sens,
        test1_spec = test1_spec,
        test2_name = test2_name,
        test2_sens = test2_sens,
        test2_spec = test2_spec,
        strategy = strategy,
        prevalence = prevalence,
        show_explanation = show_explanation,
        show_formulas = show_formulas,
        show_nomogram = show_nomogram)

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

    analysis$run()

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