Taux moyens de remboursement par prestation (juillet 2026)

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("resultats_taux.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", "resultats_taux.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
t <- d |> mutate(per = case_when(str_detect(periode, "DECEMBRE") ~ "2025 (année)",
                                 str_detect(periode, "^JANVIER à JUILLET") ~ "Janv.-juil. 2026",
                                 TRUE ~ "Juillet 2026"),
                 per = factor(per, c("2025 (année)", "Janv.-juil. 2026", "Juillet 2026")),
                 is_total = str_detect(prestation, "^TOTAL"))

Taux moyens de remboursement par prestation de soins de ville (rapport du montant remboursé à la base de remboursement, en %), pour trois périodes : l’année 2025, le mois de juillet 2026 et le cumul janvier-juillet 2026. Le taux reflète à la fois le taux légal (70 % pour les consultations et les actes médicaux, 60 % pour l’auxiliaire médical…) et la part des assurés exonérés (ALD, maternité, accidents du travail) : il dépasse donc largement les taux légaux.

Les totaux par profession

Code
t |> filter(is_total, per %in% c("2025 (année)", "Janv.-juil. 2026")) |>
  mutate(l = forcats::fct_reorder(str_remove(prestation, "^TOTAL "), taux_remboursement_pct, max)) |>
  ggplot(aes(l, taux_remboursement_pct, fill = per)) + geom_col(position = "dodge") + coord_flip() +
  scale_fill_manual(values = c("grey65", col1)) +
  labs(x = NULL, y = "Taux moyen de remboursement (%)", fill = NULL, title = "Taux de remboursement moyen par grande catégorie") + theme_cnam

Évolution 2025 → 2026 (cumul)

Code
t |> filter(per %in% c("2025 (année)", "Janv.-juil. 2026")) |>
  select(section, prestation, per, taux_remboursement_pct) |>
  pivot_wider(names_from = per, values_from = taux_remboursement_pct, values_fn = mean) |>
  mutate(diff = `Janv.-juil. 2026` - `2025 (année)`) |> filter(!is.na(diff)) |>
  slice_max(abs(diff), n = 20) |>
  mutate(l = forcats::fct_reorder(paste0(str_trunc(prestation, 40), " [", str_trunc(section, 20), "]"), diff)) |>
  ggplot(aes(l, diff, fill = diff > 0)) + geom_col(show.legend = FALSE) + coord_flip() +
  scale_fill_manual(values = c(`TRUE` = col1, `FALSE` = col2)) +
  labs(x = NULL, y = "Écart de taux (points de %)", title = "Plus forts changements de taux moyen, 2025 → janv.-juil. 2026") + theme_cnam

Les plus fortes variations concernent des postes de faible volume (petits dénominateurs) ou soumis à des réformes tarifaires (revalorisations) : à lire avec prudence.

Explorer

Code
t |> select(section, prestation, per, taux_remboursement_pct) |>
  pivot_wider(names_from = per, values_from = taux_remboursement_pct, values_fn = mean) |>
  reactable::reactable(searchable = TRUE, filterable = TRUE, defaultPageSize = 20, compact = TRUE,
    columns = list(section = reactable::colDef(name = "Catégorie", minWidth = 180), prestation = reactable::colDef(name = "Prestation", minWidth = 260),
      `2025 (année)` = reactable::colDef(format = reactable::colFormat(digits = 1)),
      `Janv.-juil. 2026` = reactable::colDef(format = reactable::colFormat(digits = 1)),
      `Juillet 2026` = reactable::colDef(format = reactable::colFormat(digits = 1))))

Source

Caisse nationale de l’Assurance Maladie (Cnam) — Cnam (SNDS) — « Résultats à fin juillet 2026 », onglet TAUX. Conversion Excel → Parquet : cnam.R (dossier data/cnam).