I have the shiny app below with this sf object and I want to use the leaflet package to create an interactive map with clickable polygons. When a user clicks on a polygon, the app will save and display a subset of the table based on the clicked polygon. I take Warning: Error in is.finite: default method not implemented for type 'list'
. Is there another map library that I can do this if it is impossible with leaflet?
databad<-structure(list(ac_code = c(259L, 259L, 259L), booth_no = 1:3,
state = c("West Bengal", "West Bengal", "West Bengal"), ac_name = c("Khandaghosh",
"Khandaghosh", "Khandaghosh"), voteshare.IND = c(0.01, 0,
0.01), voteshare.BMUP = c(0.01, 0, 0), voteshare.CPM = c(0.58,
0.31, 0.25), voteshare.AITC = c(0.33, 0.52, 0.57), voteshare.BJP = c(0.06,
0.13, 0.11), voteshare.INC = c(0, 0.02, 0.05), voteshare.BSP = c(0,
0, 0.01), voteshare.SUCI = c(0, 0.01, 0.01), nn_hospital = c("Khundkuri Hospital",
"Khundkuri Hospital", "Mankar Rural Hospital"), distance_nn_hospital = c(8949.68646563084,
17217.1419457099, 16939.2318150416), nn_school = c("বর্ধমান টাউন স্কুল",
"বর্ধমান টাউন স্কুল", "Guskara Girls High School"
), distance_nn_school = c(16834.9368635036, 24332.8584456302,
19846.4525464748), nn_bank = c("contai", "contai", "Allahabad Bank"
), distance_nn_bank = c(13959.9950089655, 20598.4763042432,
19688.6296071566), nn_atm = c("ING Bank", "ING Bank", "ING Bank"
), distance_nn_atm = c(55404.6817200836, 47524.5016641311,
45106.1556369373), voteshare.JMM = c(NA_real_, NA_real_,
NA_real_), voteshare.JDP = c(NA_real_, NA_real_, NA_real_
), voteshare.CPI.ML..L. = c(NA_real_, NA_real_, NA_real_),
voteshare.IUML = c(NA_real_, NA_real_, NA_real_), voteshare.GaAP = c(NA_real_,
NA_real_, NA_real_), voteshare.NOTA = c(NA_real_, NA_real_,
NA_real_), geometry = structure(list(structure(list(list(
structure(c(87.7090902547602, 87.7151753707173, 87.7154550055682,
87.7086421531382, 87.7023431042605, 87.6970612820198,
87.7017218525372, 87.7090902547602, 23.2040982701717,
23.2136143676662, 23.2156954885727, 23.2276541162583,
23.2281630737782, 23.2181646062169, 23.2053620549479,
23.2040982701717), dim = c(8L, 2L)))), class = c("XY",
"MULTIPOLYGON", "sfg")), structure(list(list(structure(c(87.6365062737229,
87.6376152918208, 87.6308791550368, 87.625023101282, 87.62345364621,
87.6365062737229, 23.2401534236987, 23.244460158139, 23.2496234950258,
23.2489032619139, 23.2468180156553, 23.2401534236987), dim = c(6L,
2L)))), class = c("XY", "MULTIPOLYGON", "sfg")), structure(list(
list(structure(c(87.6586184806029, 87.67258178803, 87.6804334223628,
87.6655208748092, 87.6611300171367, 87.6604474038247,
87.6586184806029, 23.3194136362408, 23.3169136956011,
23.3271416599132, 23.333645873538, 23.3347376687085,
23.3208934817488, 23.3194136362408), dim = c(7L, 2L)))), class = c("XY",
"MULTIPOLYGON", "sfg"))), class = c("sfc_MULTIPOLYGON", "sfc"
), precision = 0, bbox = structure(c(xmin = 87.62345364621,
ymin = 23.2040982701717, xmax = 87.7154550055682, ymax = 23.3347376687085
), 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[\"geodetic latitude (Lat)\",north,\n ORDER[1],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n AXIS[\"geodetic longitude (Lon)\",east,\n ORDER[2],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n ID[\"EPSG\",4326]]"), class = "crs"), n_empty = 0L)), sf_column = "geometry", agr = structure(c(ac_code = NA_integer_,
booth_no = NA_integer_, state = NA_integer_, ac_name = NA_integer_,
voteshare.IND = NA_integer_, voteshare.BMUP = NA_integer_, voteshare.CPM = NA_integer_,
voteshare.AITC = NA_integer_, voteshare.BJP = NA_integer_, voteshare.INC = NA_integer_,
voteshare.BSP = NA_integer_, voteshare.SUCI = NA_integer_, nn_hospital = NA_integer_,
distance_nn_hospital = NA_integer_, nn_school = NA_integer_,
distance_nn_school = NA_integer_, nn_bank = NA_integer_, distance_nn_bank = NA_integer_,
nn_atm = NA_integer_, distance_nn_atm = NA_integer_, voteshare.JMM = NA_integer_,
voteshare.JDP = NA_integer_, voteshare.CPI.ML..L. = NA_integer_,
voteshare.IUML = NA_integer_, voteshare.GaAP = NA_integer_, voteshare.NOTA = NA_integer_
), levels = c("constant", "aggregate", "identity"), class = "factor"), row.names = c(NA,
3L), class = c("sf", "data.frame"))
app
library(shiny)
library(leaflet)
library(dplyr)
library(sf)
# Define the shiny app
ui <- fluidPage(
leafletOutput("map"),
tableOutput("subset_table")
)
server <- function(input, output, session) {
# Render the leaflet map
output$map <- renderLeaflet({
leaflet() %>%
addProviderTiles("OpenStreetMap.Mapnik") %>%
addPolygons(data = databad, layerId = ~ac_code) # Replace sf_data with your actual sf object
})
# Subset and display the table based on the clicked polygon
output$subset_table <- renderTable({
event <- input$map_shape_click
if (!is.null(event)) {
clicked_layer_id <- event$id
subset_data <- databad %>%
filter(ac_code == clicked_layer_id) # Replace ac_code with the appropriate column name
subset_data
}
})
}
# Run the app
shinyApp(ui, server)
The geometry column in databad is a list (sfc_MULTIPOLYGON exactly). And the function renderTable doesn't handle a dataframe with a list column. You can remove the geometry column.
The easiest way to solve this is to replace the lines
subset_data <- databad %>%
filter(ac_code == clicked_layer_id)
subset_data
by
subset_data <- databad %>%
filter(ac_code == clicked_layer_id)
st_drop_geometry(subset_data) # remove the geometry column
To get rid of the geometry column.