Search code examples
rshinyshiny-servershinyappsshiny-reactivity

Generating UI/Server based on initial selection


Below is the script I've created for a Shiny app I've created. I am trying to create a landing page of sorts (I don't even know if that's the right phrase to use) that allows you to pick between which dataset you're using. You will notice in the beginning of the script, there is df and df2 (They're both the same dataset but that's irrelevant).

What I would like to do is perhaps have an initial "page" come up that gives you the option to select which data set you're working from. Once that's selected, it would then take you to setup you see below, but with one notable exception: If df2 is selected, it will not include an option to select:

sliderInput("score2", label = h3("Select Score2 Range"), min = 0, max = 100, value = c(20,80))

But you will be able to choose from all the other inputs.

I'm not even sure where to begin with this, so what would be the best way to accomplish this?

    library(dbplyr)
    library(dplyr)
    library(shiny)
    library(shinyWidgets)
    library(DT)
    
    df <- read.csv('https://raw.githubusercontent.com/datacfb123/testdata/main/sampleset_df.csv')
    df2 <- read.csv('https://raw.githubusercontent.com/datacfb123/testdata/main/sampleset_df.csv')
    
    ui <- fluidPage(
  titlePanel("Sample"),
  sidebarLayout(
    sidebarPanel(
      radioButtons("mydata", label = "Choose dataframe", choices = c("df","df2"), inline=TRUE),
      selectizeInput("data1", "Select State", choices = c(unique(df$state))),
      selectizeInput("data2", "Select County", choices = NULL),
      selectizeInput("data3", "Select City", multiple = TRUE, choices = NULL),
      selectizeInput("data4", "Select Demo", choices = c("All", unique(df$demo))),
      selectizeInput("data5", "Select Status", choices = c("All", unique(df$status))),
      sliderInput("age", label = h3("Select Age Range"), 18,
                  35, value = c(18, 20), round = TRUE, step = 1),
      sliderInput("score1", label = h3("Select Score1 Range"), min = 0,
                  max = 100, value = c(20,80)),
      conditionalPanel(condition = "input.mydata=='df'",
                       sliderInput("score2", label = h3("Select Score2 Range"), min = 0, max = 100, value = c(20,80))
      ),
      prettyCheckboxGroup("phones", h3("Only Include Valid Phone Numbers?"), selected = "Yes", choices = list("Yes")),
      downloadButton("download", "Download Data")
    ),
    mainPanel(
      DTOutput("table")
    )
  )
)

    server <- function(input, output, session){
  
  mydf <- reactive({get(input$mydata)})
  
  observeEvent(input$data1, {
    df <- mydf()
    #if (input$data1 != "All") {
    updateSelectizeInput(session, "data2", "Select County", server = TRUE, choices = c("All", unique(df$county[df$state == input$data1])))
    # } else {
    #   updateSelectizeInput(session, "data2", "Select County", server = TRUE, choices = c("All", unique(df$county)))
    # }
  }, priority = 2)
  
  observeEvent(c(input$data1, input$data2), {
    df <- mydf()
    if (input$data2 != "All") {
      updateSelectizeInput(session, "data3", "Select City", multiple = TRUE, server = TRUE, choices = c("All", unique(df$city[df$county == input$data2])))
    } else {
      #if (input$data1 != "All") {
      updateSelectizeInput(session, "data3", "Select City", multiple = TRUE, server = TRUE, choices = c("All", unique(df$city[df$state == input$data1])))
      # } else {
      #   updateSelectizeInput(session, "data3", "Select City", server = TRUE, choices = c("All", unique(df$city)))
      # }
    }
  }, priority = 1)
  
  filtered_data <- reactive({
    temp_data <- mydf()
    if (input$data1 != "All") {
      temp_data <- temp_data[temp_data$state == input$data1, ]
    }
    if (input$data2 != "All") {
      temp_data <- temp_data[temp_data$county == input$data2, ]
    }
    if (input$data3 != "All") {
      temp_data <- temp_data[temp_data$city %in% input$data3, ]
    }
    if (input$data4 != "All") {
      temp_data <- temp_data[temp_data$demo == input$data4, ]
    }
    if (input$data5 != "All") {
      temp_data <- temp_data[temp_data$status == input$data5, ]
    }
    
    df2 <- temp_data %>% dplyr::filter(age >= input$age[1] &
                                         age <= input$age[2] &
                                         score1 >= input$score1[1] &
                                         score1 <= input$score1[2])
    if (input$mydata=="df") df2 <- df2 %>% dplyr::filter(score2 >= input$score2[1] & score2 <= input$score2[2])
    
    df3 <- if (is.null(input$phones)) df2 else df2 %>%  dplyr::filter(!is.na(phone))
    df3 %>% dplyr::select(unique_id, first_name, last_name, phone)
  })
  
  output$table <- renderDT(
    filtered_data()
  )
  
  output$download <- downloadHandler(
    filename = function() {
      paste("universe", "_", date(), ".csv", sep="")
    },
    content = function(file) {
      write.csv(filtered_data() %>% distinct_all(), file, row.names = FALSE)
    }
  )
  
}
    
    shinyApp(ui, server)

