--- title: Simulation de réforme CSG : Préparation des données keywords: fastai sidebar: home_sidebar nb_path: "notebooks/analyses/csg_20_preparation.ipynb" ---
{% raw %}
{% endraw %} {% raw %}
from IPython.core.interactiveshell import InteractiveShell

InteractiveShell.ast_node_interactivity = "all"
{% endraw %} {% raw %}
import os
import random

import pandas as pd

# Load OpenFisca
from leximpact_simulation_engine.simulate_pop_from_reform import (  # type: ignore
    TBS_DEFAULT,
    annee_de_calcul,
    simulation,
)
from leximpact_socio_fisca_simu_etat.config import Configuration

config = Configuration(project_name="leximpact-prepare-data")
os.environ["YEAR_COMPUTATION"] = config.get("SAMPLE_POP")
{% endraw %} {% raw %}
!pwd
{% endraw %} {% raw %}
!ls ./leximpact_simulation_engine/DCT.csv
!ls ../leximpact_simulation_engine/DCT.csv
{% endraw %} {% raw %}
with open(
    config.get("COPULE_FOLDER") + "20210610ExportCopule-rev_capital_partiel.txt"
) as fichier:
    contenu = fichier.read()
    dictionnaire_fichier = eval(contenu)

"""
lower_bound : revenu minimum de RFR
upper_bound : revenu maximum de RFR
nb_people : { 'zero' : Nb foyers tels que Rk==0 , 'nonzero': Nb foyers tels que Rk > 0 }
nonzerobucket : Tableau de couple [nb foye] du bucket, Seuil plafond du bucket
"""
print(dictionnaire_fichier[0])
print("-" * 50)
print(dictionnaire_fichier[5])

# foyers = 0
# somme = 0
# for b in dictionnaire_fichier:
#     for rk in b['nonzerobuckets']:
#         foyers += rk[0]
#         somme += rk[1]
#     foyers += b['nb_people']['zero']
#     print("compa sommes : ", b['nb_people']['zero'] , sum([rk[0] for rk in b["nonzerobuckets"]]))
# print(f'Somme des revenus du capital : {somme / 1e9:.2f}')
# print(f'Nombre de foyers : {foyers}')

calib_rk = pd.read_csv(config.get("CALIB_POTE_RK"))
# La première ligne suffit pour retrouver la somme

# print('Nb foy dans CalibPOTE_rev_capital_partiel : ', calib_rk['Nk'].sum())
# print('Somme revKpi dans CalibPOTE_rev_capital_partiel : ', calib_rk['Ark'].sum())
# calib_rk['somme'] = calib_rk['Nk'] * calib_rk['Ark'] * 38_000_000
# somme_rk = calib_rk['somme'].sum()
# print(somme_rk)
{% endraw %} {% raw %}
def revenu_du_capital_estime(rfr):
    # Dans quel bucket est rfr? ===> Nous donne la distrib du Rk
    # rfr :  un nombre
    # dictionnaire_fichier

    for bucket in dictionnaire_fichier:
        if bucket["lower_bound"] <= rfr < bucket["upper_bound"]:
            break

    probazero = bucket["nb_people"]["zero"] / sum(bucket["nb_people"].values())
    # {'lower_bound': 0, 'upper_bound': 1.0, 'nb_people': {'zero': 2267320, 'nonzero': 33668}
    # 2267320 /(2267320+33668) = 98.5%

    # On genere une variable aleatoire entre 0 et 1
    randunif = random()
    # Si cette proba est <= à la probabilité que Rk = 0
    if randunif <= probazero:
        return 0
    # Si on n'est pas dans ce cas
    randunif = (randunif - probazero) / (1 - probazero)

    randinnbgens = randunif * bucket["nb_people"]["nonzero"]

    # Générer un rk à partir de cette distrib (Monte-Carlo probablement)
    sommepass = 0  # nombre de gens dans les buckets déjà dépassés. Quand on a passé le nombre de gens qu'on veut, on a fini de générer !
    for bucket_rk in bucket["nonzerobuckets"]:
        sommepass += bucket_rk[0]
        if sommepass > randinnbgens:
            return bucket_rk[1] / bucket_rk[0]
{% endraw %} {% raw %}
nbpopo = 0
nbtot = 10000
for _i in range(nbtot):
    rfr = 10000
    rce = revenu_du_capital_estime(rfr)
    # print(f"J'ai genere {rce} pour un random ff qui aurait {rfr} de revenu")
    if rce > 0:
        nbpopo += 1

