0

I want to create a choropleth for income values in each state with package ggvis. Below is my data. I think latitude and longitude columns are required for mapping the data. Anyone knows that how can I convert the state name to latitude and longitude? Thanks a lot!

mapdata<-data.frame(
 state=c("alabama","alaska","arizona","arkansas","california","colorado","connecticut","delaware","florida","georgia","hawaii","idaho","illinois","indiana","iowa","kansas","kentucky","louisiana","maine","maryland","massachusetts","michigan", "minnesota","mississippi","missouri","montana","nebraska","nevada","new hampshire","new jersey","new mexico","new york","north carolina","north dakota","ohio","oklahoma", "oregon","pennsylvania","rhode island","south carolina","south dakota","tennessee","texas","utah","vermont","virginia","washington","west virginia","wisconsin","wyoming"),
  income=runif(50,min=100,max=9000))
wsda
  • 1,335
  • 1
  • 12
  • 16

1 Answers1

4

Here's one way. I'm using ggplot rather than ggVis but this should get you started.

library(raster)       # for getData(...)
library(ggplot2)
library(data.table)
usa   <- getData('GADM',country='USA',level=1)         # shapefile of US states
shp   <- usa[(!usa$NAME_1 %in% c("Alaska","Hawaii")),] # remove AK, HI for this example
gg.dt <- setDT(fortify(shp))               # convert shapefile to format ggplot can use
# merge with attribute table
gg.dt <- gg.dt[setDT(cbind(id=rownames(shp@data),shp@data)),on="id"]  
gg.dt[,state:=tolower(NAME_1)]             # convert state names to lower case                                     
gg.dt <- gg.dt[setDT(mapdata),on="state"]  # merge with mapdata

ggplot(gg.dt, aes(x=long, y=lat, group=group,fill=revenue)) + 
  geom_polygon(color="grey50", size=0.1)+
  scale_fill_gradientn(colours=rev(heat.colors(10)))+
  coord_map()

So here is a ggvis solution (probably should be a separate answer, but WTH). It turns out that the shapefile above is very high resolution and ggvis just can't deal with that large a file. So here we download a low-res shapefile of US state boundaries, merge using data.frames (which is adequately fast with the low-res shapefile), and then render using ggvis.

library(rgdal)   # for readOGR(...)
library(ggplot2) # for fortify(...)
library(ggvis)
# load low resolution US state shapefile (1:20MM)
url   <- "http://www2.census.gov/geo/tiger/GENZ2014/shp/cb_2014_us_state_20m.zip"
tf    <- tempfile()
td    <- tempdir()
download.file(url,tf, mode="wb")   # download shapefile archive of US state boundaries
unzip(tf, exdir=td)                # unzip into directory td

usa <- readOGR(dsn=td, layer="cb_2014_us_state_20m")
shp <- usa[(!usa$STUSPS %in% c("AK","HI")),] # remove AK, HI for this example

gg.df       <- fortify(shp)                     # convert shapefile to format ggvis can use
gg.df       <- merge(gg.df,cbind(id=rownames(shp@data),shp@data),by="id")   # merge with attribute table
gg.df$state <- tolower(gg.df$NAME)              # convert state names to lower case                                     
gg.df       <- merge(gg.df,mapdata,by="state")  # merge with mapdata
gg.df       <- gg.df[order(gg.df$order),]       # reset to original order

gg.df %>%
  group_by(group) %>%
  ggvis(~long, ~lat)  %>%
  layer_paths(fill= ~revenue)

There's a decent blog post on creating choropleth maps using ggvis here. If you want custom colors (as in the earlier answer), see the post.

jlhoward
  • 58,004
  • 7
  • 97
  • 140
  • Thanks! I want to use ggvis because I will put this choropleth on my shiny app and I need mouseover event for choropleth to show revenue value, not just a static image. – wsda Oct 12 '15 at 18:53
  • I was trying to add tooltip for this choropleth but when tooltip was added, the map just show the land of new jersey, the other parts are missing. It is wired. Could you help to have a look? : gg<-gg.df gg$id<-1:nrow(gg) values<-function(x){ if(is.null(x)) return(NULL) row<-gg[gg$id==x$id,] paste0("State: ",row$state,"
    ", "Revenue: ", row$revenue, "
    ")
    – wsda Oct 13 '15 at 17:16
  • You should post this as a separate question. You can link back to this question/answer as background. There are people on SO who know a lot more about `ggvis` than I do. – jlhoward Oct 13 '15 at 19:12