0

Here is an existing example

library(shiny)
runExample("06_tabsets")

And you will see you can choose distribution type in radiobutton and there are three tabs "Plot", "Summary", and "Table".

My question is how can I add a selectInput under the sliderInput(number of observations) with two values. The default one is "NULL", the second one is "1". Once users select "1", the previous three tabs would disappear. Instead, a new tab would show whatever it content is.

Bratt Swan
  • 1,068
  • 3
  • 16
  • 28
  • 1
    What you need to do is to create the tabs dynamically using `renderUI` on the server side. That way you can have it dependent on the `selectInput` to render different UI according to input. – Xiongbing Jin Aug 28 '16 at 21:44

1 Answers1

1

This is the modified "06_tabsets". A select input is added and the UI is generated depending of the selection. The only difference is that is not using NULL, but two options. I could make it run with NULL. Let me know if this helps.

ui.R

    library(shiny)

    # Define UI for random distribution application 
    shinyUI(fluidPage(

            # Application title
            titlePanel("Tabsets"),

            # Sidebar with controls to select the random distribution type
            # and number of observations to generate. Note the use of the
            # br() element to introduce extra vertical spacing
            sidebarLayout(
                    sidebarPanel(
                            radioButtons("dist", "Distribution type:",
                                         c("Normal" = "norm",
                                           "Uniform" = "unif",
                                           "Log-normal" = "lnorm",
                                           "Exponential" = "exp")),
                            br(),

                            sliderInput("n", 
                                        "Number of observations:", 
                                        value = 500,
                                        min = 1, 
                                        max = 1000),
                            selectInput("contentSelect", "Select content to dislay:", choices = c("1", "2"), selected = 1)
                    ),

                    # Show a tabset that includes a plot, summary, and table view
                    # of the generated distribution
                    mainPanel(
                            uiOutput("content")
                    )
            )
    ))

server.R

    library(shiny)

    # Define server logic for random distribution application
    shinyServer(function(input, output) {

            # Reactive expression to generate the requested distribution.
            # This is called whenever the inputs change. The output
            # functions defined below then all use the value computed from
            # this expression
            data <- reactive({
                    dist <- switch(input$dist,
                                   norm = rnorm,
                                   unif = runif,
                                   lnorm = rlnorm,
                                   exp = rexp,
                                   rnorm)

                    dist(input$n)
            })

            # Generate a plot of the data. Also uses the inputs to build
            # the plot label. Note that the dependencies on both the inputs
            # and the data reactive expression are both tracked, and
            # all expressions are called in the sequence implied by the
            # dependency graph

            output$plot <- renderPlot({
                    dist <- input$dist
                    n <- input$n

                    hist(data(), 
                         main=paste('r', dist, '(', n, ')', sep=''))
            })

            # Generate a summary of the data
            output$summary <- renderPrint({
                    summary(data())
            })

            # Generate an HTML table view of the data
            output$table <- renderTable({
                    data.frame(x=data())
            })
            output$textA <- renderText({
                    paste(input$contentSelect, " A")
            })

            observeEvent(input$contentSelect, {
                    if (input$contentSelect == "1") {
                            output$content <- renderUI({
                                    tabsetPanel(type = "tabs",
                                                tabPanel("Plot", plotOutput("plot")),
                                                tabPanel("Summary", verbatimTextOutput("summary")),
                                                tabPanel("Table", tableOutput("table"))
                                    )
                            })    
                    } else {
                            output$content <- renderUI({
                                    tabsetPanel(type = "tabs",
                                                tabPanel("A", textOutput("textA"))
                                    )
                            })       
                    }
            })


    })
Valter Beaković
  • 3,140
  • 2
  • 20
  • 30
  • Nice answer. I've figured it out. By the way, I think the most important code is observeEvent() function, can you give me some intuition that what situation do we need use observeEvent? – Bratt Swan Aug 30 '16 at 23:28
  • observe in general creates side effects, unlike reactive (or reactiveEvent) that can be considered as a function and returns a value. So to create a side effect (print to the console, download a file, render ui...) you would use observe. observeEvent would typically be used when you want to create a side effect but triggered by one specific event if if in the body of observe event you have other reactives. I guess a typical example would be an actionButton. Check the videos by @JoeCheng from RStudio: [Reactive programming](https://www.rstudio.com/resources/webinars/shiny-developer-conference/) – Valter Beaković Aug 31 '16 at 06:07
  • Is it necessary to use observeEvent? I think if I remove observeEvent function. With only if (input$contentSelect == "1") { output$content <- renderUI({...... That should work also – Bratt Swan Sep 05 '16 at 21:48