Chapitre 6 Les opérations spatiales sur les données
Les opérations spatiales sont des opérations prenant nos données en entrée pour en sortir un résultat dépendant de leur composante spatiale (forme, localisation).
Dans ce chapitre, nous allons utiliser les packages suivants.
# CRAN
library(mapview)
library(sf)
library(tidyverse)
Nous utiliserons les données de la table des régions de la France métropolitaine et des établissements publics de coopération intercommunale (EPCI)6 de la France Métropolitaine
load("extdata/admin_express.RData")
glimpse(epci_geo)
Rows: 1,241
Columns: 5
$ ID <fct> EPCI00000000000000000001, EPCI00000000000000000002, EPCI0000…
$ CODE_EPCI <fct> 200000172, 200000438, 200000545, 200000628, 200000800, 20000…
$ NOM_EPCI <fct> "CC Faucigny-Glières", "CC du Pays de Pontchâteau Saint-Gild…
$ TYPE_EPCI <fct> CC, CC, CC, CC, CC, CC, CC, CC, CC, CC, CA, CC, CC, CC, CC, …
$ geometry <MULTIPOLYGON [m]> MULTIPOLYGON (((964676 6561..., MULTIPOLYGON ((…
glimpse(departements_geo)
Rows: 96
Columns: 6
$ ID <fct> DEP000000000000000000001, DEP000000000000000000002, DEP00000…
$ NOM_DEP <fct> AIN, HAUTE-CORSE, AISNE, CORSE-DU-SUD, ALLIER, ALPES-DE-HAUT…
$ INSEE_DEP <fct> 01, 2B, 02, 2A, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, …
$ INSEE_REG <fct> 84, 94, 32, 94, 84, 93, 93, 93, 84, 44, 76, 44, 76, 76, 93, …
$ AREA [m^2] 5774813520 [m^2], 4722274798 [m^2], 7419025664 [m^2], 403749…
$ geometry <MULTIPOLYGON [m]> MULTIPOLYGON (((839096 6563..., MULTIPOLYGON ((…
glimpse(regions_geo)
Rows: 13
Columns: 4
$ ID <fct> REG000000000000000000001, REG000000000000000000002, REG00000…
$ NOM_REG <fct> AUVERGNE-RHONE-ALPES, BOURGOGNE-FRANCHE-COMTE, BRETAGNE, CEN…
$ INSEE_REG <fct> 84, 27, 53, 24, 94, 44, 32, 11, 28, 75, 76, 52, 93
$ geometry <MULTIPOLYGON [m]> MULTIPOLYGON (((974065 6594..., MULTIPOLYGON (((880573 6730.…
6.1 Filtrer
Nous souhaitons par exemple filtrer nos EPCI sur les EPCI du département de Loire-Atlantique.
<- departements_geo %>%
departement_44 filter(INSEE_DEP == "44")
<- epci_geo[departement_44, , op = st_within]
epci_d44
mapview(list(departement_44, epci_d44), zcol = list("NOM_DEP", "NOM_EPCI"), legend = FALSE)
L’opération de filtre sur les données spatiales fonctionne en prenant la table en entrée (epci_geo
), la table avec laquelle on souhaite définir les lignes à garder (departement_44
), et l’opérateur qui va définir le test entre les deux géométries. Ici cet opérateur est st_within(x, y)
, qui renvoie TRUE
si la géométrie de x
est contenue à l’intérieur de celle de y
.
On peut spécifier différents prédicats spatiaux pour réaliser ce filtre.
En deuxième argument des [ , , ]
, on peut ajouter, comme dans une opération [
classique de R, les colonnes que l’on souhaite garder.
On peut aussi écrire en tidyverse :
# 1er méthode
<- epci_geo %>%
epci_d44 st_filter(departement_44, .predicate = st_within)
# 2e méthode
<- epci_geo %>%
epci_d44 filter(st_within(., departement_44, sparse = FALSE))
Il faut noter la présence du paramètre sparse = FALSE
.
L’option sparse
est abordée dans la partie Prédicats spatiaux. Il faut retenir que pour utiliser les prédicats à l’intérieur de la fonction filter
, il faut utiliser l’option sparse = FALSE
.
On voit ici que le résultat n’est pas très concluant : il manque 3 EPCI du département, ceux qui sortent des frontières de celui-ci. Prenons un buffer autour du département.
Qu’est ce qu’un buffer ? C’est un tampon qui va nous permettre d’appliquer une transformation sur un objet vectoriel.
A partir d’une couche de départ de type ponctuel, linéaire ou polygonal, le buffer va créer une nouvelle couche vectorielle. La géométrie de cette couche représente des objets surfaciques dont les frontières sont positionnées à une distance euclidienne, définie par l’utilisateur, des limites des objets vectoriels de la couche de départ.
La fonction qui permet de faire cela avec sf
s’appelle st_buffer()
.
st_buffer()
prend en paramètre :
- un objet de classe sf
- une distance dont l’unité est définie par celle de l’objet
sf
, que l’on peut obtenir comme cecist_crs(x)$units
.
<- departement_44 %>%
departement_44_buffer st_buffer(dist = 5000)
mapview(list(departement_44_buffer, departement_44), legend = FALSE,
layer.name = c("Loire-Atlantique avec un buffer de 5 km", "Loire-Atlantique"),
zcol = list("NOM_DEP", "NOM_DEP"), col.regions = list("#440154FF", "#FDE725FF"))
<- epci_geo[departement_44_buffer, , op = st_within]
epci_d44_buffer
mapview(list(departement_44_buffer, epci_d44_buffer), zcol = list("NOM_DEP", "NOM_EPCI"), legend = FALSE)
On récupère 2 des 3 EPCI manquant ainsi. Celui qui manque est l’EPCI de Redon qui est à cheval sur la Loire-Atlantique, le Morbihan et l’Île et Vilaine.
Une méthode pour le récupérer est de prendre l’opérateur de filtre st_intersect
au lieu de st_within
en utilisant un buffer légèrement négatif de notre département pour ne pas récupérer tous les EPCI limitrophes.
<- departement_44 %>%
departement_44_buffer_negatif st_buffer(dist = -2000)
<- epci_geo[departement_44_buffer_negatif, , op = st_intersects]
epci_d44
mapview(list(departement_44, epci_d44), zcol = list("NOM_DEP", "NOM_EPCI"), legend = FALSE)
On aurait pu obtenir le même résultat en prenant les EPCI à l’intérieur du département 44 (avec st_within
) ainsi que les EPCI qui chevauchent (avec st_overlaps
) le département 44.
<- epci_geo %>%
epci_d44 filter(st_within(., departement_44, sparse = FALSE) | st_overlaps(., departement_44, sparse = FALSE))
mapview(list(departement_44, epci_d44), zcol = c("NOM_DEP", "NOM_EPCI"), legend = FALSE)
6.2 Prédicats spatiaux
Les prédicats spatiaux décrivent les relations spatiales entre objets. Pour bien les illustrer, on va utiliser quelques données de notre création.
Nous allons utiliser un polygone (a), des lignes (l) et des points (p), que nous créons à partir de leur coordonnées.
# polygone (a - orange)
<- st_polygon(list(rbind(c(-1, -1), c(1, -1), c(1, 1), c(-1, -1))))
a_poly <- st_sfc(a_poly)
a
# lignes (l - bleues)
<- st_multilinestring(list(rbind(c(0.5, -1), c(-0.5, 1))))
l1 <- st_multilinestring(list(rbind(c(.9, -.9), c(.5, 0))))
l2 <- st_sfc(l1, l2)
l
# multi-points (p - noirs)
<- matrix(c(0.5, 1, -1, 0, 0, 1, 0.5, 1), ncol = 2)
p_matrix <- st_multipoint(x = p_matrix)
p_multi
p_multi<- st_cast(st_sfc(p_multi), "POINT") p
La fonction st_cast
sert à passer d’un type de géométrie à l’autre, ici on transforme un multi-points en points.
A partir de ces objets, on peut se poser les questions suivantes :
Quels sont les points de
p
contenus dans le trianglea
?Quels sont les points de
p
qui ne sont pas contenus dans le trianglea
?Quels sont les points de
p
qui touchent le trianglea
?Quelles sont les lignes de
l
contenues dansa
?
Les prédicats spatiaux servent à répondre à ces questions et sf
contient une liste de fonctions dédiée à l’une ou l’autre de ces questions.
st_intersects()
permet de répondre à la première question, à savoir quels points de p
sont dans a
.
st_intersects(p, a)
Sparse geometry binary predicate list of length 4, where the predicate
was `intersects'
1: 1
2: 1
3: (empty)
4: (empty)
L’opposé de st_intersects()
est st_disjoint()
: st_disjoint(x,y)
renvoie TRUE
pour les objets de x
non reliés à y
.
st_disjoint(p, a)
Sparse geometry binary predicate list of length 4, where the predicate
was `disjoint'
1: (empty)
2: (empty)
3: 1
4: 1
Le résultat de cette opération est une liste. Par défaut, la fonction st_intersect()
renvoie une matrice creuse7. Cette structure permet d’économiser de la mémoire en n’enregistrant que les relations qui existent. Sur une opération de ce type, le gain est peu évident, mais quand on travaille sur des objets plus complexes, le gain est appréciable.
Si on souhaite mieux utiliser cette information, on peut vouloir privilégier la matrice dense, qui renvoie une matrice de booléen pour chaque relation possible.
Pour cela on peut utiliser l’option sparse = FALSE
, ‘sparse’ signifiant en anglais ‘clairsemé’.
st_intersects(p, a, sparse = FALSE)
[,1]
[1,] TRUE
[2,] TRUE
[3,] FALSE
[4,] FALSE
st_within()
est une variante de st_intersect()
qui ne renvoie TRUE
que pour les points strictement à l’intérieur du polygone.
st_within(p, a, sparse = FALSE)
[,1]
[1,] TRUE
[2,] FALSE
[3,] FALSE
[4,] FALSE
Une variante de st_within()
permet d’ajouter un critère de distance pour intégrer des points presque dans le polygone, st_is_within_distance()
.
st_is_within_distance(p, a, dist = 0.8)
Sparse geometry binary predicate list of length 4, where the predicate
was `is_within_distance'
1: 1
2: 1
3: (empty)
4: 1
st_touches()
permet de récupérer les points qui touchent le polygone sans sans être à l’intérieur du polygone.
st_touches(p, a, sparse = FALSE)
[,1]
[1,] FALSE
[2,] TRUE
[3,] FALSE
[4,] FALSE
st_contains(x,y)
est équivalent à st_within(y,x)
. Par exemple si nous voulons savoir lesquelles de nos lignes l
sont contenues dans a
.
st_contains(a, l, sparse = FALSE)
[,1] [,2]
[1,] FALSE TRUE
Equivalent à :
st_within(l, a, sparse = FALSE)
[,1]
[1,] FALSE
[2,] TRUE
st_crosses()
renvoie TRUE si l’intersection des deux géométries est une géométrie de dimension n-1 ou n est le maximum des dimensions des deux objets et si l’intersection est à l’intérieur des deux objets.
st_crosses(l, a, sparse = FALSE)
[,1]
[1,] TRUE
[2,] FALSE
Il existent encore d’autres prédicats qu’on ne détaillera pas ici :
st_covers()
st_covered_by()
st_equals()
etst_equals_exact()
st_contains_properly()
st_overlaps()
6.2.1 Exercice 1 - manipuler des objets sf
Créer un objet contenant les points de p qui intersectent le polygone a, à partir du code suivant :
library(sf)
library(tidyverse)
# polygone (a - orange)
<- st_polygon(list(rbind(c(-1, -1), c(1, -1), c(1, 1), c(-1, -1))))
a_poly <- st_sfc(a_poly)
a # lignes (l - bleues)
<- st_multilinestring(list(rbind(c(0.5, -1), c(-0.5, 1))))
l1 <- st_multilinestring(list(rbind(c(.9, -.9), c(.5, 0))))
l2 <- st_sfc(l1, l2)
l # multi-points (p - noirs)
<- matrix(c(0.5, 1, -1, 0, 0, 1, 0.5, 1), ncol = 2)
p_matrix <- st_multipoint(x = p_matrix)
p_multi <- st_cast(st_sfc(p_multi), "POINT") p
Résultat attendu :
# A tibble: 2 × 1
p
<POINT>
1 (0.5 0)
2 (1 1)
Visualisation graphique :
6.3 Les jointures spatiales
Les jointures attributaires se basent sur un appariement entre une liste des variables présentes dans les deux tables.
Les jointures spatiales se basent sur un appariement géographique, c’est à dire sur un espace géo commun.
6.3.1 Jointure de points avec des polygones
Ce cas est relativement simple, une jointure spatiale entre une liste de points et une liste de polygones va attribuer pour chaque point le ou les polygones auquel il appartient.
On va utiliser ici le fichier sirene du département de Loire Atlantique géocodé par Christian Quest8. Prenons les entreprises de production de sel (code APE ‘0893Z’) sur ce département et regardons dans quelle partie du territoire elles se trouvent.
load("extdata/sirene.RData")
<- sirene44 %>%
sirene44_sel filter(APET700 == "0893Z")
mapview(list(departement_44, epci_d44, sirene44_sel), zcol = list("NOM_DEP", "NOM_EPCI", "NOMEN_LONG"), legend = FALSE)
Nous allons réaliser une jointure spatiale pour récupérer le code sirene de l’EPCI où se trouve chaque entreprise.
<- sirene44_sel %>%
sirene44_sel_avec_code_epci st_join(epci_geo)
mapview(list(departement_44, epci_d44, sirene44_sel_avec_code_epci), zcol = list("NOM_DEP", "NOM_EPCI", "NOM_EPCI"), legend = FALSE)
Une jointure entre deux couches de données géographiques demande à ce que celles-ci partagent la même projection.
6.3.2 Jointure de polygones avec des polygones
A la différence des appariements entre points et polygones, la jointure spatiales entre deux couches de polygones nécessite quelques critères complémentaires : souhaite-t-on joindre deux polygones dès qu’ils s’intersectent ? Souhaite-t-on joindre à un polygone de la première couche à celui de la deuxième avec lequel il partage le plus de surface en commun ?
Par exemple, imaginons que nous voulions joindre notre couche des EPCI avec celle des départements, souhaite-t-on que l’EPCI de Redon se retrouve apparié avec tous les départements auxquels il appartient, ou seulement le département dans lequel il est principalement situé ?
<- epci_d44 %>%
epci_d44_avec_departement st_join(departements_geo %>% st_buffer(dist = -1000))
names(epci_d44_avec_departement)
[1] "ID.x" "CODE_EPCI" "NOM_EPCI" "TYPE_EPCI" "ID.y" "NOM_DEP"
[7] "INSEE_DEP" "INSEE_REG" "AREA" "geometry"
%>%
epci_d44_avec_departement select(NOM_EPCI, NOM_DEP) %>%
group_by(NOM_EPCI) %>%
tally() %>%
arrange(-n)
# A tibble: 17 × 3
NOM_EPCI n geometry
<fct> <int> <MULTIPOLYGON [m]>
1 CA Redon Agglomération 3 (((306620 6741720, 30626…
2 CA de la Presqu'île de Guérande Atlantique (… 2 (((276339 6716135, 27628…
3 CC du Pays d'Ancenis 2 (((371339 6714790, 37131…
4 CA Clisson Sèvre et Maine Agglo 1 (((363286 6675340, 36313…
5 CA de la Région Nazairienne et de l'Estuaire… 1 (((302551 6716906, 30254…
6 CA Pornic Agglo Pays de Retz 1 (((308476 6686309, 30859…
7 CC Châteaubriant-Derval 1 (((352474 6745979, 35243…
8 CC d'Erdre et Gesvres 1 (((344433 6712377, 34443…
9 CC de Grand Lieu 1 (((350722 6678570, 35073…
10 CC de la Région de Blain 1 (((347300 6718329, 34716…
11 CC de Nozay 1 (((348972 6729772, 34899…
12 CC du Pays de Pontchâteau Saint-Gildas-des-B… 1 (((316649 6727168, 31667…
13 CC du Sud-Estuaire 1 (((312929 6700671, 31338…
14 CC Estuaire et Sillon 1 (((321943 6705416, 32193…
15 CC Sèvre et Loire 1 (((369368 6686432, 36928…
16 CC Sud Retz Atlantique 1 (((336398 6673676, 33641…
17 Nantes Métropole 1 (((353637 6695899, 35362…
Une jointure classique va donc rattacher 3 EPCI à plus de 1 département.
Avec l’option largest = TRUE
la jointure va attribuer aux EPCI le département avec lequel il partage le plus de surface.
On voit ici que tout les EPCI adhérents à la Loire-Atlantique se retrouvent alors rattachés à la Loire-Atlantique.
<- epci_d44 %>%
epci_d44_avec_departement st_join(departements_geo %>% st_buffer(dist = -1000), largest = TRUE)
mapview(list(departement_44, epci_d44, sirene44_sel_avec_code_epci), zcol = list("NOM_DEP", "NOM_EPCI", "NOM_EPCI"),
legend = FALSE)
st_join()
utilise par défaut le prédicat st_intersects, dans le paramètrejoin
.Après une jointure spatiale, le dataframe résultat contient la géométrie du jeu de données de gauche (càd le 1er jeu de données passé dans les arguments de
st_join()
).
6.3.3 Exercice 2 : exploitation des données DVF en API
Le but de cet exercice va être d’exploiter les données DVF sur les transactions immobilières dans l’ancien et la carte des quartiers de Nantes pour obtenir des indicateurs des transactions par quartier.
On va utiliser pour DVF l’API mise en place par Christian Quest : http://api.cquest.org/dvf.
## Activation des packages
library(httr)
library(jsonlite)
library(sf)
library(tidyverse)
<- GET("http://api.cquest.org/dvf?code_commune=44109")
get_dvf <- content(get_dvf, "text", encoding = "UTF-8")
dvf_content <- fromJSON(dvf_content)$resultats %>%
dvf_json # On ne garde que les données avec une géolocalisation valide, un prix et une surface renseignés.
filter(!is.na(lon), !is.na(lat), !is.na(valeur_fonciere), !is.na(surface_relle_bati))
<- st_as_sf(dvf_json, coords = c("lon", "lat"), crs = 4326) dvf
- Contour des quartiers de Nantes, ils proviennent de Nantes Métropole Open Data :https://data.nantesmetropole.fr
<- st_read("https://data.nantesmetropole.fr/explore/dataset/244400404_quartiers-communes-nantes-metropole/download/?format=geojson&disjunctive.libcom=true&refine.libcom=Nantes&timezone=Europe/Berlin&lang=fr")
quartier_nantes <- st_set_crs(quartier_nantes, 4326) quartier_nantes
On veut produire les infos suivantes par quartier et année :
- Volume de ventes (nb)
- Pourcentage de maisons dans les ventes
- Prix moyen au m2 par type de bien
Résultat attendu :
Rows: 66
Columns: 8
$ quartier <chr> "Ile de Nantes", "Ile de Nantes", "Ile de Nantes",…
$ annee_mutation <dbl> 2014, 2015, 2016, 2017, 2018, 2019, 2014, 2015, 20…
$ nb_ventes <dbl> 255, 346, 405, 464, 475, 221, 212, 203, 196, 224, …
$ pourcentage_maison <dbl> 1.960784, 2.312139, 2.962963, 1.293103, 1.263158, …
$ prix_m2_appartement <dbl> 4227.436, 2720.641, 3583.049, 3496.280, 3574.651, …
$ prix_m2_maison <dbl> 3208.333, 2961.019, 19695.106, 3519.273, 4144.621,…
$ prix_m2_ensemble <dbl> 4187.948, 2728.811, 4208.121, 3496.700, 3587.453, …
$ geometry <POLYGON [°]> POLYGON ((-1.518491 47.2105..., POLYGON ((…
6.4 Les mesures
Contrairement aux opérations précédentes qui sont binaires, les opérations de mesure sont continues.
6.4.1 Calcul de surface
Le calcul de surface se fait à l’aide de la fonction st_area()
.
Le résultat sera exprimé dans l’unité du crs.
st_area(epci_d44)
Units: [m^2]
[1] 327171752 451105821 311573694 277485664 425120290 884405865 313277739
[8] 995291184 533909100 300537854 214300118 509590978 275642240 865087496
[15] 223059032 396227313 333955602
6.4.2 Matrice de distances
Les distances se calculent avec la fonction st_distance()
.
<- st_centroid(departements_geo) %>%
centres_departements_pdl filter(INSEE_REG == "52")
st_distance(centres_departements_pdl)
Units: [m]
1 2 3 4 5
1 0.00 84564.06 115956.62 159032.47 81705.88
2 84564.06 0.00 84434.09 89195.57 97175.56
3 115956.62 84434.09 0.00 67722.46 170458.60
4 159032.47 89195.57 67722.46 0.00 186168.94
5 81705.88 97175.56 170458.60 186168.94 0.00
Trois choses à noter sur le résultat :
st_distance()
retourne une matrice…… contenant toute les distances calculables 2 à 2…
…et qui a un paramètre
Units
nous donnant l’unité de mesure des distances calculées.
Ici on calcule notre matrice sur un seul objet. Vous pouvez calculer des distances entre deux objets x
et y
de classe sf
.
Dans ce cas il fera le calcul des distances pour toutes les combinaisons possibles d’objets de x
et de y
.
Une option de st_distance()
vous permet de limiter le résultat aux calculs 2 à 2 : by_element = TRUE
.
Dans ce cas le résultat est un vecteur.
6.4.3 Identification du plus proche voisin
Un besoin fréquent en géomatique est d’identifier l’objet le plus proche d’un autre.
La fonction qui permet cela est st_nearest_feature()
.
Prenons l’ensemble des départements français, et trouvons celui de la région qui leur est le plus proche. On va utiliser les centroïdes pour alléger le calcul.
<- st_nearest_feature(
index_dep_pdl
departements_geo,
centres_departements_pdl
)
index_dep_pdl
[1] 4 4 4 4 4 4 4 4 4 4 5 4 5 5 5 3 2 5 5 4 5 4 1 2 5 4 4 4 4 1 5 5 5 5 5 3 4 4
[39] 4 4 5 4 4 2 1 4 5 5 5 2 3 4 4 3 4 4 1 4 4 4 4 3 4 4 5 5 5 4 4 4 4 4 4 4 4 4
[77] 4 4 4 2 4 5 5 2 2 5 2 2 4 4 4 4 4 4 4 4
st_nearest_feature()
renvoie un vecteur d’index en résultat.
Pour visualiser cet index, vous pouvez utiliser ensuite la fonction st_nearest_point()
qui va permettre de faire un lien entre les départements et le département ligérien le plus proche.
st_nearest_point()
permet en effet de renvoyer pour deux géométries la ligne rejoignant les 2 points les plus proches.
<- st_nearest_points(departements_geo,
liens
centres_departements_pdl[index_dep_pdl, ],pairwise = TRUE
)
ggplot() +
geom_sf(data = departements_geo) +
geom_sf(data = liens)
On peut utiliser aussi st_nearest_feature()
comme un mode de jointure des données.
<- st_join(departements_geo,
departements_join
centres_departements_pdl,join = st_nearest_feature
)
ggplot() +
geom_sf(data = departements_join, aes(fill = NOM_DEP.y)) +
labs(
title = "Département ligérien le plus proche de chaque département français",
fill = NULL
)
6.5 Carroyage
6.5.1 Créer une grille régulière
La fonction st_make_grid()
permet de créer une grille régulière à partir d’un objet géo.
Elle produit un objet rectangulaire de type sfc
, il faut ensuite utiliser la fonction st_sf()
pour transformer
cet objet sfc
en objet sf
.
Lors de cette transformation nous rajoutons ici une colonne d’identifiants uniques.
<- st_make_grid(epci_d44, cellsize = 10000) %>%
grille st_as_sf() %>%
rowid_to_column("id")
mapview(grille) + mapview(epci_d44, col.regions = "white", alpha.regions = 0.5)
On constate que plusieurs carreaux sont inutiles. On peut réduire leur nombre avec st_intersects()
comme vu précédemment.
<- grille[epci_d44, , op = st_intersects]
grille_ajustee mapview(grille_ajustee) + mapview(epci_d44, col.regions = "white", alpha.regions = 0.5)
6.5.2 Compter des points dans un polygone
On cherche ici à compter par carreau, le nombre d’entreprises de type “Boulangerie et boulangerie-pâtisserie” (code APE 1071C) du fichier sirene 44 .
<- filter(sirene44, APET700 == "1071C") %>% select(SIREN, NOMEN_LONG)
boul_44 mapview(grille_ajustee) + mapview(epci_d44, col.regions = "white", alpha.regions = 0.5) + mapview(boul_44, col.regions = "grey")
La grille ajustée comprend 113 carreaux. Le 44 comprend 717 boulangeries.
<- st_intersects(grille_ajustee, boul_44, sparse = TRUE)
intersection
dim(intersection)
[1] 113 717
L’objet intersection est une liste de la longueur de l’objet grille_ajustee et chaque élément de la liste contient le ou les index des éléments de l’objet boul_44 qu’il intersecte. Exemple avec le 46e carreau :
46]] intersection[[
[1] 92 359 383 652 653 655
Le 46e carreau comprend les boulangeries des lignes 92, 359, 383, 652, 653, 655 de la table boul_44
.
Pour compter le nombre de boulangeries par carreau, on peut parcourir la liste et reporter la longueur de chacun de ces éléments.
<- mutate(grille_ajustee, nb_boulang = map_dbl(intersection, length))
grille_boul select(grille_boul, nb_boulang) %>%
plot
Une autre solution est de passer par les jointures spatiales :
<- st_join(x = grille_ajustee, y = boul_44) %>%
nb_boul_par_carreau group_by(id) %>%
summarise(nb_boulang = length(SIREN))
select(nb_boul_par_carreau, nb_boulang) %>% plot