2017-10-12 7 views
3

Le nouveau paquet-ish sf R rend vraiment facile à traiter des données géographiques dans R, et la version develompent de ggplot2 a une nouvelle couche geom_sf() pour tracer sf données géographiques.esthétique Carte à géométries LineString avec sf en R

Dans le paradigme de travailler avec des données sf, est-il possible de cartographier ggplot aestheics à LINESTRING geometries?

Par exemple, avec ggplot standard, il est possible de recréer Minard's famous plot of survivors from Napoleon's Grande Armée in 1812 avec ggplot et this data, dimensionnement de la voie de l'armée par le nombre de survivants:

# Install the dev version of ggplot2 for geom_sf() 
# devtools::install_github("tidyverse/ggplot2") 
library(tidyverse) 

troops <- read_csv("https://gist.githubusercontent.com/andrewheiss/69b9dffb7cca392eb7f9bdf56789140f/raw/3e2a48635ae44837955765b5e7747c429b0b5d71/troops.csv") 

ggplot(troops) + 
    geom_path(aes(x = long, y = lat, color = direction, 
       group = group, size = survivors), 
      lineend = "round") 

Nous pouvons travailler avec cette donnée de troupes en tant qu'objet sf en créant une nouvelle colonne geometry, comme ceci:

library(sf) 
#> Linking to GEOS 3.6.1, GDAL 2.1.3, proj.4 4.9.3 

troops_with_geometry <- troops %>% 
    st_as_sf(coords = c("long", "lat")) 

head(troops_with_geometry) 
#> Simple feature collection with 6 features and 3 fields 
#> geometry type: POINT 
#> dimension:  XY 
#> bbox:   xmin: 24 ymin: 54.5 xmax: 28 ymax: 55 
#> epsg (SRID): NA 
#> proj4string: NA 
#> # A tibble: 6 x 4 
#> survivors direction group   geometry 
#>  <int>  <chr> <int> <simple_feature> 
#> 1 340000   A  1 <POINT (24 54.9)> 
#> 2 340000   A  1 <POINT (24.5 55)> 
#> 3 340000   A  1 <POINT (25.5 ...> 
#> 4 320000   A  1 <POINT (26 54.7)> 
#> 5 300000   A  1 <POINT (27 54.8)> 
#> 6 280000   A  1 <POINT (28 54.9)> 

Si nous traçons cela avec geom_sf, ggplot utilisera points:

ggplot(troops_with_geometry) + 
    geom_sf(aes(color = direction, group = group)) 

Nous pouvons créer des chaînes de ligne pour chacun des groupes et des directions par groupement, résumant et coulée.

troops_lines <- troops_with_geometry %>% 
    group_by(direction, group) %>% 
    summarize() %>% 
    st_cast("LINESTRING") 

head(troops_lines) 
#> Simple feature collection with 6 features and 2 fields 
#> geometry type: LINESTRING 
#> dimension:  XY 
#> bbox:   xmin: 24 ymin: 54.1 xmax: 37.7 ymax: 55.8 
#> epsg (SRID): NA 
#> proj4string: NA 
#> direction group      geometry 
#> 1   A  1 LINESTRING (24 54.9, 24.5 5... 
#> 2   A  2 LINESTRING (24 55.1, 24.5 5... 
#> 3   A  3 LINESTRING (24 55.2, 24.5 5... 
#> 4   R  1 LINESTRING (24.1 54.4, 24.2... 
#> 5   R  2 LINESTRING (28.3 54.2, 28.5... 
#> 6   R  3 LINESTRING (24.1 54.4, 24.2... 

ggplot peut alors tracer ces six lignes connectées et les colorer correctement:

ggplot(troops_lines) + 
    geom_sf(aes(color = direction, group = group)) 

Cependant, les données des survivants est maintenant disparu et il n'y a aucun moyen de la carte taille esthétique à les nouvelles lignes.

Existe-t-il un moyen d'associer d'autres aestheics (comme la taille) à sf-based LINESTRING data? Ou, en d'autres termes, est-il un moyen de recréer ggplot(...) + geom_path(aes(x = long, y = lat, size = something)) en utilisant geom_sf() et le paradigme sf de travailler avec des données géographiques?

+1

'geom_sf' semble être uniquement disponible en version dev de ggplot2 (https://github.com/ropensci/seaaroundus/issues/24). J'ai dû installer à partir de github ('devtools :: install_github (" tidyverse/ggplot2 ")) avant de pouvoir répliquer. – mkearney

+0

Oh ouais, ça. Vous avez besoin de la version de développement :) – Andrew

Répondre

0

enter image description here Vous devez créer une ligne de chaque paire de points dans chaque groupe. Le résultat n'est pas aussi joli parce que je ne sais pas comment faire pour contourner les extrémités.

# within each group repeat each point 
# then slice the first and last out and 
# add a variable called linegroup, which provides grouping for start and endpoints of each line 
troops %<>% group_by(group) %>% 
    slice(rep(1:n(), each = 2)) %>% 
    slice(-c(1, n())) %>% 
    mutate(linegroup = lapply(1:(n()/2), function(x) rep(x, 2)) %>% unlist) %>% 
    ungroup 

# create linestring sf object by summarizing the points, 
# grab the last survivor and direction value of each group (i.e. the 'endpoint' value) 
troops_line <- st_as_sf(troops, coords = c("long", "lat"), crs = 4326) %>% 
    group_by(group, linegroup) %>% 
    summarise(survivors = last(survivors), direction = last(direction), do_union = FALSE) %>% 
    st_cast("LINESTRING") 

gp <- ggplot(troops_line) + 
    geom_sf(aes(color = direction, size = survivors), show.legend = "line")