rshinyr-leafletr-mapview

Map average value on a Choropleth map


I am creating a shiny app that:

  1. Allows the user to upload a shapefile (sf_object) "filemap".
  2. Based on the uploaded shapefile, the user will then be able to select a column/variable of interest to plot a an average temperature value Choropleth/classification map (mapview).

The app loads fine with no errors however the map is I think only showing a single value (last value to be precise) on the map, however the shapefile consists of 40 years (year column )of monthly (month column) data.

I guess part of the problem is that mapview is not averaging point values (those at the same point) rather it's mapping points with the same location on top of each other.

How can I fix this ?

Sample Data:

 structure(list(Info = c(NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_), tmean = c(22.2395992279053, 22.7657985687256, 
    24.4260005950928, 19.601001739502, 17.5659999847412), CITYNAME = c("NORTH LAUDERDALE", 
    "NORTH LAUDERDALE", "NORTH LAUDERDALE", "NORTH LAUDERDALE", "NORTH LAUDERDALE"
    ), Model = c("PRISM", "PRISM", "PRISM", "PRISM", "PRISM"), Variable = c("tmean", 
    "tmean", "tmean", "tmean", "tmean"), Datatype = c("provisional", 
    "provisional", "stable", "stable", "stable"), Resolution = c("4kmM3", 
    "4kmM3", "4kmM3", "4kmM3", "4kmM3"), year = c(2021L, 2021L, 2020L, 
    2020L, 2020L), month = c(11L, 12L, 11L, 12L, 0L), TMin = c(0, 0, 
    0, 0, 0), TMax = c(0, 0, 0, 0, 0), geometry = structure(list(
        structure(c(-80.2083333327448, 26.2083333333333), class = c("XY", 
        "POINT", "sfg")), structure(c(-80.2083333327448, 26.2083333333333
        ), class = c("XY", "POINT", "sfg")), structure(c(-82.2083333327448, 
        28.2083333333333), class = c("XY", "POINT", "sfg")), structure(c(-82.2083333327448, 
        28.2083333333333), class = c("XY", "POINT", "sfg")), structure(c(-84.2083333327448, 
        30.2083333333333), class = c("XY", "POINT", "sfg"))), class = c("sfc_POINT", 
    "sfc"), precision = 0, bbox = structure(c(xmin = -84.2083333327448, 
    ymin = 26.2083333333333, xmax = -82.2083333327448, ymax = 28.2083333333333
    ), class = "bbox"), crs = structure(list(input = "WGS 84", wkt = "GEOGCRS[\"WGS 84\",\n    DATUM[\"World Geodetic System 1984\",\n        ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n            LENGTHUNIT[\"metre\",1]]],\n    PRIMEM[\"Greenwich\",0,\n        ANGLEUNIT[\"degree\",0.0174532925199433]],\n    CS[ellipsoidal,2],\n        AXIS[\"latitude\",north,\n            ORDER[1],\n            ANGLEUNIT[\"degree\",0.0174532925199433]],\n        AXIS[\"longitude\",east,\n            ORDER[2],\n            ANGLEUNIT[\"degree\",0.0174532925199433]],\n    ID[\"EPSG\",4326]]"), class = "crs"), n_empty = 0L)), row.names = c(NA, 
    -5L), class = c("sf", "data.frame"), sf_column = "geometry", agr = structure(c(Info = NA_integer_, 
    tmean = NA_integer_, CITYNAME = NA_integer_, Model = NA_integer_, 
    Variable = NA_integer_, Datatype = NA_integer_, Resolution = NA_integer_, 
    year = NA_integer_, month = NA_integer_, TMin = NA_integer_, 
    TMax = NA_integer_), class = "factor", .Label = c("constant", 
    "aggregate", "identity")))

UI

library(shiny)
library(shinydashboard)
library(shinythemes)
library(tidyverse)
library(RColorBrewer)
library(png)
library(shinyWidgets)
library(sf)
library(mapview)
library(leaflet)


 

       # Define UI for application that draws an interactive ggplot
        options(shiny.maxRequestSize=30*1024^2)
        ui =   navbarPage("Temperature Analysis", theme = shinytheme("sandstone"),
                        tabPanel("Temperature",
                        icon = icon("chart-area"),
                        sidebarLayout(sidebarPanel(fileInput("filemap", label = "Input Shapefile 
                                                             (.shp,.dbf,.sbn,.sbx,.shx,.prj)",
                                                             multiple=TRUE,
                                                             accept = c(".shp",
                                                                        ".dbf",
                                                                        ".sbn",
                                                                        ".sbx",
                                                                        ".shx",
                                                                        ".prj",
                                                                        ".cpg",
                                                                        ".xml"))),
                        mainPanel(selectInput(inputId = "Temp", label = "Select Temperature Variable", choices = c("Mean Temperature" = "TMean", "Minimum Temperature" = "TMin", "Maximum Temperature" = "TMax")),
                                  leafletOutput("mapview")))))

Server

# Tell the server how to assemble inputs into outputs
    server = function(input, output, session) {
Temp_map =   reactive({
            req(input$filemap)
          df = Read_Shapefile(input$filemap)
          df
        })
          pal_fun = colorQuantile("YlOrRd", NULL, n = 5) # Define color palette and classes
          
          observe({
            dff = Temp_map()
            updateSelectInput(session, "Temp", choices = names(dff))
          })
          
          #t_popup = paste0("Air Temperature", input$Temp) # Popup depends on the "Temp" variable selected 
          
          output$mapview =  renderLeaflet({
            Map_data = Temp_map() 
            Mapview_map = mapview(Map_data, zcol=input$Temp)   
            Mapview_map@map
          })    
}

Solution

  • This is because your example data is all on the exact same location, there is no reason the mapping function would be expected to average overlapping points. As well if you did you would not have the data from all the different years. I think what you are looking for is clustering, which I don't think is possible in mapview, you can do it with leaflet or tmap though, ex:

    output$mapview =  renderLeaflet({
      Map_data <-  Temp_map() 
      TMAP_MAP <- tm_basemap()+
        tm_shape(Map_data)+
        tm_dots(clustering=TRUE, col=input$Temp, popup.vars=TRUE)
      tmap_leaflet(TMAP_MAP)
    })