Manipulation de Données avec dplyr

Formation en R

Introduction

Bienvenue !

Dans ce module, nous apprendrons comment manipuler (nettoyer, transformer et préparer) des données fiscales en utilisant dplyr.

Que signifie “manipulation de données” ?

La manipulation de données est le processus de transformation de données brutes en un format prêt pour l’analyse.

Pensez-y comme préparer des ingrédients avant de cuisiner :

  • Laver les légumes 🥕 → Éliminer les mauvaises données
  • Couper les ingrédients 🔪 → Sélectionner ce dont vous avez besoin
  • Mélanger les ingrédients 🍜 → Combiner des jeux de données

À la fin de ce module, vous pourrez :

  • Filtrer, sélectionner et transformer des données fiscales
  • Créer de nouvelles variables et transformer les existantes
  • Travailler avec des dates pour l’analyse des déclarations fiscales
  • Construire des flux de travail complets de traitement de données

Pourquoi dplyr ?

dplyr fait partie du tidyverse - une collection de paquets R conçus pour travailler ensemble de manière transparente.

Avantages :

Lisible - les verbes correspondent à ce que vous voulez faire

Cohérent - syntaxe similaire pour toutes les opérations

Adapté aux débutants - clair et logique

Bien documenté - tonnes de ressources

# Code similaire à l'anglais !
tax_data %>%
  filter(filing_year == 2023) %>%
  select(firm_id, vat_outputs) %>%
  arrange(desc(vat_outputs))

# "Prendre tax_data, PUIS
#  filtrer à 2023, PUIS
#  sélectionner ces colonnes, PUIS
#  trier par montant"

Note

Nous expliquerons ce que signifie %>% dans un moment !

Stocker Votre Travail : Affectation dans R

Avant de plonger dans la manipulation de données, nous devons comprendre un concept crucial :

Les Modifications Ne Sont Pas Sauvegardées Sauf Si Vous Les Sauvegardez !

Lorsque vous transformez des données dans R, les modifications NE sont PAS sauvegardées automatiquement. Vous devez utiliser l’opérateur d’affectation <- pour stocker les résultats.

# Ceci affiche le résultat mais NE le sauvegarde PAS
panel_vat %>%
  filter(vat_outputs > 40000)

# La prochaine fois que vous utilisez panel_vat, ces modifications ONT DISPARU !

Comment Fonctionne l’Affectation

L’opérateur d’affectation <- stocke les résultats dans un objet :

# Créer un nouvel objet avec des données filtrées
high_vat <- panel_vat %>%
  filter(vat_outputs > 40000)

# Maintenant nous pouvons utiliser high_vat plus tard
nrow(high_vat)  # Vérifier combien de lignes
[1] 211

Vous pouvez aussi écraser l’original :

# Ceci REMPLACE panel_vat par la version filtrée
panel_vat <- panel_vat %>%
  filter(vat_outputs > 40000)

# Attention ! Les données originales sont maintenant perdues.

Avertissement

Écraser est permanent ! Si vous n’êtes pas sûr, créez un nouvel objet à la place.

Quand Créer un Nouveau vs. Écraser

Créez un NOUVEL objet quand :

  • Vous voulez garder les données originales
  • Vous testez différentes approches
  • Vous explorez ou expérimentez
vat_2023 <- panel_vat %>%
  filter(filing_year == 2023)

# Le panel_vat original est toujours là !

Écrasez le MÊME objet quand :

  • Vous nettoyez les données étape par étape
  • Vous ajoutez des colonnes calculées permanentes
  • Vous êtes sûr de ne pas avoir besoin de l’original
# Ajouter une colonne année de manière permanente
panel_vat <- panel_vat %>%
  mutate(filing_year = year(declaration_date))

# Maintenant panel_vat a la colonne filing_year !

Pratique : Raccourci Clavier

L’opérateur d’affectation <- a un raccourci clavier :

Astuce

Alt + - (moins) (Windows/Linux)

Option + - (moins) (Mac)

Cela écrit <- automatiquement !

Pratiquons le concept :

# Créer une variable avec l'année extraite
panel_vat <- panel_vat %>%
  mutate(filing_year = year(declaration_date))

# Vérifier qu'elle est là
"filing_year" %in% names(panel_vat)
[1] TRUE

L’Opérateur Pipe : %>%

L’opérateur pipe (%>%) est la clé pour écrire du code clair et lisible.

Pensez-y comme “et puis” :

# Sans pipes - difficile à lire !
arrange(select(filter(tax_data, filing_year == 2023), firm_id, vat_outputs), desc(vat_outputs))

# Avec pipes - beaucoup plus clair !
tax_data %>%
  filter(filing_year == 2023) %>%
  select(firm_id, vat_outputs) %>%
  arrange(desc(vat_outputs))

Comment le lire :

  1. Commencer avec vos données : tax_data
  2. PUIS (%>%) filtrer à 2023
  3. PUIS (%>%) sélectionner des colonnes spécifiques
  4. PUIS (%>%) trier les résultats

