2012-02-08 15 views
6

Utilizzando grande ggplot2 di Hadley e il suo libro, sono in grado di produrre trame singole mappa coropletica con facilità, utilizzando il codice in questo modo:griglia con mappa coropletica in ggplot2

states.df <- map_data("state") 
states.df = subset(states.df,group!=8) # get rid of DC 
states.df$st <- state.abb[match(states.df$region,tolower(state.name))] # attach state abbreviations 

states.df$value = value[states.df$st] 

p = qplot(long, lat, data = states.df, group = group, fill = value, geom = "polygon", xlab="", ylab="", main=main) + opts(axis.text.y=theme_blank(), axis.text.x=theme_blank(), axis.ticks = theme_blank()) + scale_fill_continuous (name) 
p2 = p + geom_path(data=states.df, color = "white", alpha = 0.4, fill = NA) + coord_map(project="polyconic") 

Dove " valore "è il vettore di dati a livello di stato che sto progettando. Ma cosa succede se voglio tracciare più mappe, raggruppate per una variabile (o due)?

Ecco un esempio di un plot done by Andrew Gelman, later adapted in the New York Times, su parere di assistenza sanitaria negli Stati Uniti:

enter image description here

Mi piacerebbe essere in grado di emulare questo esempio: grafici mostrano choropleth a griglia in base a due variabili (o anche uno). Quindi non passo un vettore di valori, ma piuttosto un dataframe organizzato "lungo", con più voci per ogni stato.

So che ggplot2 può farlo, ma non sono sicuro di come. Grazie!

risposta

7

È possibile aggiungere due colonne per i raggruppamenti desiderati e uso sfaccettature:

library(ggplot2) 
library(maps) 
d1 <- map_data("state") 
d2 <- unique(d1$group) 
n <- length(d2) 
d2 <- data.frame( 
    group=rep(d2,each=6), 
    g1=rep(1:3,each=2,length=6*n), 
    g2=rep(1:2,length=6*n), 
    value=runif(6*n) 
) 
d <- merge(d1, d2, by="group") 
qplot(
    long, lat, data = d, group = group, 
    fill = value, geom = "polygon" 
) + 
    facet_wrap(~ g1 + g2) 
+0

Questo funziona. La chiave era il comando di unione che espandeva il frame di dati che emergeva da map_data, e quindi l'opzione facet_wrap che funziona esattamente come farebbe per ggplot2. Grazie! – bshor

3

mi limiterò a incollare questo script qui all'ingrosso. È autonomo, e io genero solo alcune variabili categoriali arbitrarie e un DV casuale in base al quale gli stati sono colorati. Ci sono alcune cose nel codice che non sono necessarie; mi scuso per questo.

rm(list = ls()) 
install.packages("ggplot2") 
library(ggplot2) 
install.packages("maps") 
library(maps) 
install.packages("mapproj") 
library(mapproj) 
install.packages("spatstat") 
library(spatstat) 

theme_set(theme_bw(base_size = 8)) 
options(scipen = 20) 

MyPalette <- colorRampPalette(c(hsv(0, 1, 1), hsv(7/12, 1, 1))) 

### Map ### 
StateMapData <- map_data("state") 
head(StateMapData) 

### Some Invented Data ### 

IndependentVariable1 <- c("Low Income", "Mid Income", "High Income") 
IndependentVariable2 <- c("18-29", "30-44", "45-64", "65+") 

# Here is one way to "stack" lots of copies of the shapefile dataframe on top of each other: 
# This needs to be done, because (as far as I know) ggplot2 needs to have the state names and polygon coordinates 
# for each level of the faceting variables. 

TallData <- expand.grid(1:nrow(StateMapData), IndependentVariable1, IndependentVariable2) 
TallData <- data.frame(StateMapData[TallData[, 1], ], TallData) 
colnames(TallData)[8:9] <- c("IndependentVariable1", "IndependentVariable2") 

# Some random dependent variable we want to plot in color: 
TallData$State_IV1_IV2 <- paste(TallData$region, TallData$IndependentVariable1, TallData$IndependentVariable2) 
RandomVariable <- runif(length(unique(TallData$State_IV1_IV2))) 
TallData$DependentVariable <- by(RandomVariable, unique(TallData$State_IV1_IV2), mean)[TallData$State_IV1_IV2] 

### Plot ### 

MapPlot <- ggplot(TallData, 
aes(x = long, y = lat, group = group, fill = DependentVariable)) 
MapPlot <- MapPlot + geom_polygon() 
MapPlot <- MapPlot + coord_map(project="albers", at0 = 45.5, lat1 = 29.5) # Changes the projection to something other than Mercator. 
    MapPlot <- MapPlot + scale_x_continuous(breaks = NA, expand.grid = c(0, 0)) + 
    scale_y_continuous(breaks = NA) + 
    opts(
     panel.grid.major = theme_blank(), 
     panel.grid.minor = theme_blank(), 
     panel.background = theme_blank(), 
     panel.border = theme_blank(), 
     expand.grid = c(0, 0), 
     axis.ticks = theme_blank(), 
     legend.position = "none", 
     legend.box = "horizontal", 
     title = "Here is my title", 
    legend.key.size = unit(2/3, "lines")) 
MapPlot <- MapPlot + xlab(NULL) + ylab(NULL) 
MapPlot <- MapPlot + geom_path(fill = "transparent", colour = "BLACK", alpha = I(2/3), lwd = I(1/10)) 
MapPlot <- MapPlot + scale_fill_gradientn("Some/nRandom/nVariable", legend = FALSE, 
colours = MyPalette(100)) 

# This does the "faceting": 
MapPlot <- MapPlot + facet_grid(IndependentVariable2 ~ IndependentVariable1) 

# print(MapPlot) 

ggsave(plot = MapPlot, "YOUR DIRECTORY HERE.png", h = 8.5, w = 11) 
+0

Anche questo funziona - expand.grid sta facendo lo stesso lavoro di fusione qui. Inoltre questa risposta ha molti piccoli tocchi e opzioni che ho intenzione di appropriarsi! Grazie. – bshor

Problemi correlati