2014-12-23 16 views
9

Gibt es eine Möglichkeit, Punkte zu behalten, die auf einer Karte innerhalb einer Grenze der Karte vertauscht sind? In dem folgenden Beispiel, in dem verklemmte Orte im Südwesten von Connecticut im Wasser oder in einem angrenzenden Staat enden, gibt es eine Möglichkeit, R die Positionspunkte zu jittern, aber nicht über eine Kartengrenze?Wie kann ggplot2 verwackelte Orte innerhalb einer Kartengrenze halten, z. B. in einem US-Bundesstaat?

Alternativ gibt es eine andere Technik, wie zum Beispiel eine Tischplatte in der Nähe jeder Stadt zu erstellen, um die Firmennamen aufzulisten?

# create a data frame called "ct" of geolocations in two cities near the border of a US state (Connecticut). Each firm has the same lat and longitude of one of the two cities 

> dput(ct) 
structure(list(city = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L), .Label = c("Greenwich", "Stamford"), class = "factor"), 
    firm = structure(c(1L, 12L, 21L, 22L, 23L, 24L, 25L, 26L, 
    27L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 13L, 14L, 
    15L, 16L, 17L, 18L, 19L, 20L), .Label = c("A1", "A10", "A11", 
    "A12", "A13", "A14", "A15", "A16", "A17", "A18", "A19", "A2", 
    "A20", "A21", "A22", "A23", "A24", "A25", "A26", "A27", "A3", 
    "A4", "A5", "A6", "A7", "A8", "A9"), class = "factor"), long = c(-73.63, 
    -73.63, -73.63, -73.63, -73.63, -73.55, -73.55, -73.55, -73.55, 
    -73.55, -73.55, -73.55, -73.55, -73.55, -73.55, -73.55, -73.55, 
    -73.55, -73.55, -73.55, -73.55, -73.55, -73.55, -73.55, -73.55, 
    -73.55, -73.55), lat = c(41.06, 41.06, 41.06, 41.06, 41.06, 
    41.09, 41.09, 41.09, 41.09, 41.09, 41.09, 41.09, 41.09, 41.09, 
    41.09, 41.09, 41.09, 41.09, 41.09, 41.09, 41.09, 41.09, 41.09, 
    41.09, 41.09, 41.09, 41.09)), .Names = c("city", "firm", 
"long", "lat"), row.names = c(NA, -27L), class = "data.frame") 


library(ggplot2) 
# load the map of the United States 
all_states <- map_data("state") 
# choose to map the borders only of the state of Connecticut 
st.map <- subset(all_states, region == "connecticut") 

# plot the points for the firms with minimal jitter that still distinguishes each point 
ggplot(ct, aes(long, lat)) + 
    geom_polygon(data=st.map, aes(x=long, y=lat, group = group), colour="grey70", fill="white") + 
    coord_map() + 
    geom_point(position=position_jitter(width=.1, height=.1), size=2) 

enter image description here

jede Länge ändern oder ein klein wenig geografischer Breite, wie in dieser Frage wird nicht funktionieren, weil es zu viele Punkte und ich für eine algorithmische Lösung bin der Hoffnung, da ich viele Situationen wo diese Überfüllung und Grenzüberschreitung entstehen könnte. https://stackoverflow.com/questions/22943110/jitter-coordinates

Vielen Dank für Anregungen oder Antworten.

Antwort

7

Sie können Ihre eigene jitter Funktion erstellen, die die Daten wackelt. Verwenden Sie dann die Funktion pnt.in.poly von SDMTools, um zu überprüfen, ob der Punkt innerhalb des Polygons liegt. Sonst joncht man einfach den ursprünglichen Punkt erneut. Im folgenden sehen Sie ein Beispiel:

require(SDMTools) 
bounded_jitter <- function(mapping, data, bounds, width, height, ...){ 
    # data2 is the jittered data 
    data2 <- data 
    data2[, paste(mapping$x)] <- rnorm(nrow(data), data[, paste(mapping$x)], width/1.96) 
    data2[, paste(mapping$y)] <- rnorm(nrow(data), data[, paste(mapping$y)], height/1.96) 
    # is it inside the polygon? 
    idx <- as.logical(pnt.in.poly(pnts = data2[, c(paste(mapping$x), paste(mapping$y))], 
           poly.pnts = bounds)[, 'pip']) 
    while(!all(idx)) { # redo for points outside polygon 
    data2[!idx, paste(mapping$x)] <- rnorm(sum(!idx), data[!idx, paste(mapping$x)], width/1.96) 
    data2[!idx, paste(mapping$y)] <- rnorm(sum(!idx), data[!idx, paste(mapping$y)], height/1.96) 
    idx <- as.logical(pnt.in.poly(pnts = data2[, c(paste(mapping$x), paste(mapping$y))], 
            poly.pnts = bounds)[, 'pip']) 
    } 
    # the point 
    geom_point(data = data2, mapping, ...) 
} 
# plot the points for the firms with minimal jitter that still distinguishes each point 
ggplot(ct, aes(long, lat)) + 
    geom_polygon(data=st.map, aes(x=long, y=lat, group = group), colour="grey70", fill="white") + 
    coord_map() + 
    geom_point(size=2) + 
    bounded_jitter(mapping = aes(x=long, y=lat), 
       data = ct, 
       bounds = st.map[, c('long', 'lat')], 
       width = .1, 
       height = .1) 

resulting plot: Connecticut with jittered points inside

+0

Wow, das ist eine großartige Funktion ist. Es wäre großartig, wenn diese Funktion in einem Paket existiert! +1 – jazzurro

+0

@shadow, das ist sehr cool! Was, wenn ich diese Situation in vielen Staaten habe und nicht weiß, welche Jitter improvisieren werden? Meine tatsächlichen Anwendungsfälle haben Tausende von Standorten in Hunderten von Städten, von denen viele in der Nähe von Ozeanen, Seen oder Staatsgrenzen liegen. Wie kann ich R für die Grenzüberschreitung prüfen lassen und die Funktion bei Bedarf aufrufen? – lawyeR