Astuce

Raccourci clavier : Ctrl + Shift + M (Windows) ou Cmd + Shift + M (Mac)

Exemple de Pipe : Café du Matin ☕

Comprenons les pipes avec un exemple quotidien :

Faire du café (sans pipes) :

drink(pour(brew(grind(beans))))
# Vous devez lire de l'intérieur vers l'extérieur ! Confus !

Faire du café (avec pipes) :

beans %>%
  grind() %>%
  brew() %>%
  pour() %>%
  drink()

# Lire de haut en bas - comme suivre une recette !

La même logique pour les données fiscales :

panel_vat %>%
  mutate(filing_year = year(declaration_date)) %>%  # Extraire l'année d'abord
  filter(filing_year == 2023) %>%                   # Puis filtrer
  arrange(desc(vat_outputs))                        # Puis trier

Filtrer les Lignes : filter()

Filtrage de Base

filter() sélectionne des lignes basées sur des conditions :

# Obtenir seulement les déclarations de 2023
vat_2023 <- panel_vat %>%
  filter(filing_year == 2023)

nrow(vat_2023)  # Combien de lignes restent ?
[1] 339

Opérateurs de comparaison courants :

  • == égal à
  • != différent de
  • > plus grand que
  • < plus petit que
  • >= plus grand ou égal à
  • <= plus petit ou égal à

Conditions Multiples

Utiliser des virgules ou & pour AND (toutes les conditions doivent être vraies) :

# Grands contribuables en 2023
large_vat_2023 <- panel_vat %>%
  filter(filing_year == 2023, vat_outputs > 40000)

nrow(large_vat_2023)
[1] 71

Utiliser | pour OR (n’importe quelle condition peut être vraie) :

# Très bas ou très haut
extreme_vat <- panel_vat %>%
  filter(vat_outputs < 5000 | vat_outputs > 50000)

nrow(extreme_vat)
[1] 84

Filtrer avec %in%

Vérifier si les valeurs correspondent à une liste :

# Entreprises spécifiques
selected_firms <- c("FIRM_001", "FIRM_003", "FIRM_005")

firms_subset <- panel_vat %>%
  filter(firm_id %in% selected_firms)

unique(firms_subset$firm_id)
character(0)

Nier avec ! (pas dans la liste) :

# Toutes sauf ces entreprises
other_firms <- panel_vat %>%
  filter(!firm_id %in% selected_firms)

nrow(other_firms)
[1] 1000

Exercice 1 : Pratique de Filtrage

Vous pouvez trouver l’exercice dans le dossier “Exercises/exercise_01_template.R”

10:00

Vos tâches :

En utilisant panel_vat :

  1. Filtrer les déclarations où vat_outputs > 30000
  2. Filtrer les entreprises qui ont déclaré en T1 de 2023 (filing_quarter == 1 ET filing_year == 2023)
  3. Trouver les déclarations avec TVA nette négative (vat_outputs - vat_inputs < 0)
  4. Bonus : Trouver les déclarations des 5 entreprises principales par total de vat_outputs

Indice : Pour le bonus, utilisez group_by(), summarize(), arrange(), et head()

Exercice 1 : Solutions

# 1. Filtrer grands outputs
grands_outputs <- panel_vat %>%
  filter(vat_outputs > 30000)
nrow(grands_outputs)

# 2. Filtrer T1 de 2023
q1_2023 <- panel_vat %>%
  filter(filing_year == 2023, filing_quarter == 1)
nrow(q1_2023)

# 3. TVA nette négative
tva_negative <- panel_vat %>%
  filter(vat_outputs - vat_inputs < 0)
nrow(tva_negative)

# 4. Bonus : Top 5 entreprises
top_firms <- panel_vat %>%
  group_by(firm_id) %>%
  summarize(total_vat = sum(vat_outputs, na.rm = TRUE), .groups = "drop") %>%
  arrange(desc(total_vat)) %>%
  head(5)

# Déclarations de ces entreprises
declarations_top <- panel_vat %>%
  filter(firm_id %in% top_firms$firm_id)

Sélectionner des Colonnes : select()

Sélection de Base

select() choisit quelles colonnes conserver :

# Garder seulement des colonnes spécifiques
vat_simple <- panel_vat %>%
  select(firm_id, declaration_date, vat_outputs, vat_inputs)

names(vat_simple)
[1] "firm_id"          "declaration_date" "vat_outputs"      "vat_inputs"      

Exclure des colonnes avec - :

# Garder tout sauf filing_month
vat_no_month <- panel_vat %>%
  select(-filing_month)

names(vat_no_month)
[1] "firm_id"            "declaration_date"   "vat_inputs"        
[4] "vat_outputs"        "reimbursement_date" "filing_year"       
[7] "filing_quarter"    

Fonctions Auxiliaires de Select

Sélectionner des colonnes par motif :

