Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How keep information from shapefile after fortify()

Tags:

r

ggplot2

rgdal

How can I keep polygons's information after shapefile? Let me try to explain:

I have a shapefile with this data:

> head(mapa@data)
         ID      CD_GEOCODI   TIPO   CD_GEOCODB    NM_BAIRRO  CD_GEOCODS NM_SUBDIST CD_GEOCODD   NM_DISTRIT CD_GEOCODM   NM_MUNICIP     NM_MICRO                       NM_MESO
12228 33679 431490205000133 URBANO 431490205003 Cidade Baixa 43149020500       <NA>  431490205 PORTO ALEGRE    4314902 PORTO ALEGRE PORTO ALEGRE METROPOLITANA DE PORTO ALEGRE
12229 33680 431490205000134 URBANO 431490205003 Cidade Baixa 43149020500       <NA>  431490205 PORTO ALEGRE    4314902 PORTO ALEGRE PORTO ALEGRE METROPOLITANA DE PORTO ALEGRE
12230 33681 431490205000135 URBANO 431490205003 Cidade Baixa 43149020500       <NA>  431490205 PORTO ALEGRE    4314902 PORTO ALEGRE PORTO ALEGRE METROPOLITANA DE PORTO ALEGRE
12231 33682 431490205000136 URBANO 431490205003 Cidade Baixa 43149020500       <NA>  431490205 PORTO ALEGRE    4314902 PORTO ALEGRE PORTO ALEGRE METROPOLITANA DE PORTO ALEGRE
12232 33683 431490205000137 URBANO 431490205003 Cidade Baixa 43149020500       <NA>  431490205 PORTO ALEGRE    4314902 PORTO ALEGRE PORTO ALEGRE METROPOLITANA DE PORTO ALEGRE
12233 33684 431490205000138 URBANO 431490205003 Cidade Baixa 43149020500       <NA>  431490205 PORTO ALEGRE    4314902 PORTO ALEGRE PORTO ALEGRE METROPOLITANA DE PORTO ALEGRE

and this data:

> head(data)
       CD_GEOCODI Population
1 431490205000133       1272
2 431490205000134        822
3 431490205000135       1085
4 431490205000136       1454
5 431490205000137        964
6 431490205000138        834

I could just merge data and mapa@data and plot it with plot(), but I want use ggplot2. But fortify()'s output donsn't have any of originals variables. For example:

> head(fortify(mapa))
Regions defined for each Polygons
       long       lat order  hole piece   group    id
1 -51.22254 -30.03526     1 FALSE     1 12228.1 12228
2 -51.22332 -30.03648     2 FALSE     1 12228.1 12228
3 -51.22365 -30.03702     3 FALSE     1 12228.1 12228
4 -51.22482 -30.03610     4 FALSE     1 12228.1 12228
5 -51.22488 -30.03606     5 FALSE     1 12228.1 12228
6 -51.22476 -30.03591     6 FALSE     1 12228.1 12228

Both (fortify and mapa@data) have an id variable, but aren't the same values. So, again, my question is: How can I pass mapa@data's information to fortify()'s output (or another function that allows use ggplot2)

like image 605
Rcoster Avatar asked Feb 28 '14 13:02

Rcoster


People also ask

Can you load a shapefile into R?

Shapefile Metadata & Attributes When we import the HarClip_UTMZ18 shapefile layer into R (as our aoi_boundary_HARV object), the st_read() function automatically stores information about the data.

What does fortify function do in R?

Description. The fortify function converts an S3 object generated by evalmod to a data frame for ggplot2.

What is shapefile in R?

Shapefiles are a common way to store geospatial data. This post explains how to read it with R and the rgdal package, and how to plot it in base R or with ggplot2 . Background map section About Maps.


4 Answers

Since you did not provide your shapefile or data, it's impossible to test, but something like this should work:

# not tested...
library(plyr)      # for join(...)
library(rgdal)     # for readOGR(...)
library(ggplot2)   # for fortify(...)

mapa <- readOGR(dsn=".",layer="shapefile name w/o .shp extension")
map@data$id <- rownames(mapa@data)
mapa@data   <- join(mapa@data, data, by="CD_GEOCODI")
mapa.df     <- fortify(mapa)
mapa.df     <- join(mapa.df,mapa@data, by="id")

ggplot(mapa.df, aes(x=long, y=lat, group=group))+
  geom_polygon(aes(fill=Population))+
  coord_fixed()
like image 80
jlhoward Avatar answered Oct 06 '22 02:10

jlhoward


Maybe this is a slightly simpler solution

library(dplyr)
library(ggplot2)

# fortify the shape file
  map.df <- fortify(shape, region ="CD_GEOCODI")

# merge data
  map.df <- left_join(map.df, data, by=c('id'='CD_GEOCODI'))
like image 24
rafa.pereira Avatar answered Oct 06 '22 04:10

rafa.pereira


I came across the same problem and was able to achieve the desired results using slightly different approach.

Import and fortify

I have used the following code to read the shapes:

shps <- maptools::readShapePoly(fn = file.path("file",
                                               "path",
                                               "no extension"),
                                     # Column with unique IDs
                                     IDvar = "geoID")

and subsequently fortified the objet using the code:

shpsFort <- ggplot2::fortify(model = shps)

Results

This created a data.frame object with the id value corresponding to the column passed in IDvar = "geoID". Adding any other data could be simply addressed via ordinary merge command.

like image 39
Konrad Avatar answered Oct 06 '22 02:10

Konrad


Assumption that data$CD_GEOCODI and shape@data are both unique for each row. Below is a better and simpler answer:

library(dplyr)
library(ggplot2)

# fortify the shape file
  map.df <- fortify(shape, region ="CD_GEOCODI")

# change data$CD_GEOCODI to character, as shp.df$CD_GEOCODI is of character class.
  data <- data %>% mutate(data, CD_GEOCODI = as.character(CD_GEOCODI))

# merge data
  map.df <- left_join(map.df, data, by=c('id'='CD_GEOCODI'))
like image 30
Huanfa Chen Avatar answered Oct 06 '22 03:10

Huanfa Chen