使用validate + need或eventReactive在Shiny中渲染传单

时间:2019-02-26 09:18:32

标签: r shiny leaflet

我正在尝试使用Leaflet库构建R Shiny Dashboard应用程序。在应用程序中,用户可以选择来源国家,目的地国家和产品。然后针对该特定输入组合对数据帧进行过滤。然后将所得数据帧传递给renderLeaflet,并将位置数据和详细信息显示给用户。

我的目标是仅在用户输入后创建过滤后的数据框时才渲染和显示传单图。我尝试为此同时使用validate + need和eventReactive。我现在已经在传单呼叫中添加了一些占位符数据。

eventReactive即使在用户选择输入后也不会在仪表板上返回任何传单地图。 eventReactive 为了验证+需要,甚至在用户选择输入之前就绘制并显示了传单地图和占位符数据。 enter image description here UI.R的代码:


sidebar <- shinydashboard::dashboardSidebar(
  selectizeInput(
    "srcLoc", label="Source Country", choices=locsAgg$SrcLocation, options=list(create=TRUE, maxItems=100, placeholder="Select a Country")
  ),
  selectizeInput(
    "destLoc", label="Destination Country", choices=locsAgg$SonLocation, options=list(create=TRUE, maxItems=100, placeholder="Select a Country")
  ),
  selectizeInput(
    "pdt", label="Product", choices=locsAgg$Pdt, options=list(create=TRUE, maxItems=100, placeholder="Select a Product")
  )
)

body <- shinydashboard::dashboardBody(
  tags$style(type = "text/css", "#map {height: calc(100vh - 80px) !important;}"),
  leafletOutput("map")
)


# Put them together into a dashboardPage
dashboardPage(
  dashboardHeader(title = "World Map"),
  sidebar,
  body
)

用于验证+需要的Server.R代码:

### Using valid and need --> plot still gets plotted

shinyServer<- function(input,output,session){
  updateSelectizeInput(session, "srcLoc", choices=locsAgg$SrcLocation, server=T)

  locsFil1 <-reactive({
    locsAgg %>% filter(SrcLocation %in% input$srcLoc)
  })

  observeEvent(input$srcLoc, {updateSelectizeInput(session, "destLoc", choices=locsFil1()$SonLocation, server=T)})

  locsFil2 <-reactive({
    locsFil1() %>% filter(SonLocation %in% input$destLoc)
  })

  observeEvent(input$destLoc, {updateSelectizeInput(session, "pdt", choices=locsFil2()$Pdt, server=T)})

  locsFil3 <-reactive({
    locsFil2() %>% filter(Pdt %in% input$pdt)
  })


  output$map <- renderLeaflet({
    validate(
      need(locsFil3(), "Select inputs")
    )
    m <- leaflet(options=leafletOptions(minZoom=1, maxZoom=5, zoomDelta=0.5)) %>% 
      addProviderTiles(providers$OpenStreetMap) %>% setView(lng=-93.85, lat=37.45, zoom=2)
    m <- addMarkers(m, lng=c(12,21) , lat=c(37,67))
  })

}

用于eventReactive的Server.R的代码:

# doesnt work and messes up filters as well

shinyServer<- function(input,output,session){
  updateSelectizeInput(session, "srcLoc", choices=locsAgg$SrcLocation, server=T)

  locsFil1 <-reactive({
    locsAgg %>% filter(SrcLocation %in% input$srcLoc)
  })

  observeEvent(input$srcLoc, {updateSelectizeInput(session, "destLoc", choices=locsFil1()$SonLocation, server=T)})

  locsFil2 <-reactive({
    locsFil1() %>% filter(SonLocation %in% input$destLoc)
  })

  observeEvent(input$destLoc, {updateSelectizeInput(session, "pdt", choices=locsFil2()$Pdt, server=T)})

  locsFil3 <-reactive({
    locsFil2() %>% filter(Pdt %in% input$pdt)
  })


  output$map <- eventReactive(locsFil3(), {
    renderLeaflet({

      m <- leaflet(options=leafletOptions(minZoom=1, maxZoom=5, zoomDelta=0.5)) %>% 
        addProviderTiles(providers$OpenStreetMap) %>% setView(lng=-93.85, lat=37.45, zoom=2)
      m <- addMarkers(m, lng=c(12,21) , lat=c(37,67))
    })
  }
  )
}

使用的软件包:在Global.R中定义:

packages = c("shiny",
             "shinydashboard",
             "dplyr",
             "openxlsx",
             "stringr",
             "readr",
             "tidyr",
             "leaflet",
             "geosphere")

如何更新传单图的server.R代码,使其仅在过滤的数据框可用后才呈现?谢谢!

1 个答案:

答案 0 :(得分:1)

没有数据集locsAgg很难帮助。

我会尝试

locsFil3 <- eventReactive(list(locsFil2(), input$pdt), {
  locsFil2() %>% filter(Pdt %in% input$pdt)
}, ignoreInit = TRUE)

output$map <- renderLeaflet({
  req(locsFil3())
  m <- leaflet(options=leafletOptions(minZoom=1, maxZoom=5, zoomDelta=0.5)) %>% 
    addProviderTiles(providers$OpenStreetMap) %>% setView(lng=-93.85, lat=37.45, zoom=2)
  addMarkers(m, lng=c(12,21) , lat=c(37,67))
})

locsFil3 <- reactive({
  locsFil2() %>% filter(Pdt %in% input$pdt)
})

 observeEvent(locsFil3(), {
   output$map <- renderLeaflet({
    m <- leaflet(options=leafletOptions(minZoom=1, maxZoom=5, zoomDelta=0.5)) %>% 
      addProviderTiles(providers$OpenStreetMap) %>% setView(lng=-93.85, lat=37.45, zoom=2)
    addMarkers(m, lng=c(12,21) , lat=c(37,67))
  })
}, ignoreInit = TRUE)

如果这不起作用,请提供locAggs(编辑您的问题,并粘贴dput(locsAgg)dput(head(locsAgg,20))的输出,如果足够的话)。