# Toutes les colonnes commençant par "vat"
vat_cols <- panel_vat %>%
  select(starts_with("vat"))

names(vat_cols)
[1] "vat_inputs"  "vat_outputs"

Autres fonctions auxiliaires utiles :

# Colonnes se terminant par "_date"
select(ends_with("_date"))

# Colonnes contenant "filing"
select(contains("filing"))

# Réorganiser - mettre firm_id en premier, puis tout le reste
select(firm_id, everything())

Renommer en Sélectionnant

Vous pouvez renommer des colonnes dans select() :

# Sélectionner et renommer
vat_renamed <- panel_vat %>%
  select(
    empresa = firm_id,
    fecha = declaration_date,
    iva_cobrado = vat_outputs,
    iva_pagado = vat_inputs
  )

names(vat_renamed)
[1] "empresa"     "fecha"       "iva_cobrado" "iva_pagado" 

Ou utiliser rename() pour garder toutes les colonnes :

# Renommer sans supprimer d'autres colonnes
panel_vat %>%
  rename(iva_cobrado = vat_outputs, iva_pagado = vat_inputs)

Créer/Modifier des Colonnes : mutate()

Créer de Nouvelles Colonnes

mutate() est votre outil le plus important - crée ou modifie des colonnes :

# Calculer TVA nette
vat_with_net <- panel_vat %>%
  mutate(net_vat = vat_outputs - vat_inputs)

# Vérifier les nouvelles colonnes
vat_with_net %>%
  select(firm_id, vat_outputs, vat_inputs, net_vat) %>%
  head(3)
     firm_id vat_outputs vat_inputs net_vat
      <char>       <int>      <int>   <int>
1: FIRM_0096       45914      45262     652
2: FIRM_0081       29661       9225   20436
3: FIRM_0024       10005      15289   -5284

Mutations Multiples

Créer plusieurs colonnes à la fois :

# Ajouter plusieurs calculs
vat_enhanced <- panel_vat %>%
  mutate(
    net_vat = vat_outputs - vat_inputs,
    vat_ratio = vat_inputs / vat_outputs,
    is_large = vat_outputs > 40000
  )

vat_enhanced %>%
  select(firm_id, net_vat, vat_ratio, is_large) %>%
  head(3)
     firm_id net_vat vat_ratio is_large
      <char>   <int>     <num>   <lgcl>
1: FIRM_0096     652 0.9857995     TRUE
2: FIRM_0081   20436 0.3110145    FALSE
3: FIRM_0024   -5284 1.5281359    FALSE

Astuce

Vous pouvez référencer des colonnes nouvellement créées dans la même instruction mutate !

Logique Conditionnelle : if_else()

Créer des colonnes basées sur des conditions :

# Catégoriser les contribuables
vat_categorized <- panel_vat %>%
  mutate(
    taxpayer_size = if_else(
      vat_outputs > 40000,
      "Grand",
      "Petit"
    )
  )

vat_categorized %>%
  select(firm_id, vat_outputs, taxpayer_size) %>%
  head(3)
     firm_id vat_outputs taxpayer_size
      <char>       <int>        <char>
1: FIRM_0096       45914         Grand
2: FIRM_0081       29661         Petit
3: FIRM_0024       10005         Petit

Syntaxe :

if_else(condition, valeur_si_vrai, valeur_si_faux)

Conditions Multiples : case_when()

Pour plus de 2 catégories, utilisez case_when() :

# Catégories de taille multiples
vat_sized <- panel_vat %>%
  mutate(
    size_category = case_when(
      vat_outputs > 40000 ~ "Grand",
      vat_outputs > 20000 ~ "Moyen",
      vat_outputs > 5000 ~ "Petit",
      TRUE ~ "Micro"  # Tout le reste
    )
  )

vat_sized %>%
  select(firm_id, vat_outputs, size_category) %>%
  head(5)
     firm_id vat_outputs size_category
      <char>       <int>        <char>
1: FIRM_0096       45914         Grand
2: FIRM_0081       29661         Moyen
3: FIRM_0024       10005         Petit
4: FIRM_0091       14410         Petit
5: FIRM_0014       33378         Moyen

Exercice 2 : Pratique de Mutate

Vous pouvez trouver l’exercice dans le dossier “Exercises/exercise_02_template.R”

10:00

Vos tâches :

En utilisant panel_vat :

  1. Créer net_vat (vat_outputs - vat_inputs)
  2. Créer vat_ratio (vat_inputs / vat_outputs)
  3. Créer un drapeau logique is_refund (vrai si net_vat < 0)
  4. Créer une catégorie compliance_status :
    • “Risque élevé” si vat_ratio > 0.95
    • “Risque modéré” si vat_ratio > 0.80
    • “Risque faible” sinon

Bonus : Créer days_to_file calculant les jours entre declaration_date et la fin de filing_quarter

Exercice 2 : Solutions

# Charger les paquets
library(dplyr)
library(lubridate)

