LPP-AM — agrégats par nature de prestation et nomenclature

Données - Assurance Maladie (Cnam)

Code
source(here::here("_rinit.R"))
invisible(Sys.setlocale("LC_TIME", "fr_FR.UTF-8"))
# cd ~/iCloud/website/data/cnam; /usr/local/bin/R -e 'quarto::quarto_render("lpp_agregats.qmd")'
# (données : Rscript --vanilla cnam.R)

knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE,
                      fig.width = 9, fig.height = 5.5, dpi = 150)
library(dplyr); library(tidyr); library(ggplot2); library(stringr)

path <- here::here("data", "cnam", "lpp_agregats.parquet")
d <- arrow::read_parquet(path)

mdd <- scales::label_number(scale = 1e-9, suffix = " Md€", accuracy = 0.1, big.mark = " ", decimal.mark = ",")
mde <- scales::label_number(scale = 1e-6, suffix = " M€", accuracy = 1, big.mark = " ", decimal.mark = ",")
pct <- scales::label_percent(accuracy = 0.1, decimal.mark = ",")
nb  <- scales::label_number(big.mark = " ", decimal.mark = ",")

theme_cnam <- theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", size = 13), plot.title.position = "plot",
        plot.subtitle = element_text(colour = "grey35"),
        panel.grid.minor = element_blank(), legend.position = "bottom")
col1 <- "#1b7f79"; col2 <- "#c0392b"

# barres horizontales triées
barh <- function(df, lab, val, fmt = mdd, fill = col1, ...) {
  df |>
    mutate(.l = forcats::fct_reorder({{ lab }}, {{ val }})) |>
    ggplot(aes(.l, {{ val }})) +
    geom_col(fill = fill, ...) +
    geom_text(aes(label = fmt({{ val }})), hjust = -0.08, size = 3) +
    coord_flip() +
    scale_y_continuous(labels = fmt, expand = expansion(mult = c(0, 0.2))) +
    labs(x = NULL, y = NULL) + theme_cnam
}
Code
agr <- d

Agrégats officiels de la Cnam extraits du fichier LPP-AM 2016-2025 : nature de prestation (NAT_PREST — le champ inclut ici les appareils générateurs d’aérosol, orthoprothèses et orthèses non codés) et trois niveaux de la nomenclature TS (TS1 : chapitres, TS2 : sections, TS3 : sous-sections, champ limité aux dispositifs médicaux). Colonne niveau : NAT_PREST, TS1, TS2, TS3.

Par nature de prestation

Code
nat <- agr |> filter(niveau == "NAT_PREST")
nat |> filter(annee == 2025) |> mutate(l = paste0(code, " — ", str_to_sentence(str_trunc(libelle, 50)))) |>
  slice_max(montant_rembourse, n = 20) |>
  barh(l, montant_rembourse) + labs(title = "Nature de prestation : montant remboursé 2025 (top 20)")

Code
top6 <- nat |> filter(annee == 2025) |> slice_max(montant_rembourse, n = 6) |> pull(code)
nat |> filter(code %in% top6) |> mutate(l = str_to_sentence(str_trunc(libelle, 40))) |>
  ggplot(aes(annee, montant_rembourse, colour = l)) + geom_line(linewidth = 1) + geom_point() +
  scale_x_continuous(breaks = 2016:2025) + scale_y_continuous(labels = mdd) +
  labs(x = NULL, y = NULL, colour = NULL, title = "Six premières natures de prestation, 2016-2025") +
  theme_cnam + guides(colour = guide_legend(nrow = 3))

Le taux de prise en charge selon la nature

Code
nat |> filter(annee == 2025, montant_remboursable > 5e7) |>
  mutate(taux = montant_rembourse / montant_remboursable, l = paste0(code, " — ", str_to_sentence(str_trunc(libelle, 50)))) |>
  barh(l, taux, fmt = pct, fill = "#8e6cb8") +
  labs(title = "Taux de remboursement (remboursé / remboursable), natures > 50 M€, 2025")

Chapitres de la nomenclature (TS1)

