Bike accidents

Days 20 & 21 of 30DayMapChallenge. OSM & conflicts
R
spatial
datavisualization
30DayMapChallenge
OSM
Author

Michaël

Published

2024-11-21

Modified

2024-11-22

A photo of a crashed bike

Ciclista atropellado – CC-BY by Nicanor Arenas Bermejo

Day 20 & 21 of 30DayMapChallenge: « OpenStreetMap » and « Conflict » (previously).

Mapping the accidents between bicycles and cars in 2023 in France. We have had a few sad accidents recently showing a growing attention on cyclist security and the conflicts on the road.

We’ll use the Annual databases of road traffic injuries on an OSM background.

Config

library(dplyr)
library(tidyr)
library(readr)
library(janitor)
library(sf)
library(glue)
library(leaflet)

Data

The data guide is available (in french).

# vehicules-2023.csv
vehicles <- read_csv2(
  "https://www.data.gouv.fr/fr/datasets/r/146a42f5-19f0-4b3e-a887-5cd8fbef057b", 
  name_repair = make_clean_names) 

# caract-2023.csv
caract <- read_csv2(
  "https://www.data.gouv.fr/fr/datasets/r/104dbb32-704f-4e99-a71e-43563cb604f2", 
  name_repair = make_clean_names)

# usagers-2023.csv
user <- read_csv2(
  "https://www.data.gouv.fr/fr/datasets/r/68848e2a-28dd-4efc-9d5f-d512f7dbe66f", 
  name_repair = make_clean_names)

severity <- tribble(
    ~grav, ~severity,
        1, "Unharmed",
        2, "Killed",
        3, "Injured hospitalized",
        4, "Slightly injured") |> 
  mutate(severity = factor(
    severity, 
    labels = c("Killed",
               "Injured hospitalized",
               "Slightly injured",
               "Unharmed")))

Find out

# accidents where car and bikes are involved
bike_car_acc <- vehicles |> 
  filter(catv %in% c(1, 7)) |> # 1: bike ; 7: car
  count(num_acc, catv) |> 
  pivot_wider(names_from = catv, 
              values_from = n, 
              names_prefix = "catv_") |> 
  filter(catv_7 > 0 & catv_1 > 0) |> 
  pull(num_acc)

# bikers injuries
bikers <- vehicles |> 
  filter(num_acc %in% bike_car_acc,
         catv == 1) |>
  left_join(user, join_by(num_acc, id_vehicule)) |> 
  left_join(severity, join_by(grav)) |> 
  count(num_acc, severity) 

bikers_display <- bikers |> 
  mutate(outcome = glue("{severity} ({n})")) |> 
  arrange(severity) |> 
  summarise(.by = num_acc,
            outcome = glue_collapse(outcome, sep = "<br />"))

# accident locations
bike_accidents <- caract |> 
  filter(num_acc %in% bike_car_acc) |> 
  st_as_sf(coords = c("long", "lat"), crs = "EPSG:4326") |> 
  mutate(date = as.Date(glue("{an}-{mois}-{jour}"))) |> 
  left_join(bikers_display, join_by(num_acc))

n_accidents <- nrow(bikers_display)
n_killed <- bikers |> 
  filter(severity == "Killed") |> 
  summarise(n = sum(n)) |> 
  pull(n)

That’s 2858 accidents and 772 bikers killed (only with cars, not counting accidents with vans, lorries,…).

Map

bike_accidents |> 
  leaflet() |> 
  addTiles(attribution = r"(
           <a href="https://r.iresmi.net/">r.iresmi.net</a>.
           data: Ministère de l'intérieur 2023;
           map: <a href="https://www.openstreetmap.org/copyright/">OpenStreetMap</a>)") |> 
  addCircleMarkers(popup = ~ glue("<b>{date}</b><br /><br />
                                  biker status:<br />
                                  {outcome}"),
                   clusterOptions = markerClusterOptions())
Figure 1: Bike accidents with cars in France – 2023