# Créer des variables
vat_ameliore <- panel_vat %>%
  mutate(
    # 1. TVA nette
    net_vat = vat_outputs - vat_inputs,
    
    # 2. Ratio de TVA
    vat_ratio = vat_inputs / vat_outputs,
    
    # 3. Drapeau de remboursement
    is_refund = if_else(net_vat < 0, TRUE, FALSE),
    
    # 4. Statut de conformité
    compliance_status = case_when(
      vat_ratio > 0.95 ~ "Risque élevé",
      vat_ratio > 0.80 ~ "Risque modéré",
      TRUE ~ "Risque faible"
    )
  )

# Bonus : Jours pour déclarer
vat_ameliore <- vat_ameliore %>%
  mutate(
    quarter_end = ceiling_date(declaration_date, "quarter") - days(1),
    days_to_file = as.numeric(declaration_date - quarter_end)
  )

# Vérifier les résultats
vat_ameliore %>%
  select(firm_id, net_vat, vat_ratio, is_refund, compliance_status) %>%
  head(5)

Trier les Données : arrange()

Tri de Base

arrange() trie les lignes par colonnes :

# Trier par vat_outputs (du plus petit au plus grand)
vat_sorted <- panel_vat %>%
  arrange(vat_outputs)

vat_sorted %>%
  select(firm_id, vat_outputs) %>%
  head(5)
     firm_id vat_outputs
      <char>       <int>
1: FIRM_0066        1014
2: FIRM_0044        1045
3: FIRM_0020        1073
4: FIRM_0032        1110
5: FIRM_0072        1168

Trier en ordre décroissant avec desc() :

# Plus grands contribuables d'abord
vat_sorted_desc <- panel_vat %>%
  arrange(desc(vat_outputs))

vat_sorted_desc %>%
  select(firm_id, vat_outputs) %>%
  head(5)
     firm_id vat_outputs
      <char>       <int>
1: FIRM_0020       49969
2: FIRM_0096       49844
3: FIRM_0040       49806
4: FIRM_0075       49710
5: FIRM_0022       49689

Tri Multiple

Trier par plusieurs colonnes :

# Trier par année, puis par entreprise, puis par outputs
vat_multi_sorted <- panel_vat %>%
  arrange(filing_year, firm_id, desc(vat_outputs))

vat_multi_sorted %>%
  select(firm_id, filing_year, vat_outputs) %>%
  head(5)
     firm_id filing_year vat_outputs
      <char>       <int>       <int>
1: FIRM_0001        2021       24343
2: FIRM_0002        2021       26706
3: FIRM_0002        2021        3018
4: FIRM_0003        2021       29978
5: FIRM_0003        2021        7239

Astuce

L’ordre compte ! R trie par la première colonne, puis départage avec la deuxième, etc.

Résumé et Regroupement

Agrégation de Base : summarize()

summarize() réduit les données en résumés :

# Statistiques générales
vat_summary <- panel_vat %>%
  summarize(
    total_vat = sum(vat_outputs, na.rm = TRUE),
    avg_vat = mean(vat_outputs, na.rm = TRUE),
    max_vat = max(vat_outputs, na.rm = TRUE),
    num_declarations = n()
  )

vat_summary
  total_vat  avg_vat max_vat num_declarations
1  25883247 25883.25   49969             1000

Fonctions de résumé utiles :

  • sum() - total
  • mean() - moyenne
  • median() - médiane
  • sd() - écart-type
  • min(), max() - minimum, maximum
  • n() - compter les lignes
  • n_distinct() - compter les valeurs uniques

Analyse par Groupe : group_by()

Le vrai pouvoir vient de group_by() + summarize() :

# Analyse par année
vat_by_year <- panel_vat %>%
  group_by(filing_year) %>%
  summarize(
    total_vat = sum(vat_outputs, na.rm = TRUE),
    avg_vat = mean(vat_outputs, na.rm = TRUE),
    num_firms = n_distinct(firm_id),
    .groups = "drop"
  )

vat_by_year
# A tibble: 3 × 4
  filing_year total_vat avg_vat num_firms
        <int>     <int>   <dbl>     <int>
1        2021   8582818  26088.        96
2        2022   8436159  25410.        95
3        2023   8864270  26148.        97

Important

Ajoutez toujours .groups = "drop" après summarize pour éviter des problèmes !

Regroupement Multiple

Regrouper par plusieurs variables :

# Analyse par année ET trimestre
vat_by_period <- panel_vat %>%
  group_by(filing_year, filing_quarter) %>%
  summarize(
    total_vat = sum(vat_outputs, na.rm = TRUE),
    num_declarations = n(),
    .groups = "drop"
  )

head(vat_by_period, 8)
# A tibble: 8 × 4
  filing_year filing_quarter total_vat num_declarations
        <int>          <int>     <int>            <int>
