Indice de position sociale des écoles (IPS)

Données - DEPP (Éducation nationale)

Code
source(here::here("_rinit.R"))
source(here::here("code", "basic_functions.R"))   # dataset_info_lines(), related_data()
invisible(Sys.setlocale("LC_TIME", "fr_FR.UTF-8"))
suppressMessages(library(sf))
# cd ~/iCloud/website/data/depp; /usr/local/bin/R -e 'quarto::quarto_render("fr-en-ips-ecoles-ap2022.qmd")'

knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE,
                      fig.width = 8, fig.height = 4.8, dpi = 150)

ips_path <- here::here("data", "depp", "fr-en-ips-ecoles-ap2022.parquet")
ips <- arrow::read_parquet(ips_path) |>
  dplyr::mutate(
    annee   = as.integer(substr(rentree_scolaire, 1, 4)),
    ips     = suppressWarnings(as.numeric(ips)),
    secteur = dplyr::recode(secteur, public = "Public",
                            `privé sous contrat` = "Privé sous contrat"),
    arr     = dplyr::if_else(grepl("^PARIS \\d", nom_de_la_commune),
                             as.integer(stringr::str_extract(nom_de_la_commune, "\\d+")), NA_integer_)
  ) |>
  dplyr::filter(!is.na(ips))

an      <- max(ips$annee)
paris   <- dplyr::filter(ips, departement == "PARIS", !is.na(arr))
paris14 <- dplyr::filter(paris, arr == 14)

theme_depp <- ggplot2::theme_minimal(base_size = 12) +
  ggplot2::theme(plot.title    = ggplot2::element_text(face = "bold"),
                 plot.subtitle = ggplot2::element_text(colour = "grey35"),
                 panel.grid.minor = ggplot2::element_blank(),
                 plot.title.position = "plot",
                 legend.position = "bottom")
pal_secteur <- c("Public" = "#2b6cb0", "Privé sous contrat" = "#dd6b20")

wkb2sfc <- function(x) sf::st_as_sfc(structure(lapply(x, as.raw), class = "WKB"), EWKB = FALSE)
arr_sf <- arrow::read_parquet(here::here("data", "paris", "arrondissements.parquet")) |>
  dplyr::transmute(arr = as.integer(c_ar), geometry = wkb2sfc(geom)) |>
  sf::st_as_sf(crs = 4326)

L’indice de position sociale (IPS) des écoles élémentaires, sur le même principe que pour les collèges : un score du milieu social des familles, calé autour de 106 en moyenne nationale. La ségrégation sociale entre établissements est déjà installée à l’école primaire — avant même le choix du collège.

Rentrées 2022 à 2024 ; 30 636 écoles publiques et privées sous contrat.

Paris

Code
paris |> dplyr::filter(annee == an) |>
  dplyr::group_by(arr) |> dplyr::summarise(ips = mean(ips, na.rm = TRUE), .groups = "drop") |>
  {\(x) dplyr::left_join(arr_sf, x, by = "arr")}() |>
  ggplot() +
  geom_sf(aes(fill = ips), colour = "white", linewidth = 0.3) +
  geom_sf_text(aes(label = arr), size = 3, colour = "grey20") +
  geom_sf(data = dplyr::filter(arr_sf, arr == 14), fill = NA, colour = "black", linewidth = 0.8) +
  scale_fill_gradient(low = "#f0e6d8", high = "#5a3e8c", name = "IPS moyen") +
  labs(title = sprintf("IPS moyen des écoles par arrondissement (%d)", an),
       subtitle = "Le 14e est encadré · du ~108 (18e, 19e) au ~145 (5e, 6e)") +
  theme_void(base_size = 12) +
  ggplot2::theme(plot.title = ggplot2::element_text(face = "bold"),
                 plot.subtitle = ggplot2::element_text(colour = "grey35"),
                 plot.title.position = "plot")

Code
paris |>
  dplyr::filter(annee == an) |>
  dplyr::mutate(arr = factor(arr, levels = 1:20)) |>
  ggplot(aes(ips, arr, colour = secteur)) +
  geom_vline(xintercept = 106, linetype = "dashed", colour = "grey55") +
  geom_point(size = 2, alpha = 0.7, position = position_jitter(height = 0.15, seed = 1)) +
  scale_colour_manual(values = pal_secteur, name = NULL) +
  scale_y_discrete(limits = rev) +
  labs(title = "Chaque école parisienne selon son IPS et son arrondissement",
       subtitle = sprintf("Rentrée %d · le privé sous contrat recrute presque partout au-dessus du public", an),
       x = "IPS", y = "Arrondissement") +
  theme_depp

