I tried to make an app where the user can set a range of value and see the results in a map and in the table. Here I used quakes
dataset to make a reproducible example.
The datatable
part works fine but not the leaflet
part which seems to show an unique marker. I know this is probably the min_depth
input I put in the reactive
function because the app crash when I play with. I can't figure out what to do.
Warning: Error in : Problem with `filter()` input `..1`.
x Input `..1` must be of size 988 or 1, not size 1000.
i Input `..1` is `obj$depth <= as.numeric(input$max_depth)`.
143: <Anonymous>
Warning: Error in : Problem with `filter()` input `..1`.
x Input `..1` must be of size 988 or 1, not size 1000.
i Input `..1` is `obj$depth <= as.numeric(input$max_depth)`.
53: <Anonymous>
Warning: Error in : Problem with `filter()` input `..1`.
x Input `..1` must be of size 988 or 1, not size 1000.
i Input `..1` is `obj$depth <= as.numeric(input$max_depth)`.
105: <Anonymous>
library(shiny)
library(DT)
library(dplyr)
library(leaflet)
library(leaflet.extras)
# Define UI
ui <- fluidPage(
# Application title
titlePanel("Quakes Test"),
# Sidebar with numericInput for quakes depth range
sidebarLayout(
sidebarPanel(
numericInput(inputId = "min_depth", label = "Mininum depth", value = min(quakes$depth), min = min(quakes$depth), max = max(quakes$depth)),
numericInput(inputId = "max_depth", label = "Maximum depth", value = max(quakes$depth), min = min(quakes$depth), max = max(quakes$depth))
),
# Show a map
mainPanel(
fluidRow(
leafletOutput("mymap_occ", width = "98%", height = 500))
)
),
fluidRow(DT::dataTableOutput(outputId = "prop_table"))
)
server <- function(input, output) {
#filter terrains
depth_final <- reactive({
obj <- quakes
if (input$min_depth != "All") {
obj <- quakes %>%
filter(obj$depth >= as.numeric(input$min_depth)) %>%
filter(obj$depth <= as.numeric(input$max_depth))
}
})
output$prop_table <- renderDT({
datatable(depth_final(), extensions = 'Buttons', rownames = FALSE, escape = FALSE, selection = 'none')
})
observe({
leafletProxy("mymap_occ", data = depth_final()) %>%
removeMarker(layerId = "FOO") %>%
addCircleMarkers(lng = ~long, lat = ~lat, clusterOptions = markerClusterOptions(),
weight= 4, opacity = 1, color = "yellow", layerId = "FOO")
})
output$mymap_occ <- renderLeaflet({
leaflet(depth_final()) %>%
fitBounds(~min(long), ~min(lat), ~max(long), ~max(lat)) %>%
addProviderTiles(providers$Esri.WorldImagery, group = "Vue satellite") %>%
addProviderTiles(providers$Stamen.TonerLabels, group = "Vue satellite")
})
}
# Run the application
shinyApp(ui = ui, server = server)
There are two issues with your code:
The error message results from using obj$depth
in the filter statement. Simply use depth
. By using obj$depth
you are referring to the depth
in the original obj
. While this works in the first filter it is not recommended to do so. In the second filter however you already dropped some rows, hence you got an error message as obj$depth
refers to depth
column in the unfiltered df.
Only one marker shows up because you use layerID
instead of group
. See here on the difference between the two concepts.
Try this:
server <- function(input, output) {
#filter terrains
depth_final <- reactive({
obj <- quakes
if (input$min_depth != "All") {
obj <- quakes %>%
filter(depth >= as.numeric(input$min_depth)) %>%
filter(depth <= as.numeric(input$max_depth))
}
obj
})
output$prop_table <- renderDT({
datatable(depth_final(), extensions = 'Buttons', rownames = FALSE, escape = FALSE, selection = 'none')
})
observe({
leafletProxy("mymap_occ", data = depth_final()) %>%
clearGroup(group = "FOO") %>%
addCircleMarkers(lng = ~long, lat = ~lat, clusterOptions = markerClusterOptions(),
weight= 4, opacity = 1, color = "yellow", group = "FOO")
})
output$mymap_occ <- renderLeaflet({
leaflet(depth_final()) %>%
fitBounds(~min(long), ~min(lat), ~max(long), ~max(lat)) %>%
addProviderTiles(providers$Esri.WorldImagery, group = "Vue satellite") %>%
addProviderTiles(providers$Stamen.TonerLabels, group = "Vue satellite")
})
}