inst/shiny/sample_size/ui.R

## Define Title
title <- titlePanel("Sample Size")
## Define Sidebar Panel
side <- sidebarPanel(
        sliderInput(inputId = "power",
                    label   = "Power (1 - Beta)",
                    value   = 0.9,
                    min     = 0,
                    max     = 1,
                    step    = 0.01,
                    round   = FALSE,
                    ticks   = TRUE),
        sliderInput(inputId = "sig.level",
                    label   = "Significance Level",
                    value   = 0.01,
                    min     = 0.00001,
                    max     = 0.1,
                    step    = 0.00001,
                    round   = FALSE,
                    ticks   = TRUE),
        selectInput(inputId  = "pkg",
                    label    = "Package",
                    selected = "pwr",
                    choices  = c("pwr" = "pwr",
                                 "samplesize"   = "samplesize",
                                 "TrialSize"    = "TrialSize",
                                 "clusterPower" = "clusterPower",
                                 "longpower"    = "longpower",
                                 "PowerTOST"    = "PowerTOST")),
        ## Conditional on the pkg chosen the options of which functions
        ## to use from that pkg are now displayed...
        conditionalPanel(
            condition = "input.pkg == 'pwr'",
            selectInput(inputId  = "test",
                        label    = "Function from pwr pkg",
                        selected = NULL,
                        choices  = c("One-sample Proportion"                = "pwr.p.test",
                                     "Two-sample Proportion (Equal Size)"   = "pwr.2p.test",
                                     "Two-sample Proportion (Unequal Size)" = "pwr.2p2n.test",
                                     "T-test (Equal Size)"                  = "pwr.t.test",
                                     "T-test (Unequal Size)"                = "pwr.t2n.test",
                                     "ANOVA (One-way Balanched)"            = "pwr.anova.test",
                                     "Correlation Test"                     = "pwr.r.test",
                                     "Chi-squared Test"                     = "pwr.chisq.test",
                                     "General Linear Model"                 = "pwr.f2.test"))
        ),
        conditionalPanel(
            condition = "input.pkg == 'samplesize'",
            selectInput(inputId  = "test",
                        label    = "Function from samplesize package",
                        selected = NULL,
                        choices  = c("T-Test of Means" = "n.ttest",
                                     "Wilcoxon-Mann-Whitney for Ordinal Data" = "n.wilcox.ord"))
        ),
        conditionalPanel(
            condition = "input.pkg == 'TrialSize'",
            selectInput(inputId  = "test",
                        label    = "Function from TrialSize package",
                        selected = NULL,
                        choices  = c("ANOVA - Pairwise Comparison for Multiple Sample One-Way" = "OneWayANOVA.pairwise",
                                     "ANOVA - One-Way Pairwise Comparison" = "OneWayANOVA.pairwiseComparison",
                                     "ANOVA - Repeated Measures" = "ANOVA.Repeat.Measure",
                                     "Average Bioequivalence" = "ABE",
                                     "Cox Proportional Hazard Test for Equality" = "Cox.Equality",
                                     "Cox Proportional Hazard Test for Equivalence" = "Cox.Eequivalence",
                                     "Cox Proportional Hazard Test for Non-Inferiority/Superiority" = "Cox.NIS",
                                     "One Sample Mean Test for Equality" = "OneSampleMean.Equality",
                                     "One Sample Mean Test for Equivalence" = "OneSampleMean.Equivalence",
                                     "One Sample Mean Test for Non-Inferiority/Superiority" = "OneSampleMean.NIS",
                                     "One Sample Proportion Test for Equality" = "OneSampleProportion.Equality",
                                     "One Sample Proportion Test for Equivalence" = "OneSampleProportion.Equivalence",
                                     "One Sample Proportion Test for Non-Inferiority/Superiority" = "OneSampleProportion.NIS"))
            ## ToDo - Add all possible models
                                     ## "" = "",
                                     ## "" = "",
                                     ## "" = "",
                                     ## "" = "",
                                     ## "" = ""))
        ),
        conditionalPanel(
            condition = "input.pkg == 'clusterPower'",
            selectInput(inputId  = "test",
                        label    = "Function from clusterPower package",
                        selected = NULL,
                        choices  = c("Continuous Outcome"    = "crtpwr.2mean",
                                     "Binary Outcome"        = "crtpwr.2prop",
                                     "Count (Rate) Outcome " = "crtpwr.2rate",
                                     "Coefficient of Variation" = "hayes.power.poisson"))
        ),
        conditionalPanel(
            condition = "input.pkg == 'longpower'",
            selectInput(inputId  = "test",
                        label    = "Function from longpower package",
                        selected = NULL,
                        choices  = c("Difference in slopes between two groups" = "diggle.linear.power",
                                     "Linear Mixed Model Sample Size Calculations" = "edland.linear.power",
                                     "Linear mixed model sample size calculations (Liu & Liang)" = "liu.liang.linear.power"))
            ## ToDo - Add all possible methods
                                     ## "Sample Size Calculations for Linear Mixed Models of Rate of Change based on pilot estimates " = "lmmpower",
                                     ## "" = ""))
        ),
        ## ToDo - Add functions from package PowerTOST
        ## conditionalPanel(
        ##     condition = "input.pkg == 'PowerTOST'",
        ##     selectInput(inputId  = "test",
        ##                 label    = "Function from PowerTOST package",
        ##                 selected = NULL,
        ##                 choices  = c("" = "",
        ##                              "" = ""))
        ## )
        ## Now that the function has been chosen present the user with the options
        ## specific to that package
        conditionalPanel(
            condition = "input.test == 'pwr.p.test'",
            sliderInput(inputId = "p1",
                        label   = "Proportion 1",
                        value   = 0.5,
                        min     = 0,
                        max     = 1,
                        step    = 0.001,
                        round   = FALSE,
                        ticks   = TRUE),
            sliderInput(inputId = "p2",
                        label   = "Proportion 2",
                        value   = 0.4,
                        min     = 0,
                        max     = 1,
                        step    = 0.001,
                        round   = FALSE,
                        ticks   = TRUE),
            selectInput(inputId  = "alternative",
                        label    = "Alternative Hypothesis",
                        selected = "two.sided",
                        choices  = c("Two-Sided" = "two.sided",
                                     "Greater"   = "greater",
                                     "Less"      = "less"))
        ),
        conditionalPanel(
            condition = "input.test == 'pwr.2p.test'",
            sliderInput(inputId = "p1",
                        label   = "Proportion 1",
                        value   = 0.5,
                        min     = 0,
                        max     = 1,
                        step    = 0.001,
                        round   = FALSE,
                        ticks   = TRUE),
            sliderInput(inputId = "p2",
                        label   = "Proportion 2",
                        value   = 0.4,
                        min     = 0,
                        max     = 1,
                        step    = 0.001,
                        round   = FALSE,
                        ticks   = TRUE),
            selectInput(inputId  = "alternative",
                        label    = "Alternative Hypothesis",
                        selected = "two.sided",
                        choices  = c("Two-Sided" = "two.sided",
                                     "Greater"   = "greater",
                                     "Less"      = "less"))
        ),
        conditionalPanel(
            condition = "input.test == 'pwr.2p2n.test'",
            sliderInput(inputId = "p1",
                        label   = "Proportion 1",
                        value   = 0.5,
                        min     = 0,
                        max     = 1,
                        step    = 0.001,
                        round   = FALSE,
                        ticks   = TRUE),
            sliderInput(inputId = "p2",
                        label   = "Proportion 2",
                        value   = 0.4,
                        min     = 0,
                        max     = 1,
                        step    = 0.001,
                        round   = FALSE,
                        ticks   = TRUE),
            sliderInput(inputId = "n1",
                        label   = "Number of obs in second sample",
                        value   = 100,
                        min     = 0,
                        max     = 10000,
                        step    = 1,
                        round   = FALSE,
                        ticks   = TRUE),
            sliderInput(inputId = "n2",
                        label   = "Number of obs in second sample",
                        value   = NULL,
                        min     = 0,
                        max     = 10000,
                        step    = 1,
                        round   = FALSE,
                        ticks   = TRUE),
            selectInput(inputId  = "alternative",
                        label    = "Alternative Hypothesis",
                        selected = "two.sided",
                        choices  = c("Two-Sided" = "two.sided",
                                     "Greater"   = "greater",
                                     "Less"      = "less"))
        ),
        conditionalPanel(
            condition = "input.test == 'pwr.t.test'",
            sliderInput(inputId = "d",
                        label   = "Effect Size (Cohen's D)",
                        value   = 0.2,
                        min     = 0,
                        max     = 2,
                        step    = 0.01,
                        round   = FALSE,
                        ticks   = TRUE),
            selectInput(inputId  = "type",
                        label    = "Type of T-Test",
                        selected = "one",
                        choices  = c("One Sample"  = "one.sample",
                                     "Two Sample"  = "two.sample",
                                     "Paired"      = "paired")),
            selectInput(inputId  = "alternative",
                        label    = "Alternative Hypothesis",
                        selected = "two.sided",
                        choices  = c("Two-Sided" = "two.sided",
                                     "Greater"   = "greater",
                                     "Less"      = "less"))
        ),
        conditionalPanel(
            condition = "input.test == 'pwr.t2n.test'",
            sliderInput(inputId = "d",
                        label   = "Effect Size (Cohen's D)",
                        value   = 0.2,
                        min     = 0,
                        max     = 2,
                        step    = 0.01,
                        round   = FALSE,
                        ticks   = TRUE),
            sliderInput(inputId = "n1",
                        label   = "Number of obs in second sample",
                        value   = 100,
                        min     = 0,
                        max     = 10000,
                        step    = 1,
                        round   = FALSE,
                        ticks   = TRUE),
            sliderInput(inputId = "n2",
                        label   = "Number of obs in second sample",
                        value   = NULL,
                        min     = 0,
                        max     = 10000,
                        step    = 1,
                        round   = FALSE,
                        ticks   = TRUE),
            selectInput(inputId  = "alternative",
                        label    = "Alternative Hypothesis",
                        selected = "two.sided",
                        choices  = c("Two-Sided" = "two.sided",
                                     "Greater"   = "greater",
                                     "Less"      = "less"))
        ),
        conditionalPanel(
            condition = "input.test == 'pwr.anova.test'",
            sliderInput(inputId = "k",
                        label   = "Effect Size",
                        value   = 0.2,
                        min     = 0,
                        max     = 2,
                        step    = 0.01,
                        round   = FALSE,
                        ticks   = TRUE),
            sliderInput(inputId = "k",
                        label   = "Number of groups",
                        value   = 2,
                        min     = 0,
                        max     = 100,
                        step    = 1,
                        round   = FALSE,
                        ticks   = TRUE)
        ),
        conditionalPanel(
            condition = "input.test == 'pwr.r.test'",
            sliderInput(inputId = "r",
                        label   = "Linear Correlation Coefficient",
                        value   = 0.2,
                        min     = 0,
                        max     = 2,
                        step    = 0.01,
                        round   = FALSE,
                        ticks   = TRUE),
            selectInput(inputId  = "alternative",
                        label    = "Alternative Hypothesis",
                        selected = "two.sided",
                        choices  = c("Two-Sided" = "two.sided",
                                     "Greater"   = "greater",
                                     "Less"      = "less"))
        ),
        conditionalPanel(
            condition = "input.test == 'pwr.chisq.test'",
            sliderInput(inputId = "w",
                        label   = "Effect Size",
                        value   = 0.2,
                        min     = 0,
                        max     = 2,
                        step    = 0.01,
                        round   = FALSE,
                        ticks   = TRUE),
            sliderInput(inputId = "df",
                        label   = "Degrees of Freedom",
                        value   = 1,
                        min     = 1,
                        max     = 80,
                        step    = 1,
                        round   = FALSE,
                        ticks   = TRUE)
        ),
        conditionalPanel(
            condition = "input.test == 'pwr.f2.test'",
            sliderInput(inputId = "f2",
                        label   = "Effect Size",
                        value   = 0.2,
                        min     = 0,
                        max     = 2,
                        step    = 0.01,
                        round   = FALSE,
                        ticks   = TRUE),
            sliderInput(inputId = "u",
                        label   = "Degrees of Freedom for Numerator",
                        value   = 4,
                        min     = 0,
                        max     = 1000,
                        step    = 1,
                        round   = FALSE,
                        ticks   = TRUE)
        ),
    h2("ToDo"),
    p("This is a work in progress, completed mostly in the authors personal time for gratis.  There are a number of ways in which it can be improved, some of which are listed below."),
    HTML("<ol>
            <li> Take the parameters provided and perform calculations for a range of values around these, plotting results and displaying these since the point estimates are likely to be off and its useful for researchers to know how this will impact the sample size they should be looking to obtain.
            <li> Allow users to specify mean and sd for appropriate functions and calculate effect size (Cohen's D) in the background.
            <li> Expand dynamic sidebar to include <i>all</i> functions offered by each package.
            <li> Improve documentation of the site, e.g. pop-up dialog boxes when moving the mouse over input parameters.
            <li> Migrate the site to <a href='', target='_blank'>shinydashboard</a>.
            <li> Include 'modules' for calculating sample sizes for the various group-sequential study design packages that are available.
          </ol>"),
    p("This application is part of the ",
      a(href = "https://github.com/ns-ctru/ctru",
        "ctru R package"),
      ".")
    ## ToDo - Parameters for all other functions need adding here, they take the form...
    ##
    ##          conditionalPanel(
    ##              condition = "input.test == '[test]'",
    ##              sliderInput(inputid = "[parmaeter]",
    ##                          label   = "[label]",
    ##                          value   = 0.2,
    ##                          min     = 0,
    ##                          max     = 1,
    ##                          step    = 0.01,
    ##                          round   = FALSE,
    ##                          ticks   = TRUE),
    ##              ),
    ##              selectInput(inputId  = "[parameter]",
    ##                          label    = "[label]",
    ##                          selected = "[default]",
    ##                          choices  = c("Default" = "default",
    ##                                       "Option A"   = "optiona",
    ##                                       "Option B"   = "optionb"))
    ##              )
    ##
    ## ...where [test] should reflect the function that is being used and [parameter] should
    ## be the name of the argument to the function.  [label] should be a textual description of
    ## the field that is being completed.  For selectInput() the input is an option of those listed
    ## by the function, these should have the form
    ## "choices = c("Descriptive label shown in Shiny" = "option.in.package")
    )
## Define mainPanel
main <- mainPanel(
    fluidRow(width = 8,
        h2("Overview"),
        p("This site allows you to compute sample sizes for lots of study designs.  It uses a number of packages that are listed on the",
          a(href = "https://cran.r-project.org/web/views/ClinicalTrials.html",
            "CRAN Clinical Trials TaskView"),
          " and is simply a graphical wrapper for the various packages listed there saving the user to be familiar with ",
          a(href = "https://www.r-project.org/",
            "R"),
          " and its syntax in order to perform sample size calculations.  For now only point estimates of the estimated power based on the supplied parameters are provided (see ToDo list for possible extensions).  Currently the packages that are supported are listed below and it is recommended you read and understand each package/function so that you can provide the appropriate input (links open the CRAN page in a new tab).") ,
        HTML("<ul>
                            <li> <a href='https://cran.r-project.org/web/packages/pwr/' target='_blank'>pwr</a>
                            <li> <a href='https://cran.r-project.org/web/packages/samplesize/' target='_blank'>samplesize</a>
                            <li> <a href='https://cran.r-project.org/web/packages/TrialSize/' target='_blank'>TrialSize</a>
                            <li> <a href='https://cran.r-project.org/web/packages/clusterPower/' target='_blank'>clusterPower</a>
                            <li> <a href='https://cran.r-project.org/web/packages/longpower/' target='_blank'>longpower</a>
                            <li> <a href='https://cran.r-project.org/web/packages/powerTOST/' target='_blank'>powerTOST</a>
                           </ul>")
        ),
    fluidRow(width = 10,
             h2("Results"),
             column(width = 10,
                    valueBoxOutput("pkg"),
                    valueBoxOutput("n"),
                    valueBoxOutput("alpha"),
                    valueBoxOutput("power")
             )
    ),
    fluidRow(width = 8,
        h2("Note..."),
        p("Many of these calculations over-simplify the analysis, assuming a direct test of proportions, or comparison of means is made (some of the provided calculators account for study designs such as clustering and/or longitudinal analyses).  Very often analyses are far more sophisticated and include adjustments for covariates and in doing so the power of the test performed is altered.  Such factors affecting the sample size calculations performed here are not accounted for.  Users interested in a more complete and rounded approach to sample size calculations that accounts for this may be interested in simulation and are pointed towards the excellent package ",
          a(href = "https://cran.r-project.org/web/packages/simglm/index.html",
            "simglm"),
          " (",
          a(href = "https://github.com/lebebr01/simglm",
            "GitHub"),
          ") which allows a more complete specification of many study designs and performs simulations to determine the power of a given sample size.  It includes a Shiny WebUI application to ease the process of specifying models.  It includes several vignettes, the most relevant of which is",
          a(href = "https://cran.r-project.org/web/packages/simglm/vignettes/Power.html",
            "Power Analysis with simglm"),
          ".")
    )
)
## Pass title, side and main to ui as a Fluid Page
ui <- fluidPage(title,
                side,
                main)
ns-ctru/ctru documentation built on May 23, 2019, 9:34 p.m.