I have a sample data set with 4 columns
- Year_of_connection
- country
- Method_of_connection
- User_Counts
I am trying to create a dashboard using Shiny where the user is requested to input the year drop down list and click the submit button. Upon clicking submit the output should be a leaflet map only for the year selected and reflecting User_counts from various countries
I followed the steps of getting the shapefile , ShapepolygonDataFrame using the maps package and then am trying to merge the shapefile with the dataframe - the dataframe is generated when user selects a set of specific dates only.
However, when I plot the map, it displays incorrect country names and values and this is very random. For an example from the data set if you select 2018 then all values are displayed correctly, but the moment you select 2019 or 2020 then incorrect country names and values get assigned to the poloygon.
What am I doing wrong or missed ?
I tried referencing Reactive Shiny Map Spatial Data Frame , Leaflet incorrect values for country , also value assigned to wrong country , followed the instructions, however I was not successful. I have included the image of the output, you can observe that its plotting the correct country polygons for which data exists but the country name and value from dataset is incorrect.
I will really appreciate any help
here is the code:
library(shiny)
library(shinydashboard)
library(lubridate)
library(sp)
library(sf)
library(leaflet)
library(stringr)
library(dplyr)
library(maps)
library(maptools)
#Read the file
my_data <- read.csv(file.choose(),header = T)
my_data$YEAR_OF_CONNECTION <- strptime(my_data$YEAR_OF_CONNECTION,"%Y")
my_data$YEAR_OF_CONNECTION <- as.numeric(format(my_data$YEAR_OF_CONNECTION,"%Y"))
print(my_data)
print(class(my_data$YEAR_OF_CONNECTION))
# Define UI
ui <- navbarPage("Cell Connectivity",
tabPanel("Country based Cellular Connections",
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "val",
label = "Select time period:",
choices = 2014:2021
),
br(),
br(),
submitButton("Submit")
),
#
mainPanel(
leafletOutput("map")
)
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
selected <- reactive({
fildata <- filter(my_data,my_data$YEAR_OF_CONNECTION == input$val)
fildata
# my_data[my_data$YEAR_OF_CONNECTION == input$val,]
#
# print(class((input$val)))
# print(input$val)
})
output$map <- renderLeaflet({
# Use leaflet() here, and only include aspects of the map that
# won't need to change dynamically (at least, not unless the
# entire map is being torn down and recreated).
leaflet() %>%
addProviderTiles("CartoDB.Positron")
})
observe({
if(!is.null(input$val)){
#t2@data <- left_join(t2@data, selected (), by="country")
worldmap <- map("world", fill=TRUE, plot=FALSE)
IDs <- sapply(strsplit(worldmap$names, ":"), function(x) x[1])
worldmap_poly <- map2SpatialPolygons(worldmap, IDs=IDs, proj4string=CRS("+proj=longlat +datum=WGS84"))
worldmap_poly_sp <- SpatialPolygonsDataFrame(worldmap_poly,
data.frame(IDs=names(worldmap_poly),
stringsAsFactors=FALSE), FALSE)
##subset the SpatialpolygonDataFrame only for country of interest
t2 <- subset(worldmap_poly_sp, IDs %in% selected()$country)
t2@data <- inner_join(t2@data, selected(), by=character(),copy = TRUE)
# t3 <- merge(t2, selected(),by.x="country",by.y="country",all.y= TRUE)
leafletProxy("map", data = t2 ) %>%
#addTiles() %>%
clearShapes() %>%
addPolygons(data = t2,
#fillColor = "Green",
fillOpacity = 0.7,
#color = "Blue", weight = 2,
popup = ~ paste0("USER_COUNTS: ", as.character(selected()$USER_COUNTS),
"<br>","<b>",
"COUNTRY:",as.character(selected()$country)))
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
Problem solved! I was able to reference post on stackoverflow Incorrect Labels Leaflet Map Polygons in R Shiny
I made the changes to my code, rather than merging the entire subset of the SpatialpolygonDataFrame containing countries of interest, I merged them with shapefile@data attribute (where shapefile is your shapefile and @data is part of the large shapefile). Then I assigned the merged component (Shapefile@data and user's selected data frame) back to the shapefile@data attribute of the original subseted SpatialpolygonDataFrame. Thus the originally subseted data frame now contains the correct label values .
Here are the code changes
BEFORE
t2@data <- inner_join(t2@data, selected(), by=character(),copy = TRUE)
AFTER
t3 <- merge(t2@data, selected(),by.x="IDs",by.y="country",all.y= TRUE)
t2@data <- t3
leafletProxy("map", data = t2 ) %>%
addTiles() %>%
clearShapes() %>%
addPolygons(data = t2,
#fillColor = "Green",
fillOpacity = 0.7,
#color = "Blue", weight = 2,
popup = ~ paste0("USER_COUNTS: ", as.character(t2@data$USER_COUNTS),
"<br>","<b>",
"COUNTRY:",as.character(t2@data$IDs)))
Here is the correct output with country labels and values.
Full credit to the idea present in the post Incorrect Labels Leaflet Map Polygons in R Shiny