在 Shiny 中使用 selectInput 从 API 过滤数据

filter data from API using selectInput in Shiny

很多天以来我无法解决我的问题。一开始我从 API 获取一些数据(我每 5 秒刷新一次 API 调用以获取最新数据)。数据包含有关位置(纬度和经度)的信息以及写入这些位置的一些标签。我想创建一个 selectInput 对象并使用分配给标签的选项。如果我从 selectInput 对象的下拉列表中选择一个标签,我想在 5 秒内同时过滤下一个 API 调用。主要任务是在从下拉列表中选择一个值后过滤地图上可见的数据。

标签每隔几分钟更改一次,但位置坐标每隔几秒更改一次。

我在服务器端使用 renderUI,在 UI 端使用 uiOutput。期待您的帮助,谢谢。

library("httr")
library("jsonlite")
library("shiny")
library("leaflet")
library("dplyr")


ui <- shinyUI(fluidPage(
  navbarPage("Title",
             tabPanel("MAP",

                      leafletOutput("mymap", width = "auto", height = "560px")
             )
  ),
  uiOutput("loc")
  )
  )

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

  autoInvalidate <- reactiveTimer(5000)

  reData <- eventReactive(autoInvalidate(), {

    # # example data
    # lat <- c(20.51,20.52,20.65)
    # long <- c(10.33,13.43,23.54)
    # labels <- c('John','Peter','Jolie')
    # data <- data.frame(lat, long, labels)

    # API call #1 response
    get_data <- GET(call1)
    get_data_text <- content(get_data, "text")
    get_data_json <- fromJSON(get_data_text, flatten = TRUE)
    data <- get_data_json$result

    # handling empty API response
    while(class(data) == "list"){
      Sys.sleep(1)
      get_trams <- GET(call1)
      get_data_text <- content(get_data, "text")
      get_data_json <- fromJSON(get_data_text, flatten = TRUE)
      data <- get_data_json$result
    }


    # saving data before filtering - purpose of getting labels for the drop-down list and
    # creating a sorted list for selectInput function
    list_of_vals <- data
    uniq_first_lines <- c("all", unique(as.character(sort(as.numeric(list_of_vals$FirstLine)))))
    sorted_factor <- factor(uniq_first_lines, levels=uniq_first_lines)
    my_new_list <- split(uniq_first_lines, sorted_factor)


    # filter data
    if(input$loc != "all") {
      data <- data %>%
      filter_at(
        vars(one_of("FirstLine")),
        any_vars(.==input$loc))
    }

    rownames(data) <- NULL


    return(list(data=data, my_new_list=my_new_list))
  }, ignoreNULL = FALSE)


  output$loc <-renderUI({
    selectInput("loc", label = h4("Choose location"),
                choices = reData()$my_new_list ,selected = "all"
    )
  })


  points <- eventReactive(autoInvalidate(), {
    cbind(reData()$trams_data$Lon, reData()$trams_data$Lat)
  },ignoreNULL = FALSE)

  labels <- eventReactive(autoInvalidate(), {
    paste("line: ", reData()$trams_data$FirstLine)
  },ignoreNULL = FALSE)

  output$mymap <- renderLeaflet({
    leaflet() %>%
      addTiles()
  })

  observeEvent(autoInvalidate(), {
    leafletProxy("mymap") %>%
      clearMarkers() %>%
      addMarkers(
        data = points(),
        label = labels()
      )
  },ignoreNULL = FALSE)
})


shinyApp(ui, server)

我将使用一个最小示例和您提供的小型数据集。您可以根据需要调整我的示例,但我想向您展示反应式数据集的使用,以便您可以按标签进行过滤。

您是否正在寻找类似的东西:

library("httr")
library("jsonlite")
library("shiny")
library("leaflet")
library("dplyr")


# # example data
lat <- c(20.51,20.52,20.65)
long <- c(10.33,13.43,23.54)
labels <- c('John','Peter','Jolie')
data <- data.frame(lat, long, labels)


ui <- shinyUI(fluidPage(
  navbarPage("Title",
             tabPanel("MAP",
                      leafletOutput("mymap", width = "auto", height = "560px")
             )
  ),
  uiOutput("labels")
)
)

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


  output$labels <- renderUI({
       selectInput("labels", label = h4("Choose label"), choices = c("John", "Peter", "Jolie") ,selected = "John")

  })


  reData <- reactive({

    autoInvalidate <- reactiveTimer(5000)
    data <- data %>% dplyr::filter(input$labels == labels)

  })

  output$mymap <- renderLeaflet({
    leaflet(reData()) %>%
      setView(10, 20, zoom = 5) %>%
      addTiles() %>%
    addMarkers()
  })

#  observeEvent(autoInvalidate(), {
 #   leafletProxy("mymap") %>%
  #    clearMarkers() %>%
   #   addMarkers(
    #    data = points(),
     #   label = labels()
    #  )
#  },ignoreNULL = FALSE)


})


shinyApp(ui, server)