Actes techniques CCAM 2025 — activité et dépenses par acte

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("ccam_2025.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", "ccam_2025.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
cc <- d |> mutate(dep_rate = montant_rembourse / base_remboursement)
tot <- cc |> summarise(q = sum(quantite, na.rm = TRUE), b = sum(base_remboursement, na.rm = TRUE),
                       m = sum(montant_rembourse, na.rm = TRUE), n = n_distinct(code_acte))

Actes techniques de la Classification commune des actes médicaux (CCAM) liquidés en 2025 en secteur libéral (cabinets de ville, cliniques privées, centres de santé ; dentistes et sages-femmes inclus), tous régimes du DCIR, données brutes (non extrapolées). Une ligne = un couple acte / activité / phase. 7 616 actes, 364 millions d’actes pour 15,3 Md€ remboursés (base : 19,1 Md€).

Par catégorie d’acte

Code
cc |> group_by(categorie) |> summarise(m = sum(montant_rembourse, na.rm = TRUE), q = sum(quantite, na.rm = TRUE)) |>
  barh(categorie, m) + labs(title = "Montant remboursé par catégorie d'acte, 2025")

Code
cc |> group_by(sous_categorie) |> summarise(m = sum(montant_rembourse, na.rm = TRUE)) |>
  slice_max(m, n = 25) |> barh(sous_categorie, m, fill = col2) +
  labs(title = "25 sous-catégories les plus remboursées")

Les actes les plus fréquents et les plus coûteux

Code
cc |> group_by(code_acte, libelle) |>
  summarise(q = sum(quantite, na.rm = TRUE), m = sum(montant_rembourse, na.rm = TRUE),
            tarif = mean(tarif_optam, na.rm = TRUE), .groups = "drop") |>
  arrange(desc(m)) |> slice_head(n = 25) |>
  transmute(Code = code_acte, Acte = str_trunc(libelle, 90), `Quantité` = q, `Remboursé` = m, `Tarif OPTAM moyen` = tarif) |>
  gt::gt() |> gt::fmt_number(c(`Quantité`, `Remboursé`), decimals = 0, sep_mark = " ") |>
  gt::fmt_number(`Tarif OPTAM moyen`, decimals = 2) |> gt::tab_options(table.width = "100%")
Code Acte Quantité Remboursé Tarif OPTAM moyen
HBJD001 Détartrage et polissage des dents 41 359 124 584 577 925 28.92
DZQM006 Échographie-doppler transthoracique du coeur et des vaisseaux intrathoraciques 5 648 098 481 065 126 96.25
BZQK001 Tomographie unilatérale ou bilatérale de l'oeil par scanographie à cohérence optique 11 282 587 468 272 811 57.68
YYYY166 Supplément pour contrôles balistiques de qualité en radiothérapie par imagerie portale 1 681 599 389 062 112 23.80
BFGA427 Extraction extracapsulaire du cristallin par phakoémulsification, avec implantation de ... 1 637 691 324 243 707 191.35
YYYY491 Irradiation de 300 cm² et plus en champs fixes par accélérateur par fraction de 20 Gra... 146 174 286 195 439 634.60
HBMD038 Restauration d'une dent d'un secteur prémolomolaire sur 3 faces ou plus par matériau in... 4 912 266 222 678 101 68.12
HBMD049 Restauration d'une dent d'un secteur prémolomolaire sur 2 faces par matériau inséré en ... 6 278 161 221 096 334 52.00
GLQP002 Mesure de la capacité vitale lente et de l'expiration forcée, avec mesure des volumes p... 2 411 313 147 309 324 76.80
GLQP007 Polygraphie respiratoire nocturne 1 000 264 146 179 719 148.80
BGQP002 Examen du fond d'oeil par biomicroscopie avec verre de contact 8 507 901 133 770 741 28.68
HBLD090 Pose d'une infrastructure coronoradiculaire [Inlay core] sous une couronne ou un pilier... 2 326 378 132 837 106 90.00
HBMD053 Restauration d'une dent d'un secteur prémolomolaire sur 1 face par matériau inséré en p... 6 299 978 132 046 310 30.47
DAQL009 Tomoscintigraphie de perfusion myocardique de repos, avec tomoscintigraphie de perfusio... 272 647 128 593 168 472.72
BJQP002 Examen fonctionnel de la motricité oculaire 6 866 033 120 236 145 26.63
EBQM002 Échographie-doppler des artères cervicocéphaliques extracrâniennes, avec échographie-do... 1 246 086 116 738 802 100.97
QEQK004 Mammographie de dépistage 2 409 216 114 810 373 66.42
HBQK002 Radiographie panoramique dentomaxillaire 9 224 078 114 594 298 20.00
HBLD018 Pose d'un plan de libération occlusale 658 214 113 285 454 172.80
HBLD350 Pose d'une couronne dentaire dentoportée céramique-monolithique zircone sur une dent au... 1 476 283 112 001 163 120.00
QEQK001 Mammographie bilatérale 2 201 258 110 055 583 66.42
HBLD634 Pose d'une couronne dentaire dentoportée céramométallique sur une incisive, une canine ... 1 372 937 105 319 657 120.00
LHQN001 Remnographie [IRM] d'un ou de deux segments de la colonne vertébrale et de son contenu,... 1 897 455 98 070 416 69.00
ALQP003 Test d'évaluation d'une dépression 1 703 010 96 200 164 69.12
BLQP010 Examen de la vision binoculaire 9 355 546 95 441 397 25.67

Concentration de la dépense

Code
l <- cc |> group_by(code_acte) |> summarise(m = sum(montant_rembourse, na.rm = TRUE)) |>
  arrange(desc(m)) |> mutate(rang = row_number() / n(), cum = cumsum(m) / sum(m))
ggplot(l, aes(rang, cum)) + geom_line(colour = col1, linewidth = 1) +
  geom_abline(slope = 1, linetype = 2, colour = "grey50") +
  scale_x_continuous(labels = scales::label_percent()) + scale_y_continuous(labels = scales::label_percent()) +
  labs(x = "Part des actes (classés par montant décroissant)", y = "Part cumulée du remboursé",
       title = "Courbe de concentration des dépenses d'actes CCAM") + theme_cnam

Les 10 % d’actes les plus coûteux représentent 92,7% du remboursé ; les 100 premiers actes 58,5%.

Tarifs : secteur 1/OPTAM versus secteur 2 hors OPTAM

Code
cc |> filter(quantite > 5000, tarif_optam > 0) |>
  mutate(ratio = tarif_hors_optam / tarif_optam) |>
  ggplot(aes(tarif_optam, ratio)) + geom_point(alpha = 0.5, colour = col1) +
  scale_x_log10() + scale_y_continuous(labels = scales::label_percent(accuracy = 1)) +
  geom_hline(yintercept = 1, linetype = 2) +
  labs(x = "Tarif OPTAM/secteur 1 (€, échelle log)", y = "Tarif secteur 2 hors OPTAM / tarif OPTAM",
       title = "Écart de tarif opposable entre secteur 2 non adhérent et OPTAM", subtitle = "actes > 5 000 réalisations") +
  theme_cnam

Le taux de remboursement effectif (remboursé / base) moyen est de 80,3% (les participations forfaitaires ne sont pas déduites dans ce fichier) ; il diffère du taux légal de 70 % en raison des actes exonérés (ALD, maternité) et des actes à 100 %.

Source

Caisse nationale de l’Assurance Maladie (Cnam) — Cnam (SNDS) — Actes techniques de la CCAM, série annuelle 2025. Conversion Excel → Parquet : cnam.R (dossier data/cnam).