Bin
Bin

Reputation: 547

How to add interactive textinput panel in R shiny

library(shiny)
library(ggplot2)

ui <- shinyUI(fluidPage(
    titlePanel("Central Limit Theorem Simulation"),
    sidebarLayout(
        sidebarPanel(
            numericInput("sample_size", "Size of each random sample\n(max: 100)", 
                         value = 30, min = 1, max = 100, step = 1),
            sliderInput("simulation", "THe number of simulation",
                        value = 100, min = 100, max = 1000, step = 1),
            selectInput("sample_dist", "Population Distribution where each sample is from",
                        choices = c("Binomial","Poisson", "Normal", "Uniform") ),
            numericInput("bins", "Number of bins in the histogram\n(max: 50)", 
                         value = 20, min = 1, max = 50, step = 1),
            submitButton(text = "Submit")
        ),

        mainPanel(
            tabsetPanel(type = "pills", 
                        tabPanel("mean of random sample mean", br(), 
                                 textOutput(outputId = "output_mean")), 
                        tabPanel("variance of random sample mean", br(), 
                                 textOutput(outputId = "output_var")), 
                        tabPanel("summary table", br(), 
                                 tableOutput(outputId = "output_table")),
                        tabPanel("sample matrix", br(), 
                                 verbatimTextOutput(outputId = "output_sample")),
                        tabPanel("histogram of random normal sample", br(), 
                                 plotOutput(outputId = "output_hist"))
            )
        )
  )


))


server <- shinyServer(function(input, output) {

    # Return the random sample
    rsample <- reactive({
        if (input$sample_dist == "Binomial") {
            rsample <- rbinom(input$sample_size * input$simulation, 1, 0.5)
        } else if (input$sample_dist == "Poisson") {
            rsample <- rpois(input$sample_size * input$simulation, 1)
        } else if (input$sample_dist == "Normal") {
            rsample <- rnorm(input$sample_size * input$simulation)
        } else  {
            rsample <- runif(input$sample_size * input$simulation)
        }
        rsample
    })


        # Return the random sample matrix
    rsamplematrix <- reactive({
        matrix(rsample(), nrow = input$simulation)
    })

    # output mean of sample mean
    output$output_mean <- renderText({
        sample_mean <- rowMeans(rsamplematrix())
        mean(sample_mean)
    })

    # output variance of sample mean
    output$output_var <- renderText({
        sample_mean <- rowMeans(rsamplematrix())
        var(sample_mean)
    })

    # output summary table of sample mean
    output$output_table <- renderTable({
        sample_mean <- rowMeans(rsamplematrix())
        data.frame(mean(sample_mean), var(sample_mean))
    })

    # output the first 5 rows and 5 columns of the sample matrix
    output$output_sample <- renderPrint({
        k = rsamplematrix()
        k[1:5, 1:5]
    })

    # output histogram of sample mean
    output$output_hist <- renderPlot({
        sample_mean <- rowMeans(rsamplematrix())
        ggplot(data.frame(sample_mean), aes(x = sample_mean, y = ..density..)) +
            geom_histogram(bins = input$bins, fill = "steelblue", col = "white") 
    })

})


shinyApp(ui = ui, server = server)



The above code runs well. Suppose right now I want to add textinput of distribution parameters for each distribution (for example, p is parameter for Binomial distribution, mu and sigma are parameters for normal distribution). These parameters input pop out when I made a selection for sample distribution.

What should I do? Which function should I use?


Upvotes: 2

Views: 362

Answers (1)

Gladwell
Gladwell

Reputation: 328

If you want to keep the parameter inputs hidden unless a distribution is selected then I think you want a conditionalPanel.

For example:

conditionalPanel("!(output.plot)", textInput("size", "Size"))

This size input panel would only show when output$plot is not yet rendered.

In your case I think you can use an input in the same way.

conditionalPanel('input.sample_dist) != "Poisson"', textInput("parameter2", "Parameter 2"))

This would show parameter 2 only if Poisson is not selected.

You'll need to remove your submitButton to ensure the parameter fields update when you select a new distribution. Replace it with a generic actionButton if you want to keep the same function.

I'd also suggest using numericInput fields and setting the appropriate label, min, max and step with updateNumericInput for each case in the server function when sample_dist updates.

Upvotes: 1

Related Questions