1        2021              1   1870290               72
2        2021              2   2127706               77
3        2021              3   2446393               95
4        2021              4   2138429               85
5        2022              1   2317221               90
6        2022              2   1925538               78
7        2022              3   2352286               86
8        2022              4   1841114               78

Comptage Simple : count()

Pour seulement compter, count() est plus simple :

# Compter les déclarations par année
panel_vat %>%
  count(filing_year)
   filing_year     n
         <int> <int>
1:        2021   329
2:        2022   332
3:        2023   339

Avec plusieurs variables :

# Compter par année et trimestre
panel_vat %>%
  count(filing_year, filing_quarter)
    filing_year filing_quarter     n
          <int>          <int> <int>
 1:        2021              1    72
 2:        2021              2    77
 3:        2021              3    95
 4:        2021              4    85
 5:        2022              1    90
 6:        2022              2    78
 7:        2022              3    86
 8:        2022              4    78
 9:        2023              1    82
10:        2023              2    91
11:        2023              3    94
12:        2023              4    72

Mutations Groupées

group_by() fonctionne aussi avec mutate() :

# Calculer la part d'entreprise de la TVA trimestrielle
vat_with_share <- panel_vat %>%
  group_by(filing_quarter) %>%
  mutate(
    quarter_total = sum(vat_outputs, na.rm = TRUE),
    firm_share = vat_outputs / quarter_total * 100
  ) %>%
  ungroup()  # Toujours dégrouper après !

vat_with_share %>%
  select(firm_id, filing_quarter, vat_outputs, firm_share) %>%
  head(5)
# A tibble: 5 × 4
  firm_id   filing_quarter vat_outputs firm_share
  <chr>              <int>       <int>      <dbl>
1 FIRM_0096              1       45914      0.697
2 FIRM_0081              2       29661      0.471
3 FIRM_0024              1       10005      0.152
4 FIRM_0091              3       14410      0.200
5 FIRM_0014              3       33378      0.464

Avertissement

Utilisez toujours ungroup() après des opérations groupées avec mutate !

Travailler avec les Dates

Le Paquet lubridate

lubridate facilite le travail avec les dates :

library(lubridate)

# Extraire les composants de date
date_exemple <- as.Date("2023-03-15")

year(date_exemple)    # Année
[1] 2023
month(date_exemple)   # Mois (numéro)
[1] 3
day(date_exemple)     # Jour
[1] 15
quarter(date_exemple) # Trimestre
[1] 1
wday(date_exemple)    # Jour de la semaine (1 = Dimanche)
[1] 4

Créer des Variables de Date

Modèle courant pour les données fiscales :

# Ajouter des composants de date utiles
vat_with_dates <- panel_vat %>%
  mutate(
    filing_year = year(declaration_date),
    filing_quarter = quarter(declaration_date),
    filing_month = month(declaration_date),
    filing_day = day(declaration_date),
    filing_weekday = wday(declaration_date)
  )

vat_with_dates %>%
  select(declaration_date, filing_year, filing_quarter, filing_month, filing_weekday) %>%
  head(3)
   declaration_date filing_year filing_quarter filing_month filing_weekday
             <Date>       <int>          <int>        <int>          <int>
1:       2023-01-31        2023              1            1              3
2:       2022-05-31        2022              2            5              3
3:       2023-03-31        2023              1            3              6

Calculs de Date

Calculer des différences de date :

# Jours depuis la dernière déclaration par entreprise
vat_with_gaps <- panel_vat %>%
  arrange(firm_id, declaration_date) %>%
  group_by(firm_id) %>%
  mutate(
    days_since_last = as.numeric(declaration_date - lag(declaration_date))
  ) %>%
  ungroup()

vat_with_gaps %>%
  select(firm_id, declaration_date, days_since_last) %>%
  filter(!is.na(days_since_last)) %>%
  head(5)
# A tibble: 5 × 3
  firm_id   declaration_date days_since_last
  <chr>     <date>                     <dbl>
1 FIRM_0001 2022-03-31                   335
2 FIRM_0001 2022-05-31                    61
3 FIRM_0001 2022-08-31                    92
4 FIRM_0001 2022-10-31                    61
5 FIRM_0001 2023-04-30                   181

Astuce

lag() obtient la valeur de la ligne précédente dans chaque groupe !

Fonctions de Date Utiles

# Arrondir les dates
date_exemple <- as.Date("2023-03-15")

floor_date(date_exemple, "month")    # Début du mois
[1] "2023-03-01"
ceiling_date(date_exemple, "month")  # Fin du mois
[1] "2023-04-01"
floor_date(date_exemple, "quarter")  # Début du trimestre
[1] "2023-01-01"

Opérations de date courantes :

# Ajouter/soustraire du temps
date_exemple + days(7)      # 7 jours plus tard
date_exemple - months(1)    # 1 mois avant
date_exemple + years(1)     # 1 an plus tard

# Calculer des intervalles
interval(date_debut, date_fin) / days(1)  # Jours entre dates

Opérations Spéciales