print(
    f"Au total, j'ai {nbpopo/nbtot * 100:.2f}% non nuls, je devrais en avoir {100713/(100713 + 284008) *100:.2f}% "
)

# # On va ajouter cette colonne de Rk dans le dummy_data_final (par individu)
dummy_data_final = pd.read_hdf(config.get("SAMPLE_POP"))  # Une ligne par personne
# print(dummy_data_final.columns)

# On ne peut calculer le RFR que par foyer fiscal
# On charge une simulation OpenFisca
my_simu, dico = simulation(
    data=dummy_data_final, tbs=TBS_DEFAULT["avant"], period=annee_de_calcul
)
# print(my_simu.calculate('rfr', '2020'))
# On regroupe les 117 000 lignes (d'individus) de dummy_data_final en 58 000 lignes de foyers fiscaux
ddf = dummy_data_final[["quifoy", "idfoy", "wprm"]]
dd_ff = ddf.groupby(["idfoy", "wprm"], as_index=False).sum()

to_calc = my_simu.calculate("rfr", annee_de_calcul)
dd_ff["rfr"] = to_calc
# print(dd_ff.columns)
# print(dd_ff)

# On génère la colonne 'rk' dans dd_ff
dd_ff["rk"] = dd_ff["rfr"].apply(lambda row: revenu_du_capital_estime(row))
print(dd_ff)
# print(dd_ff.columns)
{% endraw %} {% raw %}
dd_ff["rk*wprm"] = dd_ff["rk"] * dd_ff["wprm"]
print("Agrégat pondéré de Rk, wanted 75Mds€", dd_ff["rk*wprm"].sum())
dd_ff["rfr*wprm"] = dd_ff["rfr"] * dd_ff["wprm"]
print("Agrégat pondéré de RFR, wanted ??Mds€", dd_ff["rfr*wprm"].sum())
# On exporte les données (groupées par foyer fiscal)
dd_ff.to_csv(config.get("DATA_OUT") + "dummy_data_foy_rk.csv")
{% endraw %}

On split dd_ff sur les individus

1 - On attribue le Rk d'un foyer fiscal à toutes les personnes du foyer dans dummy_data_final

{% raw %}
dummy_data_final[["quifoy", "idfoy"]].head()
{% endraw %} {% raw %}
# dummy_data_final[['quifoy','idfoy']].head()
# dd_ff2.head()
dd_ff2 = dd_ff[["idfoy", "rk", "rfr"]]
dummy_data_final_rk = pd.merge(
    dummy_data_final, dd_ff2, left_on="idfoy", right_on="idfoy", indicator=True
)

print("Colonnes après merge", dummy_data_final_rk.columns)
dummy_data_final_rk[["quifoy", "idfoy", "rk"]].head()
{% endraw %}

2 - On supprime le Rk aux personnes autres que le déclarant principal du foyer fiscal (i.e. quifoy=0)

{% raw %}
print(dummy_data_final_rk.columns)
dummy_data_final_rk.loc[dummy_data_final_rk["quifoy"] != 0, "rk"] = 0
dummy_data_final_rk.loc[dummy_data_final_rk["quifoy"] != 0, "rfr"] = 0
dummy_data_final_rk[["quifoy", "idfoy", "rk", "rfr"]].head()
{% endraw %} {% raw %}
dummy_data_final_rk["rk*wprm"] = dummy_data_final_rk["rk"] * dummy_data_final_rk["wprm"]
dummy_data_final_rk["rfr*wprm"] = (
    dummy_data_final_rk["rfr"] * dummy_data_final_rk["wprm"]
)

print(
    "Agrégat pondéré de Rk avant merge, wanted 75Mds€",
    "% 10.3E" % dd_ff["rk*wprm"].sum(),
)

