Lambo Lambo - 1 year ago 91
R Question

Change setView dynamically according to select box in R shiny app

I'm developing a leaflet map in R shiny. In this app I want the focus of the map to be changed whenever the lng and lat value in

setView()
is changed. The lng and lat values are based on what country I select from a drop down box. Previously I use static value for lng and lat in an
ifelse()
function and the app works. But now the problem is when I want to make things more generic: the lng and lat will be the mean of the longitude and latitude from a subset of the data with the chosen country, the app doesn't show map anymore (from my point of view the calculation seems right)

Below is the simplified and workable R script:

global.R:

library(devtools)
library(leaflet)
library(htmlwidgets)
library(shiny)
library(shinydashboard)
library(sp)
library(rworldmap)
library(RCurl)
library(ggmap)

df <- read.csv(url("https://docs.google.com/spreadsheets/d/1rrEJiuxr4nafTqUQBlPpUdGwvGeGtBJExlPJdday2uw/pub?output=csv"),
header = T,
stringsAsFactors = F)
df$Time <- as.Date(df$Time, "%d/%m/%Y")


ui.R

header <- dashboardHeader(
title = 'Shiny Memery'
)
body <- dashboardBody(
fluidRow(
tabBox(
tabPanel("My Map", leafletOutput("mymap",height = 550)),
width = 700
))
)
dashboardPage(
header,
dashboardSidebar(
sliderInput('Timeline Value','Time line',min = min(df$Time),
max = max(df$Time),
value = c(min(df$Time), min(df$Time)+10)),
selectInput("select_country", label = "Select Country",
choices = NULL,
selected = NULL)
),
body
)


server.R

shinyServer(function(input, output, session) {

dfs <- reactive({
tmp <- subset(df, df$Time <= input$`Timeline Value`[2] & df$Time >= input$`Timeline Value`[1])
tmp
})

part_choices <- reactive({
as.list(c("All", unique(as.character(dfs()$Country))))
})

observe({
updateSelectInput(session, "select_country", choices=part_choices())
})

output$mymap <- renderLeaflet({
lng <- ifelse(input$select_country == "All", mean(dfs()$lon),
mean(subset(dfs(), Country %in% input$select_country)$lon)
)
lat <- ifelse(input$select_country == "All", mean(dfs()$lat),
mean(subset(dfs(), Country %in% input$select_country)$lat)
)

m <- leaflet(dfs()) %>%
addTiles(
) %>%
setView(lng, lat, zoom = 5) %>%
addMarkers(~lon, ~lat,
clusterOptions = markerClusterOptions())
})
})


You will see in the server.R part I use
ifelse()
to change the lng and lat value that later can be used in
setView()
function. After I changed the else argument into a calculation the app doesn't work anymore.

Really appreciate if someone can tell me where I was wrong.

Thanks in advance.

Answer Source

In your ui.R, try changing your country input to

selectInput("select_country", label = "Select Country", 
            choices = "All", 
            selected = "All")

My guess is that the ifelses do not return a number, given that input$select_country is initialized at NULL, which (for reasons that are unclear to me) causes both renderLeaflet and updateSelectInput not to run, preventing the country selector from being updated.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download