Supprimer les Doublons : distinct()

Obtenir des lignes uniques :

# Obtenir une liste unique d'entreprises
unique_firms <- panel_vat %>%
  distinct(firm_id)

nrow(unique_firms)
[1] 100

Garder d’autres colonnes :

# Obtenir une déclaration par entreprise (la première)
one_per_firm <- panel_vat %>%
  distinct(firm_id, .keep_all = TRUE)

nrow(one_per_firm)
[1] 100

Découper les Données : slice()

Obtenir des lignes spécifiques :

# Premières 5 lignes
panel_vat %>%
  slice(1:5) %>%
  select(firm_id, declaration_date)
     firm_id declaration_date
      <char>           <Date>
1: FIRM_0096       2023-01-31
2: FIRM_0081       2022-05-31
3: FIRM_0024       2023-03-31
4: FIRM_0091       2023-08-31
5: FIRM_0014       2023-09-30

Top/Bottom par groupe :

# Plus grande déclaration de TVA par entreprise
top_per_firm <- panel_vat %>%
  group_by(firm_id) %>%
  slice_max(vat_outputs, n = 1) %>%
  ungroup()

head(top_per_firm, 3)
# A tibble: 3 × 8
  firm_id declaration_date vat_inputs vat_outputs reimbursement_date filing_year
  <chr>   <date>                <int>       <int> <date>                   <int>
1 FIRM_0… 2023-10-31             2032       49327 2022-01-31                2023
2 FIRM_0… 2023-07-31            42580       44400 2022-02-28                2023
3 FIRM_0… 2023-04-30            11753       47713 2022-09-30                2023
# ℹ 2 more variables: filing_quarter <int>, filing_month <int>

Échantillonnage : slice_sample()

Échantillonnage aléatoire pour l’analyse :

# Échantillon aléatoire de 5 lignes
panel_vat %>%
  slice_sample(n = 5) %>%
  select(firm_id, vat_outputs)
     firm_id vat_outputs
      <char>       <int>
1: FIRM_0077       29739
2: FIRM_0072        5627
3: FIRM_0095       36992
4: FIRM_0075       10066
5: FIRM_0044        9112

Échantillonnage proportionnel :

# Échantillon aléatoire de 10%
panel_vat %>%
  slice_sample(prop = 0.1)

Réorganiser les Lignes : relocate()

Déplacer les colonnes vers des positions spécifiques :

# Déplacer firm_id au début
vat_reordered <- panel_vat %>%
  relocate(firm_id, declaration_date)

names(vat_reordered)[1:5]
[1] "firm_id"            "declaration_date"   "vat_inputs"        
[4] "vat_outputs"        "reimbursement_date"
# Déplacer les colonnes après une autre
panel_vat %>%
  relocate(vat_inputs, .after = vat_outputs)

# Déplacer les colonnes à la fin
panel_vat %>%
  relocate(filing_month, .after = last_col())

Construire des Flux de Travail Complets

Enchaîner Plusieurs Opérations

Le vrai pouvoir de dplyr vient de combiner des opérations dans une séquence logique :

# Exemple de flux de travail complet
analysis_result <- panel_vat %>%
  # Étape 1 : Calculer de nouvelles variables
  mutate(
    net_vat = vat_outputs - vat_inputs,
    filing_quarter = quarter(declaration_date)
  ) %>%
  
  # Étape 2 : Filtrer sur données récentes
  filter(filing_year == 2023) %>%
  
  # Étape 3 : Analyser par trimestre
  group_by(filing_quarter) %>%
  summarize(
    total_vat = sum(net_vat, na.rm = TRUE),
    avg_vat = mean(net_vat, na.rm = TRUE),
    num_firms = n_distinct(firm_id),
    .groups = "drop"
  )

analysis_result
# A tibble: 4 × 4
  filing_quarter total_vat avg_vat num_firms
           <int>     <int>   <dbl>     <int>
1              1    442405   5395.        54
2              2     15185    167.        59
3              3   -104600  -1113.        62
4              4    179021   2486.        49

Quand Diviser en Étapes

Parfois, il est préférable de diviser de longs pipelines en morceaux plus petits :

Bon pour les flux de travail complexes :

# Étape 1 : Ajouter des variables dérivées
vat_enhanced <- panel_vat %>%
  mutate(
    net_vat = vat_outputs - vat_inputs,
    filing_quarter = quarter(declaration_date)
  )

# Étape 2 : Analyser
vat_summary <- vat_enhanced %>%
  group_by(filing_year, filing_quarter) %>%
  summarize(avg_vat = mean(net_vat, na.rm = TRUE), .groups = "drop")

head(vat_summary)
# A tibble: 6 × 3
  filing_year filing_quarter avg_vat
        <int>          <int>   <dbl>
1        2021              1   -519.
2        2021              2   2447.
3        2021              3    219.
4        2021              4    442.
5        2022              1    100.
6        2022              2  -1321.

Astuce