print(
    "Agrégat pondéré de Rk, wanted 75Mds€ : ",
    "% 10.3E" % dummy_data_final_rk["rk*wprm"].sum(),
)

print(
    "Agrégat pondéré de RFR avant merge, wanted ??Mds€",
    "% 10.3E" % dd_ff["rfr*wprm"].sum(),
)
print(
    "Agrégat pondéré de RFR, wanted 1050Mds€ : ",
    "% 10.3E" % dummy_data_final_rk["rfr*wprm"].sum(),
)

print("Nombre de lignes, wanted 116861 : ", len(dummy_data_final_rk))

dd_ff[["quifoy", "idfoy", "rk", "wprm", "rk*wprm"]].head(10)
dummy_data_final_rk[["quifoy", "idfoy", "rk", "wprm", "rk*wprm"]].head(10)
{% endraw %} {% raw %}
dummy_data_final_rk.to_csv(config.get("DATA_OUT") + "dummy_data_ind_rk.csv")
{% endraw %} {% raw %}
dummy_data_final_rk_rfr_nul = dummy_data_final_rk[
    (dummy_data_final_rk["rfr"] == 0) & (dummy_data_final_rk["quifoy"] == 0)
]
somme_gens_rfr_nul = dummy_data_final_rk_rfr_nul["wprm"].sum()
print("Nb de gens de RFR nul (expected 2.3m)", "% 10.3E" % somme_gens_rfr_nul)
{% endraw %} {% raw %}
moy = (dummy_data_final_rk_rfr_nul["rk*wprm"].sum()) / (
    dummy_data_final_rk_rfr_nul["wprm"].sum()
)
print("Rk moyen par personne (expected 33€) : ", moy, " en €")
{% endraw %} {% raw %}
dummy_data_final_rk_rfr_2 = dummy_data_final_rk[
    (dummy_data_final_rk["rfr"] > 144247) & (dummy_data_final_rk["quifoy"] == 0)
]
somme_gens_rfr_2 = dummy_data_final_rk_rfr_2["wprm"].sum()
print("Nb de gens de RFR > 144 247€ (expected 384 000)", "% 10.3E" % somme_gens_rfr_2)
{% endraw %} {% raw %}
moy = (dummy_data_final_rk_rfr_2["rk*wprm"].sum()) / (
    dummy_data_final_rk_rfr_2["wprm"].sum()
)
print("Rk moyen par personne (expected 100 000€) : ", moy, " en €")
print("Soit au total, sur les 38M€ expected : ", "% 10.3E" % (moy * somme_gens_rfr_2))
{% endraw %} {% raw %}
dummy_data_final_rk_et_rfr_nuls = dummy_data_final_rk[
    (dummy_data_final_rk["rfr"] == 0)
    & (dummy_data_final_rk["rk"] == 0)
    & (dummy_data_final_rk["quifoy"] == 0)
]
somme_gens_rk_et_rfr_nuls = dummy_data_final_rk_et_rfr_nuls["wprm"].sum()
print(
    "Nb de gens de Rk et RFR nuls (expected 98.5% de )",
    "% 10.3E" % somme_gens_rk_et_rfr_nuls,
)
print("Part: ", somme_gens_rk_et_rfr_nuls / somme_gens_rfr_nul)
{% endraw %} {% raw %}
dummy_data_final_rk_et_rfr_2 = dummy_data_final_rk[
    (dummy_data_final_rk["rfr"] > 144247)
    & (dummy_data_final_rk["rk"] == 0)
    & (dummy_data_final_rk["quifoy"] == 0)
]
somme_gens_rk_et_rfr_2 = dummy_data_final_rk_et_rfr_2["wprm"].sum()
print("Nb de gens de Rk nul et RFR riche (expected  )", somme_gens_rk_et_rfr_2)
print("Part: ", somme_gens_rk_et_rfr_2 / somme_gens_rfr_2)
print(
    "Nb de gens de RFR > 144 247€ : total de : ",
    len(dummy_data_final_rk[(dummy_data_final_rk["rfr"] > 144247)]),
)
moy = (dummy_data_final_rk_et_rfr_2["rk*wprm"].sum()) / (
    dummy_data_final_rk_et_rfr_2["wprm"].sum()
)
print("Rk moyen par personne (expected €) : ", moy, " en €")
{% endraw %}

