Leaflet in R Usage

I want to make a map of India with state boundaries using the leaflet package in R. In the map, I want to make a heat map with the number of COVID cases in all states of India.
The data frames are as follows:

  1. sw - It contains name of states, total confirmed cases
  2. states - geo json file containing state names

The code is as follows:

sw <- data.frame(read_csv("state_wise.csv"))
states <- geojsonio::geojson_read("states.geojson", what = "sp")

states$Cases <- sw[match(states$ST_NM, sw$State), "Confirmed"]

bins <- c(0, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 100000, 200000, 250000, Inf)

pal <- colorBin(
  palette = "viridis", domain = states$Cases,
  bins = bins
)

map$labels <- paste0(
  "<strong> State: </strong> ",
  states$ST_NM, "<br/> ",
  "<strong> Cases: </strong> ",
  states$Cases, "<br/> "
) %>%
  lapply(htmltools::HTML)

leaflet(states) %>%
  addTiles() %>%
  setView(lng = 0, lat = 30, zoom = 1.5) %>%
  addPolygons(
    fillColor = ~ pal(Cases),
    color = "white",
    fillOpacity = 0.7,
    label = ~labels,
    highlight = highlightOptions(
      color = "black",
      bringToFront = TRUE
    )
  ) 

When I run this code, I get an error like this: Error in as.character(text) :
cannot coerce type 'closure' to vector of type 'character'
I am not able to understand where is this error coming from. Please help me out.

Suggestions:

  • Your code is not reproducible because we don't have your data. Show us how you created your inputs. We don't need all data as long as we can run the code.
  • You did not indicate where it went wrong: you have a lot of code so I assume that at some time you could see a plot. Is that so or did you never see a plot? In the first case:
  • Try to leave out non-essential items as e.g. color. At some point, I assume, there will be no more error. Then you know that this last item caused the/an error. Look up the specifications in the documentation and if you don't find the reason ask a more specific question here.
1 Like

Hi khusi,

the immediate problem seems to be that when you create the map labels - the map$labels <- paste0(... call roughly in the middle of your code - you assign them to map$labels; there is no object named map in your code, so this call fails.

When you later try to use the labels in your leaflet call there will be neither a states$labels column (remember that states is the data argument of your leaflet call, so this gets tried the first) nor a plain labels vector object in your search path, so the R environment will fall back to base::labels() function, which is of course a function and thus an object of type closure (which is not subsettable, as R likes to remind us).

Therefore I suggest to replace your map$labels by states$labels assignment.
This should be enough to make your code work.

Screenshot from 2020-06-06 14-16-03

This should solve your immediate issue, and leave you with a workable map; still in need of some tweaking (perhaps a different basemap or color palette) but it is a start.

As a suggestion: your workflow is based on the earlier {sp} package; I believe you will find it easier to work in the context of the newer {sf} package.

{sf} spatial objects are modified dataframes, and as such are much easier to work with than sp - e.g. allowing dplyr kind *_join() of data fields to shapefiles.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

Sir @HanOostdijk , the input files are uploaded in the following link:
https://drive.google.com/drive/folders/1QK52vJM9hC3vxqMAFLnppwqnhF39RsM4?usp=sharing

Also, Even though I remove the other aesthetics, there is no plot in the output. Only blank space is there.

I did change only the name of the label variable and I get a map:

map_labels <- paste0(
  "<strong> State: </strong> ",
  states$ST_NM, "<br/> ",
  "<strong> Cases: </strong> ",
  states$Cases, "<br/> "
) %>%
  lapply(htmltools::HTML)

leaflet(states) %>%
  addTiles() %>%
  setView(lng = 0, lat = 30, zoom = 1.5) %>%
  addPolygons(
    fillColor = ~ pal(Cases),
    color = "white",
    fillOpacity = 0.7,
    label = ~map_labels,
    highlight = highlightOptions(
      color = "black",
      bringToFront = TRUE
    )
  ) 
1 Like

Noted. It is working now! Thank you!

1 Like

Got it sir. Thank you so much!