Below is the shiny Dashboard. There is a hypothetical Dataframe called SalesDF. It has columns city, SalesCount, Qualifications and Age.
The city column has observations as upper case. That is "NAIROBI", "MOMBASA", "MOMBASA","MOMBASA","NAIROBI".
I want my shinydashboard to re-populate the plots based on searching by city. If a user searches using either "Nairobi", or "NAIROBI", or "NaIROBI", it loads the two charts based on that search function. Finally, if the city is not present, it should return an error such as "City not found".
How do I go about that?
Code to the shinyDashboard
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
library(easypackages)
libraries("shiny","shinydashboard","tidyverse","lubridate", "plotly","Rcpp")
theme_set(theme_minimal())
# DF
city <- c("NAIROBI", "MOMBASA", "MOMBASA","MOMBASA","NAIROBI")
SalesCount <- c(34, 50, 23, 70, 33)
Qualifications <- c("More than one", "One","One", "More than one","One")
Age <- c(45, 50, 43, 44, 60)
SalesDF <- data.frame(city, SalesCount, Qualifications, Age)
city <- SalesDF$city
cityCountplot <- ggplot(SalesDF, aes(city, SalesCount)) +
geom_col()
cityCountplot
qualifyCountplot <- ggplot(SalesDF, aes(Qualifications, SalesCount)) +
geom_col()
qualifyCountplot
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Sales Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
# sliderInput("bins",
# "Number of bins:",
# min = 1,
# max = 50,
# value = 30)
sidebarMenu(
sidebarSearchForm(textId = "Search", buttonId = "searchTown",
label = "Search Town")
)
),
# Show a plot of the generated distribution
mainPanel(
tabsetPanel(
tabPanel("plot1", plotOutput("plot1")),
tabPanel("plot2", plotOutput("plot2"))
)
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
#plot1Output
output$plot1 <- renderPlot({
cityCountplot
})
#plot2Output
output$plot2 <- renderPlot({
qualifyCountplot
})
}
# Run the application
shinyApp(ui = ui, server = server)
Here's some code that implements the required reactive expression and uses toupper
to force the user input to upper case. It also displays a message if no city has been found. This is done using the shiny::validate
function. Edited to include showing the full graph if the user selects nothing.
library(tidyverse)
library(shiny)
library(shinydashboard)
library(lubridate)
theme_set(theme_minimal())
city <- c("NAIROBI", "MOMBASA", "MOMBASA","MOMBASA","NAIROBI")
SalesCount <- c(34, 50, 23, 70, 33)
Qualifications <- c("More than one", "One","One", "More than one","One")
Age <- c(45, 50, 43, 44, 60)
SalesDF <- data.frame(city, SalesCount, Qualifications, Age)
city <- SalesDF$city
cityCountplot <- ggplot(SalesDF, aes(city, SalesCount)) + geom_col()
cityCountplot
qualifyCountplot <- ggplot(SalesDF, aes(Qualifications, SalesCount)) + geom_col()
qualifyCountplot
ui <- fluidPage(
titlePanel("Sales Data"),
sidebarLayout(
sidebarPanel(
sidebarMenu(
sidebarSearchForm(textId = "Search", buttonId = "searchTown", label = "Search Town")
)
),
mainPanel(
tabsetPanel(
tabPanel("plot1", plotOutput("plot1")),
tabPanel("plot2", plotOutput("plot2"))
)
)
)
)
server <- function(input, output) {
filteredSales = reactive({ # Make a data frame that changes when the user chooses something
if (input$Search == '') { # Force "" to mean all cities
df = SalesDF
}
else {
df = SalesDF %>% dplyr::filter(city == toupper(input$Search))
}
df
})
filteredCityCountPlot = reactive({ # Make a count plot based on the filtered data frame
df = filteredSales()
ggplot(df, aes(city, SalesCount)) + geom_col()
})
filteredQualifyCountPlot = reactive({ # Make a qualification plot based on the filtered data frame
df = filteredSales()
ggplot(df, aes(Qualifications, SalesCount)) + geom_col()
})
output$plot1 <- renderPlot({ # render the count plot with an error if there is no data
validate(
need(nrow(filteredSales()) > 0, 'Please select a city')
)
filteredCityCountPlot()
})
output$plot2 <- renderPlot({ # render the qualification plot with an error if there is no data
validate(
need(nrow(filteredSales()) > 0, 'Please select a city')
)
filteredQualifyCountPlot()
})
}
shinyApp(ui = ui, server = server)