过滤器不响应我闪亮的应用程序中的应用和清除按钮

filter does not respond to apply and clear buttons in my shiny app

我正在构建一个闪亮的应用程序以在地图上可视化酒店(使用传单包)。我有一个下拉列表,我可以加载数据的一个子集。除此之外,我还想在左上角建立一个过滤按钮,我可以用它来按年份进一步过滤数据。

我希望过滤器仅在我单击 apply 按钮时响应。另外,我想在单击 clear 按钮后清除过滤器。

下面是我闪亮的应用程序代码。我的 applyclear 按钮似乎不起作用。我的地图每年 select 从过滤器下拉列表中刷新一次。我希望它仅在单击 apply 按钮后刷新。过滤器也不响应 'clear'。我花了几个小时,但无法弄清楚为什么。有谁知道我做错了什么。

这是一个非常简化的版本。我的实际应用程序要复杂得多。在下拉按钮中有多个过滤器。

library(shiny)
library(leaflet)
library(shinyjs)
library(shinyWidgets)
library(dplyr)


df <- read.table(text = "Name Year Value longitude  latitude
                         A   2020  12    -106.50645 35.06745
                         B   2020  33    -116.00994 36.21834
                         C   2020  44    -115.24685 36.29460
                         A   2019  55    -115.24685 35.06745
                         B   2019  22    -118.18642 33.98881
                         C   2019  11    -111.83064 35.06745", 
                     header = TRUE)


ui <- fluidPage(
    
    selectizeInput(inputId = 'hotel', label='Hotel Type:',
                   choices = c('A', 'B', 'C'),
                   multiple=TRUE,
                   options = list(
                       maxItems = 1,
                       placeholder = '',
                       onInitialize = I("function() { this.setValue(''); }"))),
    actionButton("load", "load"),
    
    
    div(id = 'map_filter',
        dropdown(
            tags$h3("Filters"),
            selectizeInput(inputId = 'year', label='Choose Year:',
                           choices = c(2020,2019),
                           multiple=TRUE,
                           options = list(
                               maxItems = 2,
                               placeholder = '',
                               onInitialize = I("function() { this.setValue(''); }"))),
            #uiOutput('map_zipcode_prod2ui') ,
            # column(width=1, offset = 1, actionButton(inputId='map_zipcode_applyProductFilter',
            #                                          label='Apply Filter', style = 'margin-top:25px') )
            actionBttn(
                inputId = 'applyFilter',
                label = "Apply",
                style = "gradient",
                color = "danger",
                icon = icon("") ) ,
            actionBttn(
                inputId = 'clearFilter',
                label = "Clear",
                style = "gradient",
                color = "danger",
                icon = icon("") ) ,
            style = "unite", icon = icon("filter"),
            status = "danger", width = "300px"
        )  #dropdown
    ), #div
    
    
    leafletOutput("mymap")
    
)

server <- function(input, output, session) {
    
    df1 = eventReactive (input$load, {
        
        df %>% filter(Name == input$hotel)
    })
    
    df2 = reactive({
        if (length(input$year)==0) {
            df2 = df1()
        } else {
            df2 = df1() %>% filter(Year %in% input$year)
        }
    })
    
    # clear all filters
    observeEvent(input$clearFilter, {
        reset("map_filter")
    })
    
    
    observeEvent(c(input$load,input$applyFilter), ignoreInit = T, ignoreNULL = T, {
        
        output$mymap <- renderLeaflet({
            map <- leaflet()  %>%
                addProviderTiles("OpenStreetMap.Mapnik") %>% 
                addCircleMarkers( data = df2(),
                                  #group = 'Data Markers 1',
                                  lng = ~longitude,
                                  lat = ~latitude,
                                  radius = 10,
                                  stroke = F,
                                  fillOpacity = 0.9,
                                  color = 'red')
            
        })
    })
}

shinyApp(ui, server)

试试这个

server <- function(input, output, session) {
  
  df1 = eventReactive (input$load, {
    df %>% filter(Name == req(input$hotel))
  })
  
  df2 = reactive({
    req(input$year)
    if (length(input$year)==0) {
      df2 = df1()
    } else {
      df2 = df1() %>% filter(Year %in% input$year)
    }
  })
  
  # clear all filters
  observeEvent(input$clearFilter, {
    output$mymap <- renderLeaflet({
      return(NULL)
    })
    #reset("map_filter")
  })
  
  
  observeEvent(input$applyFilter, ignoreInit = T, ignoreNULL = T, {
    req(input$load,df2())
    output$mymap <- renderLeaflet({
      map <- leaflet()  %>%
        addProviderTiles("OpenStreetMap.Mapnik") %>% 
        addCircleMarkers( data = df2(),
                          #group = 'Data Markers 1',
                          lng = ~longitude,
                          lat = ~latitude,
                          radius = 10,
                          stroke = F,
                          fillOpacity = 0.9,
                          color = 'red')
      
    })
  })
}

shinyApp(ui, server)

这是一种方法 - 希望对您有所帮助。

您可以将地图存储在 reactiveVal 中。然后,您使用加载更新地图或应用过滤器按钮。否则地图不会改变。

会考虑使用 updateSelectizeInput 清除过滤器。

编辑: 根据评论,df1df2 没有合并。

server <- function(input, output, session) {

  map <- reactiveVal(NULL)

  df1 = reactive({
    req(input$hotel)
    filter(df, Name == input$hotel)
  })
  
  df2 = reactive({
    if (length(input$year)==0) {
      df2 = df1()
    } else {
      df2 = df1() %>% filter(Year %in% input$year)
    }
  })

  # clear all filters
  observeEvent(input$clearFilter, {
    updateSelectizeInput(session, inputId = 'year', selected = "")
  })

  output$mymap <- renderLeaflet({
    map()
  })

  observeEvent(c(input$load, input$applyFilter), ignoreInit = T, ignoreNULL = T, {
    map(leaflet()  %>%
      addProviderTiles("OpenStreetMap.Mapnik") %>%
      addCircleMarkers( data = df2(),
                        #group = 'Data Markers 1',
                        lng = ~longitude,
                        lat = ~latitude,
                        radius = 10,
                        stroke = F,
                        fillOpacity = 0.9,
                        color = 'red')
    )
  })

}