Code
agr |> filter(niveau == "TS1") |>
  mutate(l = paste0(code, " — ", str_to_sentence(libelle))) |>
  ggplot(aes(annee, montant_rembourse, fill = l)) + geom_col() +
  scale_x_continuous(breaks = 2016:2025) + scale_y_continuous(labels = mdd) +
  labs(x = NULL, y = NULL, fill = NULL, title = "TS1 : montant remboursé") +
  theme_cnam + guides(fill = guide_legend(ncol = 2))

Évolution annuelle du remboursé (tous niveaux TS3)

Code
agr |> filter(niveau == "TS3") |> group_by(code, libelle, annee) |>
  summarise(m = sum(montant_rembourse, na.rm = TRUE), .groups = "drop") |>
  filter(annee %in% c(2016, 2019, 2022, 2025)) |> pivot_wider(names_from = annee, values_from = m) |>
  mutate(`TCAM 2016-25` = (`2025` / `2016`)^(1 / 9) - 1) |>
  filter(`2025` > 1.5e8) |> arrange(desc(`2025`)) |>
  gt::gt() |> gt::fmt_number(matches("^20"), decimals = 0, sep_mark = " ") |>
  gt::fmt_percent(`TCAM 2016-25`, decimals = 1) |> gt::tab_options(table.width = "100%")
code libelle 2016 2019 2022 2025 TCAM 2016-25
R20A Pression positive continue pour apnée du sommeil, prestation seule 585 655 002 755 633 150 852 480 148 1 100 482 588 7.3%
H60B Autocontrôle du glucose interstitiel, consommable dont capteurs et transmetteurs 0 197 949 883 367 353 618 583 063 926 Inf%
A10B Nutriments pour supplémentation orale, adulte 293 005 450 317 419 769 353 241 333 405 457 787 3.7%
S40B Audioprothèses, plus 20 ans 83 391 139 147 848 228 382 978 499 400 262 437 19.0%
D10A Pansements hydrocellulaires 296 636 714 329 086 254 370 636 574 380 859 975 2.8%
T10A Perfusion, diffuseurs portables et divers 188 633 779 231 829 700 249 972 673 332 849 777 6.5%
T30A Lits médicaux, location 278 745 804 292 552 176 309 003 132 312 774 049 1.3%
G30B Génito-urinaire, matériel pour sondage vésical 191 234 618 222 739 245 248 018 687 277 814 149 4.2%
R10A Oxygénothérapie seule, long terme gazeux 133 936 417 197 146 525 242 947 738 272 953 163 8.2%
M20 Implants orthopédiques du genou 186 607 177 195 656 963 202 619 213 237 598 429 2.7%
R30B Traitements respiratoires, prestations avec oxygène 227 211 650 200 424 877 225 331 361 233 526 217 0.3%
K20A VPH Achat neuf 133 903 702 168 001 687 168 985 813 206 744 951 4.9%
H20B Autotraitement du diabète, pompes externes sans tubulure 6 151 567 149 736 569 210 020 782 202 859 279 47.5%
H10E Autocontrôle de la glycémie/corps cétoniques, bandelettes et autres 416 133 423 347 124 020 308 076 905 197 472 339 −7.9%
O20A Attelles (correction orthopédique) 111 486 637 138 148 940 159 263 763 185 265 139 5.8%
H50B Boucle semi-fermée, capteurs, transmetteurs, algorithme 0 0 3 830 230 178 122 807 Inf%
R30A Traitements respiratoires, autres prestations seules (ventilation) 139 038 119 146 621 282 163 324 679 173 600 929 2.5%
T20B Perfusion, pompes externes, sauf insuline, consommables 62 807 642 68 947 584 145 326 955 170 370 162 11.7%
M30 Implants orthopédiques de la hanche 170 298 043 146 247 797 154 653 289 169 185 407 −0.1%

Source

Caisse nationale de l’Assurance Maladie (Cnam) — Cnam — LPP-AM 2016-2025 (onglets NAT_PREST, TS1, TS2, TS3). Conversion Excel → Parquet : cnam.R (dossier data/cnam).