How to combine data and geometry with ggmap

An image is worth a thousand words: Data does not match geometry

Observed Behavior: As can be seen from the above image, the names of the countries do not match their actual geometries.

Expected Behavior: I would like to correctly associate a data frame with its geometry and display the result in ggmap.

I had previously joined various data frames, but everything is getting wrong, because apparently I ggmapneed to “fortify” (in fact, I don’t know what it really means) a data frame to display the results.

This is what I have done so far:

library(rgdal)
library(dplyr)
library(broom)
library(ggmap)

# Load GeoJSON file with countries.
countries = readOGR(dsn = "https://gist.githubusercontent.com/ccamara/fc26d8bb7e777488b446fbaad1e6ea63/raw/a6f69b6c3b4a75b02858e966b9d36c85982cbd32/countries.geojson")

# Load dataframe.
df = read.csv("https://gist.githubusercontent.com/ccamara/fc26d8bb7e777488b446fbaad1e6ea63/raw/a6f69b6c3b4a75b02858e966b9d36c85982cbd32/sample-dataframe.csv")

# Join geometry with dataframe.
countries$iso_a2 = as.factor(countries$iso_a2)
countries@data = left_join(countries@data, df, by = c('iso_a2' = 'country_code'))

# Convert to dataframe so it can be used by ggmap.
countries.t = tidy(countries)

# Here where the problem starts, as by doing so, data has been lost!

# Recover attributes' table that was destroyed after using broom::tidy.
countries@data$id = rownames(countries@data) # Adding a new id variable.
countries.t = left_join(countries.t, countries@data, by = "id")

ggplot(data = countries.t,
       aes(long, lat, fill = country_name, group = group)) +
  geom_polygon() +
  geom_path(colour="black", lwd=0.05) + # polygon borders
  coord_equal() +
  ggtitle("Data and geometry have been messed!") +
  theme(axis.text = element_blank(), # change the theme options
        axis.title = element_blank(), # remove axis titles
        axis.ticks = element_blank()) # remove axis ticks
+6
source share
2 answers

.

countries SpatialPolygonsDataFrame 177 ( 177 countries@data). left_join countries@data df, countries , countries@data 210.

countries broom::tidy countries 177 id, 0 176. ( , , ).

id countries@data rownames(countries@data), , id 1 210, countries@data df. , .

:

# (we start out right after loading countries & df)

# no need to join geometry with df first

# convert countries to data frame, specifying the regions explicitly
# (note I'm using the name column rather than the iso_a2 column from countries@data;
# this is because there are some repeat -99 values in iso_a2, and we want
# one-to-one matching.)
countries.t = tidy(countries, region = "name")

# join with the original file data
countries.t = left_join(countries.t, countries@data, by = c("id" = "name"))

# join with df
countries.t = left_join(countries.t, df, by = c("iso_a2" = "country_code"))

# no change to the plot code, except for ggtitle
ggplot(data = countries.t,
       aes(long, lat, fill = country_name, group = group)) +
  geom_polygon() +
  geom_path(colour="black", lwd = 0.05) +
  coord_equal() +
  ggtitle("Data and geometry are fine") +
  theme(axis.text = element_blank(),
        axis.title = element_blank(),
        axis.ticks = element_blank())

enter image description here

p.s. ggmap. ggplot2, .

+1

- - , , - :

1), GeoJSON - , R sp sp * - , . , ( ) sp *.

2) ggplot ggmap - sp * R ..

, - :

library(sp)
library(dplyr)
library(geojsonio)
library(dplyr)
library(tmap)

#get sp* object instead of geojson
countries <- geojsonio::geojson_read("foo.geojson",what = "sp")

#match sp* object with your data.frame
countries@data <- dplyr::left_join(countries@data, your_df, by = 
c("identifier_1" = "identifier_2"))

#creates a fast and nice looking plot / lots of configuration available
p1 <- tm_shape(countries) +
      tm_polygons() 
p1

#optional interactive leaflet plot
tmap_leaflet(p1)

/ , .

, R (, geojson ).

+2

All Articles