This comes from the ggplot2 documentation:
# Better example
crimes <- data.frame(state = tolower(rownames(USArrests)), USArrests)
library(reshape2) # for melt
crimesm <- melt(crimes, id = 1)
if (require(maps)) {
states_map <- map_data("state")
ggplot(crimes, aes(map_id = state)) + geom_map(aes(fill = Murder), map = states_map) + expand_limits(x = states_map$long, y = states_map$lat)
last_plot() + coord_map()
ggplot(crimesm, aes(map_id = state)) + geom_map(aes(fill = value), map = states_map) + expand_limits(x = states_map$long, y = states_map$lat) + facet_wrap( ~ variable)
}
I don't understand how this can work since there is no common identifier in the states_map
data frame which uses "region" to name the states column and the crimes
data frame which labels the states, "states." What ties the data to the map?
In this example the poster renames the columns of the map data frame to conform with the data but the ggplot2 documentation doesn't seem to do it. How? When I rename the columns of states_map
in the example above, so that "state" is common to both data frames, it breaks the code.
crimes <- data.frame(state = tolower(rownames(USArrests)), USArrests)
library(reshape2) # for melt
crimesm <- melt(crimes, id = 1)
if (require(maps)) {
states_map <- map_data("state")
##### my attempt to fix what isn't broken #################
names(states_map)[5]<-"state"
###########################################################
ggplot(crimes, aes(map_id = state)) + geom_map(aes(fill = Murder), map = states_map) + expand_limits(x = states_map$long, y = states_map$lat)
last_plot() + coord_map()
# Error: all(c("x", "y", "id") %in% names(map)) is not TRUE
}
Thanks.
If you look up the code for geom_map
:
function (mapping = NULL, data = NULL, stat = "identity", ...,
map, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE)
{
stopifnot(is.data.frame(map))
if (!is.null(map$lat))
map$y <- map$lat
if (!is.null(map$long))
map$x <- map$long
if (!is.null(map$region))
map$id <- map$region
stopifnot(all(c("x", "y", "id") %in% names(map)))
# etcetera...
}
This means, that for the correct building of the geom, a data frame map
will be generated with x, y, and id column. With aes(map_id = state)
you are basically assigning crimes$state
to map$id
(to my understanding)
If you don't have an id
column in your map data, the column which is called region
will be used as your id column.
You can test this with changing the name of states_map$region
to states_map$id
names(states_map)[5]<-"id"
This works with the given example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With