1
votes

First post, I'll try to do my best.

I'm trying to make an interactive choropleth map with leaflet in R, based off this tutorial. It all goes great until I compare the data represented on the map with the data in my data frame.

I'm using the same data as the person who wrote the tutorial. It is a Large Spatial Polygons Dataframe called world_spdf with 246 rows of world_spdf@data and world_spdf@polygons as well as three other objects I have no idea about. The data is essentially countries with long and lat. I don't know anything about spatial data, but I'm assuming it's responsible for the shapes of the countries on a rendered map.

I also have a data frame called results that initially has 234 rows, also about countries and some additional data for each country. This is how head(results) looks like (it goes on like this, and there are no NAs):

    ISO2      v1    v2      v3
  <chr>  <dbl> <dbl>   <dbl>
1 AD    0.118  0.880 0.001  
2 AE    0.226  0.772 0.0016 
3 AF    0.197  0.803 0.0001 
4 AG    0.0884 0.911 0.0009 
5 AI    0.172  0.827 0.00120
6 AL    0.107  0.891 0.0022 

I am merging the two dataframes by ISO2 column which contains country codes. Everything is fine so far, the data in the merged dataframe is correctly assigned to the country.

world_spdf@data = merge(world_spdf@data, results, by = "ISO2")

However, when I try to plot the data, the resulting interactive map presents the data in a "wrong order", for example, data for Poland for Nigeria etc.

What I tried was to find the missing countries in the smaller dataframe like this:

differences = c(setdiff(world_spdf@data$ISO2, results$ISO2)

And then add rows with NAs to the dataframe so that all the countries in the spatial dataframe are represented with NAs at least. But this didn't help.

I am clueless as to why this occurs. Please help!

1
I do not have your results. So I cannot help you. But I have the impression that the merge process screwed up something. If you can provide the results object and your code, someone will be able to help you out here. - jazzurro
@jazzurro, Thanks for your reply, I appreciate it. I provided more code. With the two datasets merged like this, I go on to use the code from the quoted tutorial. The map renders, and the values are indeed taken from the right columns, but they aren't mapped properly. - Ziemowit Bućko

1 Answers

0
votes

I cannot see your side. But it seems that your join process did not go well. I have seen people like that here before. In that tutorial, the author is using sp approach. But now we can use sp approach. The sp package is better, in that you can handle data manipulation much easier. For example, you can use the tidyverse package. If you use the sp package, you cannot use filter(), mutate(), left_join() and so on. In the end, it is your choice. But I recommend the sf package.

Here, I used the data you provided. So you do not see colors much in the following map. But I want to show you that country names are matching with correct locations. On my side, I see Poland has 38.2 for POP2005, which is the right value in mysf.

library(dplyr)
library(sf)
library(leaflet)
library(viridis)

# Read the shapefile as an sf object rather than as sp object.
mysf <- st_read(dsn = ".", layer = "TM_WORLD_BORDERS_SIMPL-0.3")

# Clean up the data as the tutorial shows.
mutate(mysf,
       POP2005 = if_else(POP2005 == 0, NA_real_, POP2005),
       POP2005 = round(POP2005 / 1000000, 2)) -> mysf


# Now join the results to mysf
left_join(mysf, results, by = "ISO2") -> mysf


# Create a color palette. I am not sure which variable you use.
# But I chose POP2005.
mypal <- colorNumeric(palette = "viridis",
                      domain = mysf$POP2005, na.color = "transparent")

# Draw a leaflet map
leaflet() %>% 
addProviderTiles("OpenStreetMap.Mapnik") %>%
addPolygons(data = mysf, group = "continuous",
            stroke = FALSE, smoothFactor = 0.2, fillOpacity = 0.5,
            fillColor = ~mypal(mysf$POP2005),
            popup = paste("Country: ", mysf$NAME, "<br>",
                          "ISO2: ", mysf$ISO2, "<br>",
                          "Population:", mysf$POP2005, "<br>")) %>%
addLayersControl(overlayGroups = "continuous") %>%
addLegend(position = "bottomright", pal = mypal, values = mysf$POP2005,
          title = "Population 2005",
          opacity = 0.5)

enter image description here