Diviser en étapes quand :

  • Le pipeline devient trop long (>10 opérations)
  • Vous voulez vérifier les résultats intermédiaires
  • Vous réutiliserez des jeux de données intermédiaires

Créer des Variables Dérivées

Construisez votre analyse avec des colonnes calculées significatives :

# Créer un jeu de données enrichi avec de nombreuses variables dérivées
panel_vat_enhanced <- panel_vat %>%
  mutate(
    # Calculs financiers
    net_vat = vat_outputs - vat_inputs,
    vat_ratio = vat_inputs / vat_outputs,
    
    # Drapeaux de logique métier
    is_refund = if_else(net_vat < 0, TRUE, FALSE),
    large_taxpayer = if_else(vat_outputs > 40000, TRUE, FALSE),
    high_ratio = if_else(vat_ratio > 0.9, TRUE, FALSE, missing = FALSE)
  )

# Vérifier ce que nous avons créé
panel_vat_enhanced %>%
  select(firm_id, net_vat, is_refund, large_taxpayer, high_ratio) %>%
  head(5)
     firm_id net_vat is_refund large_taxpayer high_ratio
      <char>   <int>    <lgcl>         <lgcl>     <lgcl>
1: FIRM_0096     652     FALSE           TRUE       TRUE
2: FIRM_0081   20436     FALSE          FALSE      FALSE
3: FIRM_0024   -5284      TRUE          FALSE       TRUE
4: FIRM_0091    5063     FALSE          FALSE      FALSE
5: FIRM_0014  -13939      TRUE          FALSE       TRUE

Sauvegarder les Sorties Transformées

Sauvegardez vos jeux de données améliorés pour utilisation dans les modules ultérieurs :

# Sauvegarder le panel TVA amélioré dans le dossier Clean
panel_vat_clean <- panel_vat %>%
  mutate(
    net_vat = vat_outputs - vat_inputs,
    filing_quarter = quarter(declaration_date),
    is_refund = net_vat < 0,
    large_taxpayer = vat_outputs > 40000
  )

fwrite(panel_vat_clean,
       here("r_training_datax", "Exercises", "data", "Clean", "panel_vat_clean.csv"))

# Sauvegarder le panel CIT amélioré dans le dossier Clean
panel_cit_clean <- panel_cit %>%
  mutate(
    filing_quarter = quarter(declaration_date),
    effective_tax_rate = tax_paid / taxable_income
  )

fwrite(panel_cit_clean,
       here("r_training_datax", "Exercises", "data", "Clean", "panel_cit_clean.csv"))

Meilleures Pratiques d’Organisation de Fichiers

Gardez vos fichiers organisés :

r_training_datax/
└── Exercises/
    └── data/
        ├── Raw/              # Données originales, non touchées
        │   ├── firm_characteristics.csv
        │   ├── vat_declarations.dta
        │   └── cit_declarations.xlsx
        ├── intermediate/     # Après nettoyage du Module 2
        │   ├── dt_firms.csv
        │   ├── panel_vat.csv
        │   └── panel_cit.csv
        └── Clean/            # Après transformation du Module 3
            ├── panel_vat_clean.csv
            └── panel_cit_clean.csv

Astuce

Sauvegardez les versions améliorées dans le dossier Clean pour pouvoir les utiliser dans les modules futurs !

Exercice 3 : Flux de Travail de Transformation Complet

Vous pouvez trouver l’exercice dans le dossier “Exercises/exercise_03_template.R”

15:00

Vos tâches :

Créez des jeux de données complètement transformés prêts pour l’analyse :

  1. Transformer panel_vat :
    • Ajouter net_vat, filing_year, filing_quarter, filing_month
    • Calculer vat_ratio et days_since_last par entreprise
    • Créer des drapeaux : is_refund, large_taxpayer (>40000), high_ratio (>0.9)
    • Sauvegarder comme data/Clean/panel_vat_clean.csv en utilisant fwrite()
  2. Transformer panel_cit :
    • Ajouter filing_year, filing_quarter
    • Calculer effective_tax_rate (tax_paid / taxable_income)
    • Créer un drapeau : has_adjustments (adjustments != 0)
    • Sauvegarder comme data/Clean/panel_cit_clean.csv en utilisant fwrite()
  3. Transformer dt_firms :
    • Renommer les colonnes en minuscules en utilisant clean_names()
    • Sauvegarder comme data/Clean/dt_firms_clean.csv en utilisant fwrite()
  4. Vérifier votre travail :
    • Vérifier que les trois fichiers existent dans le dossier Clean en utilisant file.exists()
    • Les recharger et vérifier que les nouvelles colonnes sont présentes en utilisant names() et glimpse()

Rappel : Ces jeux de données nettoyés seront utilisés dans les Modules 4, 5 et 6 !

Exercice 3 : Solutions

# Charger les paquets requis
library(dplyr)
library(lubridate)
library(data.table)
library(here)
library(janitor)

