Tutoriel - Usage de la Base sur la Qualité et la Sécurité des Soins (BQSS)#
Ce notebook vise à montrer un usage type dont peut être l’objet BQSS, de façon programmatique grâce au langage Python.
Import des librairies et des données#
Les URLS des données sont récupérable sur la page de la Base sur la Qualité et la Sécurité des Soins sur la plateforme Data Gouv accessible via ce lien. La section Fichiers contient les données disponibles, et pour chaque fichier, une description est présente incluant notamment un URL stable qu’il est recommandé d’utiliser.
La base BQSS adoptant un format clé-valeurs, il est nécessaire de récupérer la table des valeurs d’intérêts (concernant la qualité et la sécurité des soins) ainsi que les métadonnées associées spécifiant ces valeurs et les données caractérisant les établissements de santé via les numéro FINESS.
import numpy as np
import pandas as pd # version >= 1.4.2
# chargement du fichier valeurs.csv dans un dataframe pandas
valeurs_df = pd.read_csv(
"https://www.data.gouv.fr/fr/datasets/r/da295ccc-2011-4995-b810-ad1f1a82a83f",
low_memory=False,
)
# chargement du fichier metadata.csv dans un dataframe pandas
metadata_df = pd.read_csv(
"https://www.data.gouv.fr/fr/datasets/r/e56fb5a5-5a74-4507-ba77-e0411d4aa234",
low_memory=False,
)
# chargement du fichier finess.csv dans un dataframe pandas
finess_df = pd.read_csv(
"https://www.data.gouv.fr/fr/datasets/r/48dadbce-56a8-4dc4-ac51-befcdfd82521",
low_memory=False,
)
Observation des données#
Il est désormais possible de consulter les informations caractérisant ces données et en observer un échantillon.
Caractérisation des données valeurs_df#
valeurs_df.info()
valeurs_df.sample(n=5, random_state=187)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1432745 entries, 0 to 1432744
Data columns (total 10 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 annee 1432745 non-null int64
1 finess 1432745 non-null object
2 finess_type 1432745 non-null object
3 key 1432745 non-null object
4 value_boolean 608398 non-null object
5 value_string 110483 non-null object
6 value_integer 227845 non-null float64
7 value_float 340421 non-null float64
8 missing_value 136469 non-null object
9 value_date 9129 non-null object
dtypes: float64(2), int64(1), object(7)
memory usage: 109.3+ MB
annee | finess | finess_type | key | value_boolean | value_string | value_integer | value_float | missing_value | value_date | |
---|---|---|---|---|---|---|---|---|---|---|
1429044 | 2020 | 210013447 | geo | sld | True | NaN | NaN | NaN | NaN | NaN |
80324 | 2017 | 950300202 | geo | filtre_heb_ssr | False | NaN | NaN | NaN | NaN | NaN |
37018 | 2019 | 260000146 | geo | filtre_heb_perinat | False | NaN | NaN | NaN | NaN | NaN |
869559 | 2016 | 050002948 | jur | mco_hpp_del1_2016-del1_c1_pos_seuil_etbt | NaN | C | NaN | NaN | NaN | NaN |
647469 | 2019 | 920000643 | geo | perinat_sejces_dm | NaN | NaN | NaN | 5.8 | NaN | NaN |
Un grand nombre de variables de nature différente sont regroupées dans cette table (d’où la table metadata venant spécifier la nature de chaque variables). Le nom des variables est stocké dans la colonne key
.
Afin de pouvoir distinguer les différents types de valeurs (booléen, entier, décimal, chaîne de caractères, valeurs manquantes, dates), des colonnes dédiées leur sont attachées.
Ainsi, pour une variable donnée, un seul type est possible… :
sur l’ensemble de la classe (hormis la colonne
missing_value
)pour chaque valeur (justifiant la nature lacunaire de ces colonnes, toutes les colonnes autre que celle prenant la valeur étant à NaN)
Caractérisation des données metadata_df#
metadata_df.info()
metadata_df.sample(n=5, random_state=123)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 653 entries, 0 to 652
Data columns (total 16 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 name 653 non-null object
1 title 653 non-null object
2 description 259 non-null object
3 type 652 non-null object
4 source 653 non-null object
5 indicateur 474 non-null object
6 secteur 547 non-null object
7 theme 474 non-null object
8 acronyme 436 non-null object
9 version 440 non-null float64
10 variable 440 non-null object
11 annee 440 non-null float64
12 ancienne_variable 440 non-null object
13 url_rapport 436 non-null object
14 type_metier 589 non-null object
15 finess_type 653 non-null object
dtypes: float64(2), object(14)
memory usage: 81.8+ KB
name | title | description | type | source | indicateur | secteur | theme | acronyme | version | variable | annee | ancienne_variable | url_rapport | type_metier | finess_type | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
381 | mco_dan_tda_2015-tda_c_etbt | Valeur tenue du dossier anesthésique | NaN | classe | IQSS dossier patient | MCO_DAN_TDA_2015 | MCO | DAN | TDA | 2015.0 | tda_c_etbt | 2015.0 | tda_c_etbt | https://www.has-sante.fr/upload/docs/applicati... | resultat | mixte |
275 | mco_isoortho_ptg_2020-iso_ptg_evol | Evolution du statut des établissements évalués... | NaN | float-string | IQSS PMSI | MCO_ISOORTHO_PTG_2020 | MCO | ISOORTHO | PTG | 2020.0 | iso_ptg_evol | 2020.0 | iso_ptg_evol | https://www.has-sante.fr/upload/docs/applicati... | evolution | geo |
43 | certification_ref_2021_score_objectif_2.1 | Objectif 2.1 : La pertinence des parcours, des... | NaN | float | Certification v2021 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | geo |
227 | mco_avc_epr1_2014-epr1_c1_ichaut_etbt | Intervalle de confiance haut de l'évaluation p... | NaN | int | IQSS dossier patient | MCO_AVC_EPR1_2014 | MCO | AVC | EPR1 | 2014.0 | epr1_c1_ichaut_etbt | 2014.0 | epr1_c1_ichaut_etbt | https://www.has-sante.fr/upload/docs/applicati... | intervalle_haut | mixte |
356 | mco_dia_ser_2014-ser_c_den_etbt | Dénominateur surveillance sérologique des hépa... | NaN | float | IQSS dossier patient | MCO_DIA_SER_2014 | MCO | DIA | SER | 2014.0 | ser_c_den_etbt | 2014.0 | ser_c_den_etbt | https://www.has-sante.fr/upload/docs/applicati... | denominateur | mixte |
La colonne name
de cette table permet de faire la jointure avec la table valeurs_df
via la colonne key
associée.
Les métadonnées permettent de compléter les informations associées aux variables, en particulier leur type
(encodé implicitement dans valeur.csv
, voir ci-dessus), leur source
(provenant d’origines variées), leur secteur
, leur theme
et leur acronyme
.
Pour une recherche rapide, vous pouvez aussi utiliser directement le fichier metadata.xlsx
qui permet de faire des filtres rapides sur les différentes colonnes.
Caractérisation des données finess_df#
finess_df.info()
finess_df.sample(n=5, random_state=123)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 165374 entries, 0 to 165373
Data columns (total 56 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date_export 165374 non-null object
1 num_finess_et 165374 non-null object
2 num_finess_ej 165374 non-null object
3 raison_sociale_et 165374 non-null object
4 raison_sociale_longue_et 116991 non-null object
5 complement_raison_sociale 21061 non-null object
6 complement_distribution 25820 non-null object
7 num_voie 124493 non-null object
8 type_voie 154310 non-null object
9 libelle_voie 158756 non-null object
10 complement_voie 4965 non-null object
11 lieu_dit_bp 28910 non-null object
12 commune 8907 non-null float64
13 departement 165374 non-null object
14 libelle_departement 165374 non-null object
15 ligne_acheminement 165374 non-null object
16 telephone 146183 non-null object
17 telecopie 93832 non-null object
18 categorie_et 165374 non-null int64
19 libelle_categorie_et 165374 non-null object
20 categorie_agregat_et 165374 non-null int64
21 libelle_categorie_agregat_et 165374 non-null object
22 siret 137639 non-null float64
23 code_ape 73828 non-null object
24 code_mft 165374 non-null int64
25 libelle_mft 165374 non-null object
26 code_sph 164361 non-null float64
27 libelle_sph 164361 non-null object
28 date_ouverture 165374 non-null object
29 date_autorisation 165374 non-null object
30 date_maj 165374 non-null object
31 num_uai 2329 non-null object
32 coord_x_et 98237 non-null float64
33 coord_y_et 98235 non-null float64
34 source_coord_et 97922 non-null object
35 date_geocodage 100664 non-null object
36 region 156467 non-null float64
37 libelle_region 156467 non-null object
38 code_officiel_geo 156467 non-null object
39 code_postal 165374 non-null int64
40 libelle_routage 156467 non-null object
41 libelle_code_ape 67887 non-null object
42 ferme_cette_annee 165374 non-null bool
43 latitude 97908 non-null float64
44 longitude 97908 non-null float64
45 libelle_commune 165374 non-null object
46 adresse_postale_ligne_1 122943 non-null object
47 adresse_postale_ligne_2 165374 non-null object
48 raison_sociale_ej 165374 non-null object
49 raison_sociale_longue_ej 130887 non-null object
50 statut_juridique_ej 165374 non-null int64
51 libelle_statut_juridique_ej 165374 non-null object
52 statut_juridique 165374 non-null object
53 type_etablissement 165374 non-null object
54 actif_qualiscope 165374 non-null bool
55 dernier_enregistrement 165374 non-null bool
dtypes: bool(3), float64(8), int64(5), object(40)
memory usage: 67.3+ MB
date_export | num_finess_et | num_finess_ej | raison_sociale_et | raison_sociale_longue_et | complement_raison_sociale | complement_distribution | num_voie | type_voie | libelle_voie | ... | adresse_postale_ligne_1 | adresse_postale_ligne_2 | raison_sociale_ej | raison_sociale_longue_ej | statut_juridique_ej | libelle_statut_juridique_ej | statut_juridique | type_etablissement | actif_qualiscope | dernier_enregistrement | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1404 | 2022-07-08 | 210983565 | 210012142 | CH - HCO USLD MONTBARD | CH - HCO USLD MONTBARD | CH - HCO USLD MONTBARD | NaN | 24 | Rue | AUGUSTE CARRE | ... | 24 Rue Auguste Carre | 21500 MONTBARD | CTRE HOSPITALIER DE LA HAUTE COTE D OR | CENTRE HOSPITALIER DE LA HAUTE CÔTE-D'OR | 14 | Etablissement Public Intercommunal d'Hospitali... | Public | Public | True | True |
80171 | 2006-12-31 | 810102947 | 810000471 | ANTENNE D'AUTODIALYSE LESCURE | ANTENNE D'AUTODIALYSE LESCURE D'ALBIGEOIS | NaN | NaN | NaN | Impasse | LARQUIPEYRE | ... | NaN | 81380 LESCURE D ALBIGEOIS | SA CLINIQUE CLAUDE BERNARD | SA CLINIQUE CLAUDE BERNARD | 73 | Société Anonyme | Privé | Privé | False | False |
17438 | 2017-12-31 | 520004094 | 520003781 | POLE CANCERO SUD HTE MARNE CMC CHAUMON | NaN | NaN | NaN | 17 | Avenue | DES ETATS UNIS | ... | 17 Avenue Des Etats Unis | 52001 CHAUMONT CEDEX | GCS POLE DE CANCERO DU SUD HAUT MARNAI | NaN | 29 | G.C.S. public | Public | Public | False | False |
109866 | 2009-12-31 | 780824033 | 780001236 | CENTRE MEDICO-PSY SECT.78-I-2 | CENTRE MEDICO-PSYCHOLOGIQUE SECTEUR 78-I-2 | NaN | NaN | 1 | Rue | CHARLES BOURSEUL | ... | 1 Rue Charles Bourseul | 78700 CONFLANS STE HONORINE | CH INTERCOM DE POISSY ST-GERMAIN | CENTRE HOSPITALIER INTERCOMMUNAL POISSY ST-GER... | 14 | Etb.Pub.Intcom.Hosp. | Public | Public | False | False |
291 | 2022-07-08 | 060019957 | 060780988 | CMP ADULTE SECT3 CH CANNES | CMP ADULTE SECT3 CH CANNES | PSYCHIATRIE ADULTE | NaN | 27 | Avenue | ISOLA BELLA | ... | 27 Avenue Isola Bella | 06400 CANNES | CH DE CANNES SIMONE VEIL | CENTRE HOSPITALIER DE CANNES SIMONE VEIL | 13 | Etablissement Public Communal d'Hospitalisation | Public | Public | False | True |
5 rows × 56 columns
Cette table contient l’ensemble des données Finess historisées. Il y a une ligne par export et par Finess présent à la date de l’export. Pour un même Finess il ya donc très souvent plusieurs lignes.
Les colonnes qui s’avèrent souvent utiles sont:
num_finess_et
: numéro finess géographiquenum_finess_ej
: numéro finess juridiquelatitude
etlongitude
: les coordonnées géographiques de l’établissement dans le référentiel WGS84raison_sociale_et
: le nom de l’établissementdernier_enregistrement
: indique si cette ligne est la dernière connue pour le finess en question
Préparation des données#
Récupération des clés associées à des catégories de valeurs#
Les cas d’usages pour lesquels la base est utilisé ne concernent souvant qu’un sous-ensemble des domaines présents dans la base. On peut par exemple vouloir récupérer l’historique complet des IQSS issus du questionnaire patient (ESATIS).
La mécanique pour sélectionner le sous ensemble de données d’interêt est la suivante:
Dans le fichier
metadata.csv
utiliser la colonnesource
pour identifier le domaine d’intérêtDans le fichier
metadata.csv
recupérer le nom des variables de lasource
donnée qui sont stockées dans la colonnename
Parmis ces variables, utiliser les colonne
type_metier
(pour les IQSS) et/oudescription
pour sélectionner les variables d’intérêtDans le fichier
valeurs.csv
sélection toutes les lignes dont la colonnekey
contient une variable du domaine d’intérêt
Ci-dessous un exemple de cette mécanique:
# Affichage des sources de données existantes
metadata_df["source"].value_counts()
IQSS dossier patient 403
SAE 115
IQSS questionnaire patient 34
Certification v2014 33
IQSS PMSI 22
Certification v2021 21
IQSS questionnaire établissement 15
Activités ET 10
Name: source, dtype: int64
# Récupération des noms des variables de certification v2014
certif_14_keys = metadata_df[metadata_df["source"] == "Certification v2014"][
"name"
]
# Récupération des nom des variables esatis
esatis_keys = metadata_df[
metadata_df["source"] == "IQSS questionnaire patient"
]["name"]
# Affichage des types métiers certification
# Les variables de certification n'ont pas de type métier
metadata_df.loc[
metadata_df["name"].isin(certif_14_keys),
["name", "description", "type_metier"],
].head(5)
name | description | type_metier | |
---|---|---|---|
0 | certif_V2014_id_niveau | Code du niveau de certification validé par le ... | NaN |
1 | certif_date | Date de délibération du collège de la HAS qui ... | NaN |
2 | certif_V2014_id_demarche | Code interne à la HAS.\nIl s’agit d’un code pe... | NaN |
3 | certif_V2014_decision_thematique_1 | Décision finale pour la thématique : Managemen... | NaN |
4 | certif_V2014_decision_thematique_2 | Décision finale pour la thématique : Qualité d... | NaN |
# Affichage des types métiers esatis
metadata_df.loc[
metadata_df["name"].isin(esatis_keys),
["name", "description", "type_metier"],
].head(5)
name | description | type_metier | |
---|---|---|---|
494 | nb_rep_score_all_rea_ajust | Nombre de réponses concernant la satisfaction ... | effectif_observe |
495 | score_all_rea_ajust | Note ajustée de satisfaction globale classemen... | score |
496 | classement_48h | Classement en 6 classes {A: >=77.3, B: [74-77.... | classe |
497 | evolution_48h | Changement de classe d'une année à l'autre | evolution |
498 | nb_rep_score_accueil_rea_ajust | Nombre de réponses concernant la satisfaction ... | effectif_observe |
# Affichage des variables de type score pour esatis
metadata_df.loc[
metadata_df["name"].isin(esatis_keys)
& (metadata_df["type_metier"] == "score"),
["name", "description", "type_metier"],
]
name | description | type_metier | |
---|---|---|---|
495 | score_all_rea_ajust | Note ajustée de satisfaction globale classemen... | score |
499 | score_accueil_rea_ajust | Note ajustée concernant la satisfaction de l'a... | score |
501 | score_pecinf_rea_ajust | Note ajustée de satisfaction de la prise en ch... | score |
503 | score_pecmed_rea_ajust | Note ajustée de satisfaction de la prise en ch... | score |
505 | score_chambre_rea_ajust | Note ajustée de satisfaction de la chambre | score |
507 | score_repas_rea_ajust | Note ajustée de satisfaction des repas | score |
509 | score_sortie_rea_ajust | Note ajustée de satisfaction de la sortie | score |
510 | taux_reco_brut_48h | Pourcentage de patients recommandant certainem... | score |
513 | score_all_ajust_ca | Score de satisfaction globale ajusté | score |
516 | score_avh_ajust | Note ajustée de la satisfaction avant l’hospit... | score |
518 | score_acc_ajust | Note ajustée concernant la satisfaction accuei... | score |
520 | score_pec_ajust | Note ajustée de la satisfaction de la prise en... | score |
522 | score_cer_ajust | Note ajustée de la satisfaction chambre et rep... | score |
524 | score_ovs_ajust | Note ajustée de la satisfaction sortie et reto... | score |
526 | taux_reco_brut_ca | Pourcentage de patients recommandant certainem... | score |
Isolation des domaines de données#
Afin de pouvoir préparer et analyser un domaine de données, il est nécessaire de l’isoler en vue de traitements décrits plus bas. Pour des raisons de volumétrie, le présent tutoriel se restreint aux données esatis. Mais il est naturellement possible d’effectuer ces analyses sur un ensemble de domaines de données, voire sur tous les domaines (les mêmes opérations décrites ici peuvent leur être appliquées).
# Isolation du domaine de données esatis
esatis_df = valeurs_df[valeurs_df["key"].isin(esatis_keys)]
# Isolation du domaine de données certification v2014, pour illustration
certif_df = valeurs_df[valeurs_df["key"].isin(certif_14_keys)]
Pivot de la table esatis#
Actuellement, le format clé-valeur de la base induit que chaque valeur de chaque variable pour chacun des établissements est associée à une ligne. Nous souhaitons pourvoir avoir un regroupement des valeurs pour chaque établissement.
Pour cela, nous devons effectuer les opérations suivantes (cf. cellule de code ci-dessous) :
Effectuer un pivot à la table pour avoir une colonne par variable (par type), chaque ligne représentant un établissement pour une année donnée (puisque certaines valeurs sont collectées annuellement)
Chaque classe de valeur n’ayant qu’un type de valeur acceptable (hormis le type
missing_value
), toutes les colonnes des autres types seront remplis deNaN
=> il s’agit donc également de supprimer ces colonnes inutilesLes colonnes des valeurs manquantes pour une clé sont fusionnées avec la colonne de valeurs de la clé correspondante pour ne pas perdre l’information correspondante
# Les colonnes de valeurs sont pivotées selon le colonne key, pour chaque triplet (annee, finess, finess_type)
esatis_df = esatis_df.pivot(
index=["annee", "finess", "finess_type"], columns="key"
)
# Toutes les colonnes de valeurs liées à un type incorrect vis-à-vis du type attendu sont remplies par des NaN.
# Il s'agit ici de supprimer ces colonnes qui ne portent aucune information exploitable
esatis_df = esatis_df.dropna(axis=1, how="all")
# Les colonnes associées au type missing_value sont fusionnées avec leur colonne de valeur respective
# Cette étape est optionnelle si les valeurs manquantes sont sans intérêts pour l'étude
if "missing_value" in esatis_df:
esatis_df = esatis_df.combine_first(esatis_df["missing_value"]).drop(
columns="missing_value"
)
# Les colonnes qui résultent de ces opérations ont plusieurs niveaux qui sont ici applatis pour n'en avoir plus qu'un
esatis_df = esatis_df.droplevel(0, axis=1)
# Les données d'années, de finess et de finess_type utilisées jusqu'ici comme index sont basculées en colonnes dans la table.
esatis_df = esatis_df.reset_index()
Un échantillon de la table résultante peut être observée ci-dessous, en notant qu’il manque des données pour de nombreux établissements sur certaines années car certains indicateurs n’étaient pas calculés à ce moment là.
esatis_df.sample(n=5, random_state=123)
key | annee | finess | finess_type | classement_48h | classement_ca | evolution_48h | evolution_ca | nb_reco_brut_48h | nb_reco_brut_ca | nb_rep_score_acc_ajust | ... | score_cer_ajust | score_chambre_rea_ajust | score_ovs_ajust | score_pec_ajust | score_pecinf_rea_ajust | score_pecmed_rea_ajust | score_repas_rea_ajust | score_sortie_rea_ajust | taux_reco_brut_48h | taux_reco_brut_ca |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
607 | 2016 | 590790655 | geo | Données insuffisantes | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
3852 | 2019 | 370000531 | geo | B | NaN | 3-Amélioration | NaN | 94.0 | NaN | NaN | ... | NaN | 75.21 | NaN | NaN | 84.50 | 80.37 | 60.41 | 64.52 | 71.3 | NaN |
1975 | 2017 | 750000549 | geo | B | NaN | 3-Amélioration | NaN | NaN | NaN | NaN | ... | NaN | 72.54 | NaN | NaN | 80.98 | 82.22 | 62.58 | 64.17 | NaN | NaN |
1074 | 2016 | 930000302 | geo | Données insuffisantes | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
879 | 2016 | 760805770 | geo | D | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
5 rows × 37 columns
Exploitation des données#
Dans cette section, une analyse simple sur le domaine esatis est effectuée à des fins d’illustration quant à la valorisation de ces données.
Le cas d’usage de cette analyse est l’observation de l’évolution du positionnement national d’un établissement identifié (il s’agit ici de l’établissement associé au finess n°060000478
) vis-à-vis des établissements de même catégorie (il s’agit ici de la catégorie Centres Hospitaliers, associée au code 1102
) sur l’indicateur score_all_ajust_ca
(correspondant au “score de satisfaction globale ajusté” en chirurgie ambulatoire).
Pour ce faire, il faut :
associer aux données esatis les données finess nécessaires à la jointure et à la catégorisation des établissements
calculer le classement de l’établissement (son rang absolu et le pourcentage associé) pour chaque année
représenter la distribution des établissements pour chaque année en positionnant l’établissement étudié
Ces étapes sont réalisées dans les deux sections ci-dessous.
Finalisation de la préparation des données#
# On ne prend que les informations des finess les plus récentes pour éviter les doublons à la jointure
finess_df = finess_df.loc[finess_df["dernier_enregistrement"]]
# Jointure entre les données esatis et les données Finess restreintes aux agrégats de catégories d'établissement
df = finess_df[
[
"num_finess_et",
"categorie_agregat_et",
"raison_sociale_et",
"departement",
]
].merge(esatis_df, left_on="num_finess_et", right_on="finess", how="inner")
df.sample(5, random_state=123)
num_finess_et | categorie_agregat_et | raison_sociale_et | departement | annee | finess | finess_type | classement_48h | classement_ca | evolution_48h | ... | score_cer_ajust | score_chambre_rea_ajust | score_ovs_ajust | score_pec_ajust | score_pecinf_rea_ajust | score_pecmed_rea_ajust | score_repas_rea_ajust | score_sortie_rea_ajust | taux_reco_brut_48h | taux_reco_brut_ca | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
607 | 130783293 | 1101 | APHM HOPITAL LA TIMONE | 13 | 2016 | 130783293 | geo | Données insuffisantes | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
3852 | 620100750 | 1110 | CLINIQUE AMBROISE PARE | 62 | 2017 | 620100750 | geo | B | NaN | 2-Stable | ... | NaN | 77.67 | NaN | NaN | 82.97 | 82.36 | 61.93 | 66.11 | NaN | NaN |
1975 | 340780725 | 1110 | CL VIA DOMITIA | 34 | 2020 | 340780725 | geo | B | B | NaN | ... | 74.48 | 75.96 | 70.87 | 85.01 | 83.56 | 82.84 | 48.60 | 65.61 | 67.6 | 71.6 |
1074 | 220000368 | 1102 | CENTRE HOSPITALIER LANNION | 22 | 2017 | 220000368 | geo | C | NaN | 2-Stable | ... | NaN | 68.88 | NaN | NaN | 82.26 | 79.18 | 64.03 | 61.99 | NaN | NaN |
879 | 170000095 | 1102 | CENTRE HOSPITALIER ST-JEAN D'ANGELY | 17 | 2018 | 170000095 | geo | Données insuffisantes | Données insuffisantes | 4-Non calculable | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
5 rows × 41 columns
# Seuls les centres hospitaliers sont conservés
df = df[df["categorie_agregat_et"] == 1102]
# Pour cette étude, seules les colonnes suivantes sont nécessaires pour la suite : annee, taux_reco_brut_ca, finess
# Par ailleurs, cet indicateur n'est collecté qu'a partir de 2019.
df = df.loc[
df["annee"] >= 2019,
[
"annee",
"finess",
"raison_sociale_et",
"departement",
"score_all_ajust_ca",
],
]
# Les établissements sans valeurs pour l'indicateur sont retirés
df = df.dropna()
Un extrait de la table correspondante peut être observée :
df.sample(5, random_state=123)
annee | finess | raison_sociale_et | departement | score_all_ajust_ca | |
---|---|---|---|---|---|
6339 | 2021 | 930000286 | GHI LE RAINCY MONTFERMEIL | 93 | 75.89 |
3104 | 2019 | 550000012 | CH VERDUN/ST MIHIEL-HOP ST NICOLAS | 55 | 76.95 |
4587 | 2021 | 710978263 | CH WILLIAM MOREY CHALON SUR SAONE | 71 | 80.67 |
3764 | 2019 | 620000034 | CH ARRAS | 62 | 77.77 |
3328 | 2021 | 580972693 | HOPITAL PIERRE BEREGOVOY | 58 | 72.74 |
Visualisation des résultats#
es_finess = "060000478"
axes = df.plot.hist(by="annee", bins=20, figsize=(10, 15), legend=False)
for i, annee in enumerate(np.sort(df["annee"].unique())):
axes[i].set_xlim(0, 100)
axes[i].set_ylim(0, 37)
axes[i].set_ylabel("Fréquences", fontsize=12)
df_tmp = (
df[df["annee"] == annee]
.sort_values("score_all_ajust_ca", ascending=False)
.reset_index()
)
value = df_tmp.loc[
df_tmp["finess"] == es_finess, "score_all_ajust_ca"
].values[0]
axes[i].axvline(value, color="red")
axes[i].text(value - 3.2, -4.5, str(value), color="red", fontsize=12)
axes[i].text(
value + 1, 38, "finess n°" + str(es_finess), color="red", fontsize=12
)
rank = df_tmp[df_tmp["finess"] == es_finess].index.item() + 1
card_finess = df_tmp.shape[0]
rank_ratio = 100 * rank / card_finess
axes[i].text(
5,
30,
f"classement : {rank} / {card_finess}\nposition (%) : {rank_ratio:,.1f}",
backgroundcolor="lightgrey",
color="red",
fontsize=12,
fontweight="roman",
)
axes[2].set_xlabel(
"score de satisfaction globale ajusté",
fontsize=12,
labelpad=15,
)
Text(0.5, 0, 'score de satisfaction globale ajusté')

⚠️ Attention : L’analyse et l’interprétation des résultats des IQSS nécessite de bien prendre connaissance de leur définition.
Nous pouvons constater que l’établissement considéré dans cette étude a:
Amélioré son score (de
77.73
à80.78
)Amélioré sa place dans la distribution de
54.6
ème percentile à24.3
ème percentile