I am using Shiny and i have an issue with Leaflet.
What I want to do : The ultimate goal of my project is to select specific french counties. When those counties are selected, I create on-the-go (by merging) the file of shapes (that is necessary to plot the map on Leaflet) and the database containing all kind of public data (such as number of population, ect...) that correspond only to those specific counties.
My Issue : I know that the "merging" is done well, inside the Shiny App. BUT, my Outputmap doesn't want to work.
Details: Actually, I launched my "merging and plotting" on another .R script, and it work perfectly well (i only defined "manually" before launching the script what counties i wanted to plot). On my ShinyApp, this choice is taken by the input$choix_depa
variable.
Now a little bit of code. I have three scripts that react simultaneously : global.R ui.R and server.R (this is how Shiny works as you know). For the global.R (i only show here the"interessant" part) i load the database file containing the data for all counties (not shape files ! only data)
setwd('path')
data_BP = read_delim(
"database-allFrance.csv",
",",
na = "empty",
quote = "\"",
locale = locale(encoding = 'windows-1252')
)
On the ui.R (user interface) I have my "selection" of counties :
shinydashboard::tabItem(tabName= "Departements", class = 'active',
shiny::fluidPage(
shiny::absolutePanel(
draggable = FALSE,
fixed = TRUE,
top = 60, left = "auto", right = 20, bottom = "auto",
width = 330, height = "auto",
wellPanel(
shiny::h4("Départements"),
selectizeInput(inputId = "choix_depa", label = "",multiple=TRUE,
choices = seq(1,95))
)
), textOutput("answ")
),
The selectizeInput
is the button that allows the user to choose one or more counties in the seq(1,95)
.
And on the server.R (most important) I have:
ObserveEvent(input$choix_depa, {
output$answ<- renderText({
paste("You choose", input$choix_depa)
})
choice=input$choix_depa
print(choice)
for (i in input$choix_depa){
setwd(sprintf("path/county%s",i))
assign(paste("contouriris",i,sep=""), readOGR(
dsn = "contours_IRIS_BP.shp",
layer = "contours_IRIS_BP",
verbose = FALSE,
encoding = 'UTF-8'
))
print("modification en cours...")
assign(paste("data_BP",i,sep=""),subset(data_BP,as.numeric(as.character(data_BP$IRIS))>=as.numeric(i)*10000000&as.numeric(as.character(data_BP$IRIS))<(as.numeric(i)+1)*10000000))
}
if (length(input$choix_depa)>=1){
contours_IRIS <- get(paste("contouriris",input$choix_depa[1],sep=""))
data_BPC <- get(paste("data_BP",input$choix_depa[1],sep=""))
}
if (length(input$choix_depa)>1){
for (i in input$choix_depa[-1]){
contours_IRIS <- rbind(contours_IRIS,get(paste("contouriris",i,sep="")))
data_BPC <- rbind(data_BPC,get(paste("data_BP",i,sep="")))
}
}
map_WGS84 = spTransform(
merge(contours_IRIS, data_BPC, by.x = 'CODE_IRIS', by.y = 'IRIS'),
CRS("+init=epsg:4326")
)
# Correction of names :
names(map_WGS84)[names(map_WGS84) == "TYP_IRIS.x"] <- "TYP_IRIS"
})
You don't have to understand all this code.
You have the choice of counties in the input$choix_depa
variable.
This kind of variable is like ["4',"87"] if the counties 4 and 87 are selected by the user inside the app (for example).
I have on my computer 95 folders (one for each county). I use setwd to go to the right path, and I load the "shape file" in the contouririsK
with K the number of the county. In the previous example we would have contouriris4
and countouriris87
.
Those shape files are merged in contours_IRIS
.
I do the same thing with the data file, i took the data that is associated with those counties and i merge all the files in the data_BPC
. (if i take the previous example, we would have data_BPC4
and data_BPC87
that are merged in the data_BPC
).
After this, i use both variables(contours_IRIS
and data_BPC
) to create the map_WGS84
variable (i will need this variable for the LeafletOutput) .
OK so, after this choice of counties that i want to plot on the Leaflet map I have to choose the variables in which i am interested in. This is another menu, i don't write here all the code (not necessary)
observeEvent(input$choix_var_pop, {XXXXXXXXX})
The choice of the variable that the user want to plot on the map is in input$choix_var_pop
.
After this, i create specific variables that i will need on my LeafletMap :
label_reac_pop = reactive({as.character(input$choix_var_pop)})
var_reac_pop = reactive({dico$Variable[dico$Label == label_reac_pop()]})
col_reac_pop = reactive({as.character(dico$Couleur[dico$Label == label_reac_pop()])})
type_reac_pop = reactive({as.character(dico$Type[dico$Label == label_reac_pop()])})
unite_reac_pop = reactive({ifelse(as.character(type_reac_pop()) == "Pct", " %", "")})
Lastly, i plot the LeafletMap: (i have greatly reduced for clarity the code below)
output$Carte_Pop <- renderLeaflet({
label = label_reac_pop()
var = var_reac_pop()
col = col_reac_pop()
type = type_reac_pop()
unite = unite_reac_pop()
values_var = map_WGS84@data[,var]
leaflet(map_WGS84) %>%
addProviderTiles("CartoDB.PositronNoLabels") %>%
addProviderTiles("CartoDB.PositronOnlyLabels") %>%
setView(lng = 2.468738900000062, lat = 49.19316, zoom = 7) %>%
clearShapes() %>%
clearPopups() %>%
})
Of course, i call this output$Carte_Pop in the ui.R file, in order to plot it.
OKAY so, what is the result of all of this ?
As I mentionned before, this script work when it is "alone", and when there is no input$choix_depa
(i manually enter the counties that i want to merge in an array, and they are merged well, and the map is well plotted).
BUT when i am on the ShinyApp with my 3 scripts (global.R, ui.R and server.R), the "new" value of the "map" is not "saved".
For example: if i choose (on my alone-script) to merge and plot counties number 4 and 87, it works fine (the merging part and the plotting part work well) !
BUT when i launch my ShinyApp, when i choose the counties that i want (for example 13 and 91 ), EVEN IF the contours_IRIS
and the data_BPC
are well merged with the data corresponding to 13 and 91, so i suppose that the map_WGS84
that is created INSIDE the observeEvent(input$choix_depa....)
is CORRESPONDING WELL to 13 and 91, when I ask for plotting a specific variable (after the observeEvent(input$choix_var_pop)
the map that is plotted IS NOT the map created before, but the "older MAP" with 4 and 87 (the map that was created on the "alone-script"... before launching the ShinyApp !). But i am sure at 100% that the MAP created inside of the observeEvent(input$choix_depa .... )
is good. But, the "value" of this MAP is not "saved" by ShinyApp (they use instead the old value for the MAP...).
So my question is : what should i do in order to plot the GOOD NEW MAP (created inside the APP) instead of the OLD BAD ONE (created BEFORE and OUTSIDE the app...) ?
This issue is a little bit "complex", if you have any question please feel free to ask !
Thank you ! :)