1

I have made a US state map with the following code, but my data doesn't include all the state, yet the map is coloring in everything anyways. This is strange because I have a variable that clearly assigns one color to each of the regions in the data. When I use the option (exact=TRUE), it doesn't return any map and there's an error. Why isn't it leaving the missing data blank in the map? And does this mean the colors are random?

Here's a link to the data I used in excel format : https://docs.google.com/spreadsheets/d/19VHQdl5-i3r9OzJmJsB9FsrQU5Qk_lnkWmspq0ilAN0/edit?usp=sharing

If you load this excel file into R and save the db as Trump, then all of the following code should work to make this map image

library(maps)

# I created a set of colors I want to use, then a variable that numbers the levels
# The variable has an integer that will tell the map which color in the list to color the region
colors = c("#F1EEF6", "#D4B9DA", "#DF65B0", "#DD1C77", "#980043")
Trump$fraction_votes2 <- as.character(Trump$fraction_votes)
Trump$fraction_votes2 <- as.numeric(Trump$fraction_votes2)
Trump$colorBuckets <- as.numeric(cut(Trump$fraction_votes2, c(0, 0.3, 0.4, 0.5, 0.6, 1.0)))
lnames = c("0-30%", "31-40%", "41-50%", "51-60%", "61-100%")

par(mar=c(1,1,1,1)) # This solves the "plot region too large problem)
map("county", fill=TRUE, exact=TRUE, col = colors[Trump$colorBuckets] , lwd = 0.1)
title(main="Trump: Percentage of Votes Won by County",               font.main=2,cex.main=1.2, col.main="maroon4", family="Gill Sans Light")
legend("bottomleft",lnames, col = colors, lwd=3,bty="n"
   , cex=0.3, text.font=8, y.intersp=2, title="Voter Percentages\n Key") 
  • Welcome to SO. You'll be more much likely to get a response if you post a [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). As it stands, people can't run your code, so it will be very difficult to debug. – Tchotchke Jun 06 '16 at 12:20
  • Without any data to test, it difficult to provide meaningful recommendations. This line: map("county", fill=TRUE, exact=TRUE, col = colors[Trump$colorBuckets] , lwd = 0.1) is mapping all of the counties. There is no link between which counties to map and which color to use. Most likely you will need to define a color for exactly zero and then define a color for all counties. – Dave2e Jun 06 '16 at 12:31
  • Thanks for your advice. In my data, I don't have all of the states/counties listed. I thought this would mean they just wouldn't be colored in, but they are. Also, I made a variable in the data that assigns a color to each region that's in the db. I used the "col" option to color in the map according to that variable. is that correct? – Ashley Acker Jun 09 '16 at 14:09
  • I just added the code and the finale image, so hopefully some SO members will be up to looking this problem over. – Ashley Acker Jun 10 '16 at 10:02
  • Ashley, You are on the correct track, but your database needs to include all of the counties into your database. Another approach is to use the "regions= " option in the map command and set regions to the list of states which you do have data for. Like: map('county', regions=c('new jersey', 'iowa', 'ohio')) – Dave2e Jun 14 '16 at 12:54
  • That solution worked, thanks a lot! I make a vector with the states in the data and set region equal to it. The only problem is that now the missing states are big white wholes in the map. Is there anyway to draw the borders of missing data and just not fill them? – Ashley Acker Jun 14 '16 at 17:49

1 Answers1

0

Here is a more complete solution. This will plot the entire map. The key is to make sure the color by county list is in the same order as the list used by the map function. I called the map(county) function to return the list. I then split the list into a data frame. Use the "col" column in the data frame "statelist" to assign the proper colors.

#function to split a string and return a 2 column dataframe
strtodf<-function (list){
  slist<-strsplit(list, ",")
  x<-sapply(slist, FUN= function(x) {x[1]})
  y<-sapply(slist, FUN= function(x) {x[2]})
  df<-data.frame(state=x, county=y, stringsAsFactors = FALSE)
  return(df)
}

trump<-read.csv("trump.csv")
colors = c("#F1EEF6", "#D4B9DA", "#DF65B0", "#DD1C77", "#980043")
lnames = c("0-30%", "31-40%", "41-50%", "51-60%", "61-100%")
#create smaller dataframe with just columns of interest
trumpReduced<-data.frame(county=tolower(trump$county), state=tolower(trump$state), stringsAsFactors = FALSE)
trumpReduced$fraction_votes2 <- as.numeric(as.character(trump$fraction_votes))
trumpReduced$colorBuckets <- as.numeric(cut(trumpReduced$fraction_votes2, c(0, 0.3, 0.4, 0.5, 0.6, 1.0)))

library(maps)
#get the list of counties plotted in the map in the correct order
maplist<-map("county", namesonly = TRUE, plot=FALSE)
statelist<-strtodf(maplist)  #convert to dataframe
statelist$row<-as.numeric(rownames(statelist))  #index column
statelist$col<-NA   #add default color

#merge counties to the correct color and resort 
statelist<-merge(statelist, trumpReduced, sort=FALSE, all.x=TRUE)
statelist<-statelist[order(statelist$row),]

#plot map.
maplist<-map("county", fill=TRUE, col=colors[statelist$colorBuckets])
title(main="Trump: Percentage of Votes Won by County", font.main=2, cex.main=1.2, col.main="maroon4", family="Gill Sans Light")
legend("bottomleft", lnames, col = colors, lwd=3,bty="n", cex=0.3, text.font=8, y.intersp=2, title="Voter Percentages\n Key") 
Dave2e
  • 22,192
  • 18
  • 42
  • 50