2

I want to make a SpatialPolygonsDataFrame using the output from get_map in ggplot2. I found a way to do it after some trial and error but it seems convoluted to me. Is there a cleaner way?

library(ggplot2)
library(sp)
library(plyr)
pnw.df <- map_data("state",region=c("washington","oregon","idaho"))
# delete islands from subregions
pnw.df$subregion[is.na(pnw.df$subregion)] <- "main" 
pnw.df <- subset(pnw.df,subregion == "main") 

getPolygons <- function(x) {
  Polygons(list(Polygon(x[,c("long","lat")])),ID=unique(x$region))
}

pnw.sp <- SpatialPolygons(dlply(pnw.df, .(region), getPolygons))
pnw.sp <- as(pnw.sp,"SpatialPolygonsDataFrame")
proj4string(pnw.sp) <- "+proj=longlat +ellps=WGS84"
plot(pnw.sp)
user4100013
  • 131
  • 1
  • 9
  • `ggplot2::map_data("state")` calls `maps::map("state", ...)` under the hood. Have a look at Josh O'Brien's answer [here](https://stackoverflow.com/questions/8751497/latitude-longitude-coordinates-to-state-code-in-r/8751965#8751965) for a very convenient way to convert its output to 'SpatialPolygons'. – fdetsch Aug 30 '18 at 07:37

1 Answers1

0

Look into maptools::map2SpatialPolygons, an try its examples. map_data reads the data from maps and puts them in a data.frame, which is not very helpful. The maptools function takes the same data from maps, and converts them into a SpatialPolygons object.

Edzer Pebesma
  • 3,814
  • 16
  • 26
  • Unfortunately `map2SpatialPolygons` is buggy @EdzerPebesma. `World2 <- map(database = "mapdata::world2Hires"); World2sp <- map2SpatialPolygons(World2, IDs = sub(":.*", "", World2$names), proj4string=CRS("+proj=longlat +datum=WGS84"))` gives an error: `map and IDs differ in length`. There are, indeed, only 2284 IDs versus 3905 elements in the list returned by this code: `xyList <- .NAmat2xyList(cbind(map$x, map$y))`. – Michael Henry Sep 04 '18 at 05:07
  • I asked you to look at the examples: you need to add arguments `fill=TRUE` and `plot=FALSE`. – Edzer Pebesma Sep 04 '18 at 10:10
  • Thank you @EdzerPebesma! I was looking at the examples but somehow I completely missed `fill=TRUE`. That makes all the difference! – Michael Henry Sep 04 '18 at 23:57