Solution

  • Try this

    library(dbplyr)
    library(dplyr)
    library(shiny)
    library(shinyWidgets)
    library(DT)
    
    df <- read.csv('https://raw.githubusercontent.com/datacfb123/testdata/main/sampleset_df.csv')
    df2 <- read.csv('https://raw.githubusercontent.com/datacfb123/testdata/main/sampleset_df.csv')
    df2$unique_id <- df2$unique_id*2  ##  just to check if switching works
    
    ui <- fluidPage(
      titlePanel("Sample"),
      sidebarLayout(
        sidebarPanel(
          radioButtons("mydata", label = "Choose dataframe", choices = c("df","df2"), inline=TRUE),
          selectizeInput("data1", "Select State", choices = c(unique(df$state))),
          selectizeInput("data2", "Select County", choices = NULL),
          selectizeInput("data3", "Select City", choices = NULL, multiple = TRUE),
          selectizeInput("data4", "Select Demo", choices = c("All", unique(df$demo))),
          selectizeInput("data5", "Select Status", choices = c("All", unique(df$status))),
          sliderInput("age", label = h3("Select Age Range"), 18,
                      35, value = c(18, 20), round = TRUE, step = 1),
          sliderInput("score1", label = h3("Select Score1 Range"), min = 0,
                      max = 100, value = c(20,80)),
          conditionalPanel(condition = "input.mydata=='df'",
                           sliderInput("score2", label = h3("Select Score2 Range"), min = 0, max = 100, value = c(20,80))
                           ),
          prettyCheckboxGroup("phones", h3("Only Include Valid Phone Numbers?"), selected = "Yes", choices = list("Yes")),
          downloadButton("download", "Download Data")
        ),
        mainPanel(
          DTOutput("table")
        )
      )
    )
    
    server <- function(input, output, session){
      
      mydf <- reactive({get(input$mydata)})
      
      observeEvent(input$data1, {
        df <- mydf()
        #if (input$data1 != "All") {
          updateSelectizeInput(session, "data2", "Select County", server = TRUE, choices = c("All", unique(df$county[df$state == input$data1])))
        # } else {
        #   updateSelectizeInput(session, "data2", "Select County", server = TRUE, choices = c("All", unique(df$county)))
        # }
      }, priority = 2)
    
      observeEvent(c(input$data1, input$data2), {
        req(mydf())
        df <- mydf()
        if (input$data2 != "All") {
          updateSelectizeInput(session, "data3", "Select City", server = TRUE, choices = c("All", unique(df$city[df$county == input$data2])))
        } else {
          #if (input$data1 != "All") {
            updateSelectizeInput(session, "data3", "Select City", server = TRUE, choices = c("All", unique(df$city[df$state == input$data1])))
          # } else {
          #   updateSelectizeInput(session, "data3", "Select City", server = TRUE, choices = c("All", unique(df$city)))
          # }
        }
      }, priority = 1)
    
      filtered_data <- reactive({
        req(input$data3)
        temp_data <- mydf()
        if (input$data1 != "All") {
          temp_data <- temp_data[temp_data$state == input$data1, ]
        }
        if (input$data2 != "All") {
          temp_data <- temp_data[temp_data$county == input$data2, ]
        }
        if (input$data3 != "All") {
          temp_data <- temp_data[temp_data$city %in% input$data3, ]
        }
        if (input$data4 != "All") {
          temp_data <- temp_data[temp_data$demo %in% input$data4, ]
        }
        if (input$data5 != "All") {
          temp_data <- temp_data[temp_data$status %in% input$data5, ]
        }
    
        df2 <- temp_data %>% dplyr::filter(age >= input$age[1] &
                                           age <= input$age[2] &
                                           score1 >= input$score1[1] &
                                           score1 <= input$score1[2])
        if (input$mydata=="df") df2 <- df2 %>% dplyr::filter(score2 >= input$score2[1] & score2 <= input$score2[2])
    
        df3 <- if (is.null(input$phones)) df2 else df2 %>%  dplyr::filter(!is.na(phone))
        df3 %>% dplyr::select(unique_id, first_name, last_name, phone)
      })
    
      output$table <- renderDT(
        filtered_data()
      )
    
      output$download <- downloadHandler(
        filename = function() {
          paste("universe", "_", date(), ".csv", sep="")
        },
        content = function(file) {
          write.csv(filtered_data() %>% distinct_all(), file, row.names = FALSE)
        }
      )
    
    }
    
    shinyApp(ui, server)