Calcul de la CSG

Calcul de l'assiette des revenus du capital

{% raw %}
print(len(dummy_data_final_rk))
dummy_data_final_rk.columns
{% endraw %} {% raw %}
dummy_data_csg = dummy_data_final_rk[
    [
        "age",
        "categorie_salarie",
        "chomage_brut",
        "contrat_de_travail",
        "heures_remunerees_volume",
        "idfam",
        "idfoy",
        "idmen",
        "pensions_alimentaires_percues",
        "quifam",
        "quifoy",
        "retraite_brute",
        "statut_marital",
        "salaire_de_base",
        "taux_csg_remplacement",
        "f4ba",
        "wprm",
        "rfr",
    ]
]
# assiette_csg_revenus_capital = dummy_data_final_rk['f4ba'] + dummy_data_final_rk['rk']

# On a aggrégé ces revenus dans:
revenus_capital = dummy_data_final_rk["rk"]
# On voudrait faire:
# dummy_data_csg['revenus_capital'] = dummy_data_final_rk['rk']

# Or la variable 'revenus_capital' n'est pas lue par OF, mais ses sous-variables le sont.
# On les définis donc arbitrairement comme:
dummy_data_csg["revenus_capitaux_prelevement_bareme"] = revenus_capital / 3
dummy_data_csg["revenus_capitaux_prelevement_liberatoire"] = revenus_capital / 3
dummy_data_csg["revenus_capitaux_prelevement_forfaitaire_unique_ir"] = (
    revenus_capital / 3
)

# On calcule la CSG
# On charge une simulation OpenFisca
my_simu2, dico = simulation(
    data=dummy_data_csg, tbs=TBS_DEFAULT["avant"], period=annee_de_calcul
)
{% endraw %} {% raw %}
dummy_data_csg.columns
{% endraw %} {% raw %}
to_calc2 = my_simu2.calculate("assiette_csg_revenus_capital", annee_de_calcul)
# to_calc2 est en foyer
# dummy_data_csg est en individus

dummy_data_csg_foy = dummy_data_csg.groupby(["idfoy", "wprm"]).sum()

dummy_data_csg_foy["assiette_csg_revenus_capital"] = to_calc2

print(dummy_data_csg_foy.columns)
dummy_data_csg_foy.head()
{% endraw %} {% raw %}
# dummy_data_csg["assiette_csg_revenus_capital"] = to_calc2 --> non car ça passe en foyers fiscaux
# print(dummy_data_csg.columns)
# dummy_data_csg.head()

# Calcul de la csg
to_calc3 = my_simu2.calculate("csg_revenus_capital", annee_de_calcul)
print(to_calc3)
print("CSG avant: ", to_calc3.sum())

print(dummy_data_final_rk.columns)

dummy_data_final_rk_foy = dummy_data_final_rk.groupby(["idfoy"]).sum()

dummy_data_final_rk_foy["csg_revenus_capital"] = to_calc3
print(dummy_data_final_rk_foy.columns)
dummy_data_final_rk_foy.head()


CSG_Rk = to_calc3 * dd_ff["wprm"]

print(f"CSG pondérée, expected ~10 Mds€ : {CSG_Rk.sum():,}")
# Ref: p51 de https://www.securite-sociale.fr/files/live/sites/SSFR/files/medias/CCSS/2019/CCSS%20SEPT%2019%20DEF.pdf
{% endraw %} {% raw %}
dummy_data_final_rk_foy["wprm*csg_revenus_capital"] = (
    dummy_data_final_rk_foy["wprm"] * dummy_data_final_rk_foy["csg_revenus_capital"]
)
print(
    f"Total de CSG sur les revenus du capital : {dummy_data_final_rk_foy['wprm*csg_revenus_capital'].sum():,}"
)
{% endraw %}