Code
source (here:: here ("_rinit.R" ))
invisible (Sys.setlocale ("LC_TIME" , "fr_FR.UTF-8" ))
# cd ~/iCloud/website/data/ssmsi; /usr/local/bin/R -e 'quarto::quarto_render("delinquance-communale.qmd")'
knitr:: opts_chunk$ set (echo = TRUE , message = FALSE , warning = FALSE ,
fig.width = 9 , fig.height = 5.5 , dpi = 150 )
com_path <- here:: here ("data" , "ssmsi" , "delinquance-communale.parquet" )
com <- arrow:: read_parquet (com_path) |>
dplyr:: mutate (
indicateur = as.character (indicateur),
dept = dplyr:: if_else (substr (CODGEO_2026, 1 , 2 ) == "97" ,
substr (CODGEO_2026, 1 , 3 ), substr (CODGEO_2026, 1 , 2 ))
)
n_com <- dplyr:: n_distinct (com$ CODGEO_2026)
n_ind <- dplyr:: n_distinct (com$ indicateur)
annees <- range (com$ annee)
part_nd <- mean (com$ est_diffuse == "ndiff" )
theme_barres <- theme_minimal (base_size = 12 ) +
theme (plot.title = element_text (face = "bold" ),
plot.subtitle = element_text (colour = "grey35" ),
panel.grid.minor = element_blank ())
Nombre de faits (infractions , victimes , véhicules ou mis en cause selon l’indicateur) et taux pour 1 000 habitants de la délinquance enregistrée par la police et la gendarmerie, par commune (géographie 2026), pour 15 indicateurs et de 2016 à 2025 — 5 238 000 lignes couvrant 34 920 communes.
Pour préserver le secret statistique, 46% des lignes ne sont pas diffusées (est_diffuse == "ndiff", faible effectif) : les totaux ci-dessous, calculés sur les seules valeurs diffusées, sont donc légèrement sous-estimés, surtout pour les petites communes et les infractions rares.
Code
com |>
dplyr:: group_by (Indicateur = indicateur, ` Unité de compte ` = as.character (unite_de_compte)) |>
dplyr:: summarise (
` Communes diffusées ` = dplyr:: n_distinct (CODGEO_2026[est_diffuse == "diff" ]),
` Faits, 1re année ` = sum (nombre[annee == annees[1 ]], na.rm = TRUE ),
` Faits, dernière année ` = sum (nombre[annee == annees[2 ]], na.rm = TRUE ),
.groups = "drop"
) |>
gt:: gt () |>
gt:: fmt_number (columns = c (` Communes diffusées ` , ` Faits, 1re année ` , ` Faits, dernière année ` ),
decimals = 0 , sep_mark = " " ) |>
gt:: tab_spanner (label = sprintf ("%d → %d" , annees[1 ], annees[2 ]),
columns = c (` Faits, 1re année ` , ` Faits, dernière année ` )) |>
gt:: tab_options (table.width = "100%" )
Faits, 1re année
Faits, dernière année
Cambriolages de logement
Infraction
20 925
220 352
177 024
Destructions et dégradations volontaires
Infraction
19 872
626 560
527 271
Escroqueries et fraudes aux moyens de paiement
Victime
19 804
237 517
422 464
Trafic de stupéfiants
Mis en cause
32 952
33 158
56 956
Usage de stupéfiants
Mis en cause
28 981
171 681
327 054
Usage de stupéfiants (AFD)
Mis en cause
34 920
0
232 503
Violences physiques hors cadre familial
Victime
27 851
157 676
205 272
Violences physiques intrafamiliales
Victime
24 203
93 226
219 961
Violences sexuelles
Victime
27 464
38 383
105 362
Vols avec armes
Infraction
34 058
9 022
5 948
Vols d'accessoires sur véhicules
Véhicule
28 182
87 956
79 673
Vols dans les véhicules
Véhicule
27 485
272 531
241 728
Vols de véhicule
Véhicule
26 407
154 283
109 268
Vols sans violence contre des personnes
Victime entendue
21 470
838 286
716 898
Vols violents sans arme
Infraction
33 262
112 135
56 582
Évolution nationale par indicateur
Code
com |>
dplyr:: group_by (indicateur, annee) |>
dplyr:: summarise (n = sum (nombre, na.rm = TRUE ), .groups = "drop" ) |>
ggplot (aes (annee, n)) +
geom_col (fill = "#c0392b" , width = 0.7 ) +
facet_wrap (~ stringr:: str_wrap (indicateur, 30 ), scales = "free_y" , ncol = 3 ) +
scale_x_continuous (breaks = scales:: breaks_width (2 )) +
scale_y_continuous (labels = scales:: label_number (big.mark = " " , scale_cut = scales:: cut_short_scale ())) +
labs (title = "Faits enregistrés par an (somme des communes diffusées)" ,
subtitle = "France entière ; les faits non diffusés ne sont pas comptés" ,
x = NULL , y = NULL ) +
theme_barres +
theme (strip.text = element_text (size = 8 , face = "bold" ),
axis.text = element_text (size = 7 ))
Taux départemental — violences physiques intrafamiliales
Code
ind_sel <- "Violences physiques intrafamiliales"
an_sel <- annees[2 ]
pop_dep <- com |>
dplyr:: filter (annee == an_sel) |>
dplyr:: distinct (CODGEO_2026, dept, insee_pop) |>
dplyr:: group_by (dept) |>
dplyr:: summarise (pop = sum (insee_pop, na.rm = TRUE ), .groups = "drop" )
com |>
dplyr:: filter (annee == an_sel, indicateur == ind_sel) |>
dplyr:: group_by (dept) |>
dplyr:: summarise (faits = sum (nombre, na.rm = TRUE ), .groups = "drop" ) |>
dplyr:: inner_join (pop_dep, by = "dept" ) |>
dplyr:: filter (pop > 0 ) |>
dplyr:: mutate (taux = faits / pop * 1000 ,
dept = forcats:: fct_reorder (dept, taux)) |>
dplyr:: slice_max (taux, n = 25 ) |>
ggplot (aes (taux, dept)) +
geom_col (fill = "#3b6f8a" , width = 0.75 ) +
geom_text (aes (label = sprintf ("%.1f" , taux)), hjust = - 0.15 , size = 2.9 ) +
scale_x_continuous (expand = expansion (mult = c (0 , 0.12 ))) +
labs (title = sprintf ("%s — %d" , ind_sel, an_sel),
subtitle = "Victimes pour 1 000 habitants · 25 départements les plus élevés" ,
x = "pour 1 000 habitants" , y = NULL ) +
theme_barres +
theme (panel.grid.major.y = element_blank ())
Agrégats départementaux (table)
Code
pop_all <- com |>
dplyr:: distinct (CODGEO_2026, dept, annee, insee_pop) |>
dplyr:: group_by (dept, annee) |>
dplyr:: summarise (pop = sum (insee_pop, na.rm = TRUE ), .groups = "drop" )
com |>
dplyr:: group_by (dept, annee, indicateur, unite_de_compte) |>
dplyr:: summarise (faits = sum (nombre, na.rm = TRUE ), .groups = "drop" ) |>
dplyr:: left_join (pop_all, by = c ("dept" , "annee" )) |>
dplyr:: transmute (Dépt = dept, Année = annee, Indicateur = indicateur,
` Unité ` = as.character (unite_de_compte), Faits = faits,
` Pour 1000 hab. ` = round (faits / pop * 1000 , 2 )) |>
dplyr:: arrange (dplyr:: desc (Année), Dépt, Indicateur) |>
reactable:: reactable (
searchable = TRUE , filterable = TRUE , pagination = TRUE ,
defaultPageSize = 20 , compact = TRUE , resizable = TRUE , highlight = TRUE , wrap = TRUE ,
defaultColDef = reactable:: colDef (
align = "left" , headerStyle = list (fontWeight = "bold" ),
style = list (whiteSpace = "normal" , wordBreak = "break-word" )),
columns = list (
Dépt = reactable:: colDef (minWidth = 55 , maxWidth = 80 ),
Année = reactable:: colDef (minWidth = 55 , maxWidth = 80 , align = "right" ),
Indicateur = reactable:: colDef (minWidth = 200 ),
` Unité ` = reactable:: colDef (minWidth = 90 , maxWidth = 140 ),
Faits = reactable:: colDef (minWidth = 70 , maxWidth = 110 , align = "right" ,
format = reactable:: colFormat (separators = TRUE )),
` Pour 1000 hab. ` = reactable:: colDef (minWidth = 80 , maxWidth = 120 , align = "right" ))
)
Le détail commune par commune (5,2 M lignes) reste dans le fichier Parquet source.
Source & données
Code
tibble:: tibble (
` ` = c ("Jeu de données" , "Producteur" , "Licence" , "Fichier" , "Mise à jour" , "Observations" ),
` ` = c (
"[Bases statistiques communale, départementale et régionale de la délinquance enregistrée](https://www.data.gouv.fr/datasets/bases-statistiques-communale-departementale-et-regionale-de-la-delinquance-enregistree-par-la-police-et-la-gendarmerie-nationales/) — ressource « COM » (parquet)" ,
"Service statistique ministériel de la sécurité intérieure (SSMSI) — ministère de l'Intérieur" ,
"Licence Ouverte / Open Licence 2.0 (Etalab)" ,
sprintf ("`data/ssmsi/delinquance-communale.parquet` (%s Mo)" , round (file.size (com_path) / 1024 ^ 2 , 1 )),
format (as.Date (file.mtime (com_path)), "%d %B %Y" ),
sprintf ("%s lignes · %s communes · %d indicateurs · %d–%d" ,
format (nrow (com), big.mark = " " ), format (n_com, big.mark = " " ),
n_ind, annees[1 ], annees[2 ])
)
) |>
gt:: gt () |> gt:: fmt_markdown (columns = ` ` ) |>
gt:: tab_options (table.width = "100%" , column_labels.hidden = TRUE )
Jeu de données
Bases statistiques communale, départementale et régionale de la délinquance enregistrée — ressource « COM » (parquet)
Producteur
Service statistique ministériel de la sécurité intérieure (SSMSI) — ministère de l’Intérieur
Licence
Licence Ouverte / Open Licence 2.0 (Etalab)
Fichier
data/ssmsi/delinquance-communale.parquet (15.3 Mo)
Mise à jour
05 septembre 2026
Observations
5 238 000 lignes · 34 920 communes · 15 indicateurs · 2016–2025