在多个地块上的 Shiny Dashboard 中实现搜索功能

Implement Search Function in Shiny Dashboard on multiple plots

下面是闪亮的仪表板。有一个名为 SalesDF 的假设 Dataframe。它有城市、SalesCount、Qualifications 和 Age 列。

城市列的观察结果为大写。即“内罗毕”、“蒙巴萨”、“蒙巴萨”、“蒙巴萨”、“内罗毕”。

我希望我的 shinydashboard 根据城市搜索重新填充图表。如果用户使用“Nairobi”、“NAIROBI”或“NaIROBI”进行搜索,它会根据该搜索功能加载两个图表。最后,如果城市不存在,它应该 return 一个错误,例如“找不到城市”。

我该怎么做?

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)

下面是一些实现所需反应表达式并使用 toupper 强制用户输入大写的代码。如果没有找到城市,它还会显示一条消息。这是使用 shiny::validate 函数完成的。编辑为包括在用户未选择任何内容时显示完整图表。

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)