Focus : les écoles du 14e

Code
p14 <- dplyr::filter(paris14, annee == an)
p14 |>
  ggplot(aes(ips, y = secteur, colour = secteur)) +
  geom_vline(xintercept = 106, linetype = "dashed", colour = "grey55") +
  geom_point(size = 3, alpha = 0.8, position = position_jitter(height = 0.18, seed = 1)) +
  scale_colour_manual(values = pal_secteur, guide = "none") +
  labs(title = sprintf("Les %d écoles du 14e arrondissement par IPS (%d)", nrow(p14), an),
       subtitle = sprintf("De %.0f à %.0f — les 5 écoles privées sous contrat occupent le haut du classement",
                          min(p14$ips), max(p14$ips)),
       x = "IPS", y = NULL) +
  theme_depp

Code
paris14 |>
  dplyr::group_by(annee, secteur) |>
  dplyr::summarise(ips = mean(ips, na.rm = TRUE), n = dplyr::n(), .groups = "drop") |>
  ggplot(aes(annee, ips, colour = secteur)) +
  geom_hline(yintercept = 106, linetype = "dashed", colour = "grey55") +
  geom_line(linewidth = 1) + geom_point(size = 2.4) +
  scale_x_continuous(breaks = sort(unique(paris14$annee))) +
  scale_colour_manual(values = pal_secteur, name = NULL) +
  labs(title = "IPS moyen des écoles du 14e, public / privé",
       subtitle = paste0("Rentrées ", min(paris14$annee), "–", an),
       x = NULL, y = "IPS moyen") +
  theme_depp

Toutes les écoles de Paris

Code
ips |>
  dplyr::filter(departement == "PARIS") |>
  dplyr::transmute(
    Rentrée = rentree_scolaire, UAI = uai, École = nom_de_l_etablissement,
    Commune = nom_de_la_commune, Secteur = secteur, IPS = ips) |>
  dplyr::arrange(dplyr::desc(Rentrée), Commune, École) |>
  reactable::reactable(
    searchable = TRUE, filterable = TRUE, pagination = TRUE,
    defaultPageSize = 15, compact = TRUE, resizable = TRUE, highlight = TRUE, wrap = TRUE,
    defaultColDef = reactable::colDef(align = "left",
      headerStyle = list(fontWeight = "bold"),
      style = list(whiteSpace = "normal", wordBreak = "break-word")))

Le fichier complet (France entière, 90 154 lignes) est interrogeable sur data.education.gouv.fr.

Source & données

Code
tibble::tibble(
  ` ` = c("Jeu de données", "Producteur", "Champ", "Fichier", "Mise à jour", "Observations"),
  `  ` = c(
    "[Indice de position sociale des écoles](https://data.education.gouv.fr/explore/dataset/fr-en-ips-ecoles-ap2022/) — DEPP",
    "Direction de l'Évaluation, de la Prospective et de la Performance (DEPP), ministère de l'Éducation nationale",
    "France ; écoles élémentaires publiques et privées sous contrat ; à partir de la rentrée 2022 (le fichier `-ap2022`)",
    sprintf("`data/depp/fr-en-ips-ecoles-ap2022.parquet` (%s ko)", round(file.size(ips_path) / 1024)),
    format(as.Date(file.mtime(ips_path)), "%d %B %Y"),
    sprintf("%s lignes, rentrées %d–%d",
            format(nrow(ips), big.mark = " "), min(ips$annee), an)
  )
) |>
  gt::gt() |> gt::fmt_markdown(columns = `  `) |>
  gt::tab_options(table.width = "100%", column_labels.hidden = TRUE)
Jeu de données Indice de position sociale des écoles — DEPP
Producteur Direction de l’Évaluation, de la Prospective et de la Performance (DEPP), ministère de l’Éducation nationale
Champ France ; écoles élémentaires publiques et privées sous contrat ; à partir de la rentrée 2022 (le fichier -ap2022)
Fichier data/depp/fr-en-ips-ecoles-ap2022.parquet (3348 ko)
Mise à jour 08 septembre 2026
Observations 90 154 lignes, rentrées 2022–2024