robert mulloy
robert mulloy

Reputation: 21

Shiny dropdown menu selection to filter a dataframe

I've got a question about Shiny, dropdown selections and filtering on that selection.

I have the dropdown list; easy enough but I'm having a difficult time taking that input and then filtering a dataframe based on that value. I keep getting "can only be done inside a reactive expression" errors.

For the Shiny App

library(dtplyr)
library(dplyr)
library(shiny)
library(shinyWidgets)
library(shinydashboard)

citylist <- data.frame("City" = c("Abilene", "Amarillo", "Omaha"))
wxdata <- data.frame("City" = c("Abilene", "Abilene", "Abilene", "Abilene", "Amarillo", "Amarillo", "Amarillo", "Amarillo", "Omaha", "Omaha", "Omaha", "Omaha"), "Temp" = c(12,15, 16,17,32,34,36,37,8,6,3,4))

ui <- fluidPage(
  inputPanel(selectInput("PlotCity",
                         label = "Select City",
                         choices = citylist)),
  
  plotOutput(outputId = 'minplot')
)

server <- function(input, output) {
 
  plotmin <- as.data.frame(subset(wxdata, City == input$PlotCity))

  minplot <- ggplot(data from plotmin DF)

}

# Run the application 
shinyApp(ui = ui, server = server)

I'm stuck on this and I'm willing to bet its a simple solution but I can't figure out the "reactive" thing.

Anyway thanks for any help

Rob

Upvotes: 2

Views: 3623

Answers (1)

Richie Cotton
Richie Cotton

Reputation: 121057

citylist ought to be a vector, not a data frame. Try defining citylist <- unique(wxdata$City) after you define wxdata.

I think the reactive error is because you haven't called renderPlot().

I find Shiny apps easiest to reason about if you separate the logic for drawing plots (or other calculations) into their own functions, so that the server code is only about rendering.

Here's my version of your dashboard.

library(dplyr)
library(ggplot2)
library(shiny)

wxdata <- data.frame(
  City = rep(c("Abilene", "Amarillo", "Omaha"), each = 4), 
  Temp = c(12, 15, 16, 17, 32, 34, 36, 37, 8, 6, 3, 4)
)
citylist <- unique(wxdata$City)

draw_plot <- function(city_to_filter_by) {
  filtered_wx <- wxdata %>%
    filter(City == !!city_to_filter_by)
  ggplot(filtered_wx, aes(Temp)) +
    geom_histogram()
}

ui <- fluidPage(
  inputPanel(
    selectInput(
      "PlotCity",
      label = "Select City",
      choices = citylist
    )
  ),
  plotOutput('minplot')
)

server <- function(input, output) {
  output$minplot <- renderPlot(draw_plot(input$PlotCity))
}

shinyApp(ui = ui, server = server)

Upvotes: 4

Related Questions