# Charger les données depuis le dossier intermediate
panel_vat <- fread(here("r_training_datax", "Exercises", "data", "intermediate", "panel_vat.csv"))
panel_cit <- fread(here("r_training_datax", "Exercises", "data", "intermediate", "panel_cit.csv"))
dt_firms <- fread(here("r_training_datax", "Exercises", "data", "intermediate", "dt_firms.csv"))

# Convertir les dates
panel_vat$declaration_date <- as.Date(panel_vat$declaration_date)
panel_cit$declaration_date <- as.Date(panel_cit$declaration_date)

# 1. Transformer panel_vat
panel_vat_clean <- panel_vat %>%
  # Ajouter des composants de date
  mutate(
    filing_year = year(declaration_date),
    filing_quarter = quarter(declaration_date),
    filing_month = month(declaration_date)
  ) %>%
  # Calculer des métriques financières
  mutate(
    net_vat = vat_outputs - vat_inputs,
    vat_ratio = vat_inputs / vat_outputs
  ) %>%
  # Créer des drapeaux métier
  mutate(
    is_refund = if_else(net_vat < 0, TRUE, FALSE),
    large_taxpayer = if_else(vat_outputs > 40000, TRUE, FALSE),
    high_ratio = if_else(vat_ratio > 0.9, TRUE, FALSE, missing = FALSE)
  ) %>%
  # Calculer les jours entre déclarations par entreprise
  arrange(firm_id, declaration_date) %>%
  group_by(firm_id) %>%
  mutate(days_since_last = as.numeric(declaration_date - lag(declaration_date))) %>%
  ungroup()

# Sauvegarder dans le dossier Clean
fwrite(panel_vat_clean,
       here("r_training_datax", "Exercises", "data", "Clean", "panel_vat_clean.csv"))

# 2. Transformer panel_cit
panel_cit_clean <- panel_cit %>%
  # Ajouter des composants de date
  mutate(
    filing_year = year(declaration_date),
    filing_quarter = quarter(declaration_date)
  ) %>%
  # Calculer des métriques financières
  mutate(
    effective_tax_rate = tax_paid / taxable_income
  ) %>%
  # Créer des drapeaux métier
  mutate(
    has_adjustments = if_else(adjustments != 0, TRUE, FALSE)
  )

# Sauvegarder dans le dossier Clean
fwrite(panel_cit_clean,
       here("r_training_datax", "Exercises", "data", "Clean", "panel_cit_clean.csv"))

# 3. Transformer dt_firms
dt_firms_clean <- dt_firms %>%
  clean_names()

# Sauvegarder dans le dossier Clean
fwrite(dt_firms_clean,
       here("r_training_datax", "Exercises", "data", "Clean", "dt_firms_clean.csv"))

# 4. Vérifier le travail
file.exists(here("r_training_datax", "Exercises", "data", "Clean", "panel_vat_clean.csv"))
file.exists(here("r_training_datax", "Exercises", "data", "Clean", "panel_cit_clean.csv"))
file.exists(here("r_training_datax", "Exercises", "data", "Clean", "dt_firms_clean.csv"))

# Les recharger
vat_verify <- fread(here("r_training_datax", "Exercises", "data", "Clean", "panel_vat_clean.csv"))
cit_verify <- fread(here("r_training_datax", "Exercises", "data", "Clean", "panel_cit_clean.csv"))
firms_verify <- fread(here("r_training_datax", "Exercises", "data", "Clean", "dt_firms_clean.csv"))

# Vérifier les colonnes
names(vat_verify)
names(cit_verify)
names(firms_verify)

# Résumé rapide
glimpse(vat_verify)
glimpse(cit_verify)
glimpse(firms_verify)

Ce Que Nous Avons Appris

Verbes centraux de dplyr :

  • filter() - sélectionner des lignes
  • select() - choisir des colonnes
  • mutate() - créer/modifier des colonnes
  • arrange() - trier les données
  • summarize() + group_by() - agréger
  • count() - fréquences
  • distinct() - supprimer les doublons

Opérations avec dates :

  • Analyser les dates avec lubridate
  • Extraire des composants de date
  • Calculer des différences de date
  • Créer des variables basées sur le temps

Résumé des Meilleures Pratiques

Utilisez toujours les pipes (%>%) pour enchaîner clairement les opérations

Sauvegardez votre travail avec <- pour les variables que vous réutiliserez

Incluez na.rm = TRUE dans les calculs

Utilisez des noms de variables significatifs (net_vat, pas x1)

Commentez votre code pour que les autres le comprennent

Sauvegardez les jeux de données transformés dans le dossier Clean pour les modules futurs

Ajoutez .groups = "drop" après group_by() + summarize()

Merci !

Questions ?

Note

Prochaines étapes :

  • Pratiquez la combinaison de plusieurs opérations dplyr
  • Expérimentez avec vos propres données fiscales
  • Préparez-vous pour le Module 4 : Combiner des jeux de données !