15  De-duplication

Cette page couvre les techniques de déduplication ci-dessous :

  1. Identifier et supprimer les lignes dupliquées
  2. Utiliser la fonction “slice” pour garder seulement certaines lignes (par exemple, min ou max) de chaque groupe de lignes.
  3. “Rolling-up”, ou combinaison des valeurs de plusieurs lignes en une seule ligne.

15.1 Préparation

Importation des packages

Ces lignes de code importe les packages necessaire pour l’analyse. Dans ce guide, nous mettons l’accent sur p_load() de pacman, qui installe le package si nécessaire puis l’importe pour l’utiliser. Vous pouvez également charger les packages installés avec library() de base R. Voir la page sur bases de R pour plus d’informations sur les packages en R.

pacman::p_load(
  tidyverse,   # fonctions de déduplication, de regroupement et de slicing
  janitor,     # fonction de gestion des doublons 
  stringr)     # pour la recherche des caractères, peut être utilisé ensembler les valeurs

Importer les données

Pour la démonstration, nous allons utiliser un ensemble de données exemplaire qui a été créé avec le code R ci-dessous.

Les données sont des enregistrements des appels téléphoniques sur le COVID-19, y compris les appels avec des contacts et des cas. Les colonnes comprennent recordID (généré par ordinateur), personID, name, date de la rencontre, time de la rencontre, le purpose de la rencontre (soit pour un interview en tant que cas ou en tant que contact), et symptoms_ever (si la personne dans cette appel a déclaré avoir jamais eu des symptômes).

Voici le code pour créer la base de données obs :

obs <- data.frame(
  recordID  = c(1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18),
  personID  = c(1,1,2,2,3,2,4,5,6,7,2,1,3,3,4,5,5,7,8),
  name      = c("adam", "adam", "amrish", "amrish", "mariah", "amrish", "nikhil", "brian", "smita", "raquel", "amrish",
                "adam", "mariah", "mariah", "nikhil", "brian", "brian", "raquel", "natalie"),
  date      = c("1/1/2020", "1/1/2020", "2/1/2020", "2/1/2020", "5/1/2020", "5/1/2020", "5/1/2020", "5/1/2020", "5/1/2020","5/1/2020", "2/1/2020",
                "5/1/2020", "6/1/2020", "6/1/2020", "6/1/2020", "6/1/2020", "7/1/2020", "7/1/2020", "7/1/2020"),
  time      = c("09:00", "09:00", "14:20", "14:20", "12:00", "16:10", "13:01", "15:20", "14:20", "12:30", "10:24",
                "09:40", "07:25", "08:32", "15:36", "15:31", "07:59", "11:13", "17:12"),
  encounter = c(1,1,1,1,1,3,1,1,1,1,2,
                2,2,3,2,2,3,2,1),
  purpose   = c("contact", "contact", "contact", "contact", "case", "case", "contact", "contact", "contact", "contact", "contact",
                "case", "contact", "contact", "contact", "contact", "case", "contact", "case"),
  symptoms_ever = c(NA, NA, "No", "No", "No", "Yes", "Yes", "No", "Yes", NA, "Yes",
                    "No", "No", "No", "Yes", "Yes", "No","No", "No")) %>% 
  mutate(date = as.Date(date, format = "%d/%m/%Y"))

Voici le tableau de données

Utilisez les boîtes de filtre au-dessous pour examiner les rencontres pour chaque personne.

Quelques éléments à noter lors de l’examen des données :

  • Les deux premiers enregistrements sont des doublons complets à 100%, y compris le recordID ( cela doit être un problème informatique !).
  • Les deux secondes lignes sont des doublons, dans toutes les colonnes, sauf pour le recordID.
  • Plusieurs personnes ont été contactées plusieurs fois par téléphone, à des dates et horaires différents, et en tant que contacts et/ou cas.
  • A chaque rencontre, il a été demandé à la personne si elle avait jamais eu des symptômes, et certaines de ces informations sont manquantes.

Et voici un résumé de ces personnes et la raison de leurs rencontres, en utilisant tabyl() de janitor :

obs %>% 
  tabyl(name, purpose)
    name case contact
    adam    1       2
  amrish    1       3
   brian    1       2
  mariah    1       2
 natalie    1       0
  nikhil    0       2
  raquel    0       2
   smita    0       1

15.2 Deduplication

Cette section décrit comment examiner et supprimer les doublons dans un tableau de données. Elle montre également comment traiter les éléments dupliqués dans un vecteur.

Examiner les lignes dupliquées

Pour rapidement examiner les lignes qui ont été dupliquées, vous pouvez utiliser get_dupes() du package janitor. Par défaut, toutes les colonnes sont prises en compte lors de l’évaluation des duplications - les lignes retournées par la fonction sont des doublons à 100% en considérant les valeurs de toutes les colonnes.

Dans le tableau de données obs, les deux premières lignes sont 100% dupliquées - elles ont la même valeur dans chaque colonne (y compris la colonne recordID, qui est supposée être unique - cela doit être un problème informatique). Le tableau de données obtenu inclut automatiquement une nouvelle colonne dupe_count sur le côté droit, montrant le nombre de lignes avec cette combinaison de valeurs en double.

# 100% duplicates across all columns
obs %>% 
  janitor::get_dupes()

Voir les données originales

Cependant, si nous décidons d’ignorer le recordID, les 3e et 4e lignes sont également des doublons entre eux. C’est-à-dire qu’elles ont les mêmes valeurs dans toutes les colonnes sauf pour recordID. Vous pouvez spécifier des colonnes spécifiques à ignorer dans la fonction en utilisant le symbole moins -.

# Duplications lorsque la colonne recordID est exclue. 
obs %>% 
  janitor::get_dupes(-recordID)         # si multiples colonnes, les inclure dans c()

Vous pouvez également spécifier les colonnes à considérer. Ci-dessous, seules les lignes qui ont les mêmes valeurs dans les colonnes name et purpose sont retournées. Notez comment “amrish” a maintenant un dupe_count égal à 3 pour correspondre à ses trois rencontres “contact”.

*Défiler vers la gauche pour plus de lignes**

# duplications basées sur les colonnes name et purpose uniquement
obs %>% 
  janitor::get_dupes(name, purpose)

Voir les données originales

Voir ?get_dupes pour plus de details, ou consulter ceci référence en ligne

Garder seulement les lignes uniques

Pour garder que les lignes uniques d’un tableau de données, utilisez distinct() de dplyr (comme démontré dans la page CNettoyage de données et fonctions essentielles). Les lignes qui sont dupliquées sont enlevées de sorte que seule la première ligne est retenue. Par défaut, la première ligne correspond au plus grand rownumber (ordre des lignes de haut en bas). Seules les lignes uniques sont retenues.

Dans l’exemple ci-dessous, nous utilisons distinct() tel que la colonne recordID est exclue - ainsi deux lignes dupliquées sont enlevées. La première ligne (pour “adam”) était dupliquée à 100% et a été enlevée. Par ailleurs, la troisième ligne (pour “amrish”) était dupliquée dans chaque colonne sauf recordID (qui n’est pas considéré) donc a été supprimée. Le tableau de données obs est maintenant nrow(obs)-2, et non nrow(obs) lignes).

Défilez vers la gauche pour voir le tableau de données complet

# ajouté à une chaîne de pipes (par exemple, nettoyage de données)
obs %>% 
  distinct(across(-recordID), # réduit le tableau de données à seulement des lignes uniques (retient la première ligne de toute duplication)
           .keep_all = TRUE) 

# si en dehors des pipes, inclure les données comme premier argument  
# distinct(obs)

CAUTION: Si vous utilisez distinct() sur des données groupées, la fonction s’appliquera à chaque groupe.

Déduplication basée sur des colonnes spécifiques

Vous pouvez également spécifier des colonnes qui seront la base de la déduplication. Ainsi, la déduplication ne s’applique qu’aux lignes qui sont des duplications dans les colonnes spécifiées. A moins que vous ne définissiez .keep_all = TRUE, toutes les colonnes non mentionnées seront ignorées.

Dans l’exemple ci-dessous, la déduplication ne s’applique qu’aux lignes qui ont des valeurs identiques pour les colonnes name et purpose. Ainsi, “brian” a seulement 2 lignes au lieu de 3 - son premier “contact” et son unique “case”. Pour ajuster afin que la dernière rencontre de brian pour chaque “purpose” soit retenue, voir l’onglet “Slicing within groups”.

Défilez vers la gauche pour voir le tableau de données complet

# ajouté à une chaîne de pipes (par exemple, nettoyage de données)
obs %>% 
  distinct(name, purpose, .keep_all = TRUE) %>%  # garder les lignes uniques par 'name' et par 'purpose', retient toutes les colonnes
  arrange(name)                                  # arranger pour faciliter la visualisation

Voir données originales.

Dédupliquer les éléments d’un vecteur

La fonction duplicated() de base R va évaluer un vecteur (colonne) et renvoie un vecteur logique de même longueur (TRUE/FALSE). La première fois qu’une valeur apparaît, elle renvoie FALSE (pas de duplication), et les fois suivantes, elle renvoie VRAI. Notez que NA est traité de la même façon que toute autre valeur.

x <- c(1, 1, 2, NA, NA, 4, 5, 4, 4, 1, 2)
duplicated(x)
 [1] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE

Pour ne retourner que les éléments dupliqués, vous pouvez utiliser des parenthèses pour sous-titrer le vecteur original :

x[duplicated(x)]
[1]  1 NA  4  4  1  2

Pour ne renvoyer que les éléments uniques, utilisez unique() de base R. Pour supprimer les NA de la sortie, mettez na.omit() dans unique().

unique(x)           # alternativement, utilisez x[!duplicated(x)]
[1]  1  2 NA  4  5
unique(na.omit(x))  # supprimez les NA 
[1] 1 2 4 5

Utilisant base R

Pour retourner les lignes dupliquées

Dans base R, vous pouvez également voir quelles lignes sont dupliquées à 100% dans un tableau de données df avec la commande duplicated(df) ( retourne un vecteur logique des lignes).

Ainsi, vous pouvez également utiliser le sous-groupe de base [ ] sur le tableau de données pour voir les lignes dupliquées avec df[duplicated(df),] (n’oubliez pas la virgule, qui signifie que vous voulez voir toutes les colonnes !)

Pour retourner les lignes uniques

Voir les notes ci-dessus. Pour voir les lignes uniques, ajoutez le négateur logique ! devant la fonction duplicated() :
df[!duplicated(df),]

Pour retourner les lignes qui sont des duplications de certaines colonnes seulement.

Sous-ensembler le df qui se trouve *dans la parenthèse de duplicated(), afin que cette fonction ne traite que certaines colonnes du df.

Pour spécifier les colonnes, fournissez les numéros ou les noms des colonnes après une virgule (rappelez-vous, tout ceci est dans la fonction duplicated()).

Assurez-vous de garder la virgule , à l’extérieur après la fonction duplicated() également !

Par exemple, pour évaluer seulement les colonnes 2 à 5 pour les doublons : df[!duplicated(df[, 2:5]),]`` Pour évaluer seulement les colonnesnameetpurposepour les doublons :df[!duplicated(df[, c(“name”, “purpose)]),]`

15.3 Slicing

Pour “slice” un tableau de données pour pouvoir appliquer un filtre sur les lignes par numéro/position de ligne. Cette fonction devient particulièrement utile si vous avez plusieurs lignes par groupe fonctionnel (par exemple, par “person”) et que vous ne voulez retenir qu’une ou quelques-unes d’entre elles.

La fonction de base slice() accepte des numéros et retourne les lignes dans ces positions. Si les numéros fournis sont positifs, seuls ceux-ci sont retournés. S’ils sont négatifs, ces lignes ne sont pas retournées. Les nombres doivent être soit tous positifs, soit tous négatifs.

obs %>% slice(4)  # retourne la 4e ligne
  recordID personID   name       date  time encounter purpose symptoms_ever
1        3        2 amrish 2020-01-02 14:20         1 contact            No
obs %>% slice(c(2,4))  # retourne les lignes 2 et 4
  recordID personID   name       date  time encounter purpose symptoms_ever
1        1        1   adam 2020-01-01 09:00         1 contact          <NA>
2        3        2 amrish 2020-01-02 14:20         1 contact            No
#obs %>% slice(c(2:4))  # retourne les lignes 2 à 4

Voir données originales.

Il existe plusieurs variations : Celles-ci doivent être fournies avec une colonne et le nombre de lignes à retourner (à n =).

  • slice_min() et slice_max() ne gardent que la ou les lignes avec la ou les valeurs minimales ou maximales de la colonne spécifiée. Cela permet également de retourner le “min” et le “max” de facteurs ordonnés.
  • slice_head() et slice_tail() - Retient que la ou les premières ou dernières lignes.
  • slice_sample() - ne retenir qu’un échantillon aléatoire des lignes.
obs %>% slice_max(encounter, n = 1)  # Retourne les lignes avec le plus grand nombre de "encounter" 
  recordID personID   name       date  time encounter purpose symptoms_ever
1        5        2 amrish 2020-01-05 16:10         3    case           Yes
2       13        3 mariah 2020-01-06 08:32         3 contact            No
3       16        5  brian 2020-01-07 07:59         3    case            No

Utilisez les arguments n = ou prop = pour spécifier le nombre ou la proportion de lignes à retenir. Si vous n’utilisez pas la fonction dans un pipe, fournissez d’abord l’argument data (par exemple, slice(data, n = 2)). Voir ?slice pour plus d’informations.

Autres arguments :

.order_by = utilisé dans slice_min() et slice_max() ceci est une colonne à ordonner par avant de “slice”.
with_ties = TRUE par défaut, ce qui signifie que les liens sont retenus.
.preserve = FALSE par défaut. Si TRUE, alors la structure de regroupement est recalculée après le slicing.
weight_by = Optionnel, colonne numérique pour pondérer par ( un plus grand chiffre est plus probable d’être échantillonné).
Aussi, replace = pour savoir si l’échantillonnage est fait avec/sans remplacement.

TIP: En utilisant slice_max() et slice_min(), assurez-vous de spécifier/d’écrire n = (e.g. n = 2, pas seulement 2). Sinon, vous risquez d’obtenir une erreur: Error:is not empty.

NOTE: Vous pouvez rencontrer la fonction top_n(), qui a été remplacées par les fonctions slice.

Slice avec les groupes

Les fonctions slice_*() peuvent être très utiles si elles sont appliquées à un tableau de données groupées, puisque l’opération de slice est effectuée sur chaque groupe séparément. Utilisez la fonction group_by() en conjonction avec slice() pour regrouper les données et prendre une tranche de chaque groupe.

Ceci est utile pour la déduplication si vous avez plusieurs lignes par personne mais que vous ne voulez retenir qu’une seule d’entre elles. Vous utilisez d’abord group_by() avec des colonnes clés qui sont les mêmes pour chaque personne, puis vous utilisez une fonction slice sur une colonne qui sera différente parmi les lignes groupées.

Dans l’exemple ci-dessous, pour ne garder que la dernière rencontre par personne, nous regroupons les lignes par name et ensuite nous utilisons slice_max() avec n = 1 sur la colonne date. Mais attention ! Pour appliquer une fonction comme slice_max() sur des dates, la colonne date doit être de la classe Date.

Par défaut, les “liens” (par exemple la même date dans ce scénario) sont retenus, et nous aurions toujours plusieurs lignes pour certaines personnes (par exemple adam). Pour éviter cela, nous mettons with_ties = FALSE. Nous ne récupérons qu’une seule ligne par personne.

CAUTION: Si utilisant arrange(), specifier .by_group = TRUE pour que les données soient organisées dans chaque groupe.

DANGER: Si with_ties = FALSE, la première ligne d’une même égalité est conservée. Cela peut être déceptive. Voyez comment pour Mariah, elle a deux rencontres à sa dernière date (6 Jan) et la première (la plus ancienne) a été gardée. Il est probable que nous voulions garder la dernière rencontre de ce jour-là. Voyez comment ” séparer ” ces liens dans l’exemple suivant.

obs %>% 
  group_by(name) %>%       # regroupe les lignes par 'name'
  slice_max(date,          # retenir une ligne par groupe avec la valeur maximale de la date 
            n = 1,         # ne retenir que la ligne la plus élevée 
            with_ties = F) # s'il y a une égalité (de date), prenez le premier ligne

Ci-dessus, par exemple, nous pouvons voir que seule la ligne d’Amrish du 5 janvier a été retenue, et que seule la ligne de Brian du 7 janvier a été retenue. Voir les données originales.

Séparation des égalités

Multiples lignes de slice peuvent être exécutées pour ” séparer les égalités”. Dans ce cas, si une personne a plusieurs rencontres à leur dernière date, la rencontre avec la dernière heure est retenue (lubridate::hm() est utilisé pour convertir les heures des caractères en une classe de temps triable).
Notez comment maintenant, la seule ligne conservée pour “Mariah” le 6 janvier est la rencontre 3 de 08:32, et non la rencontre 2 de 07:25.

# Exemple de multiple lignes de slice exécutées pour " séparer les égalités"
obs %>%
  group_by(name) %>%
  
  # PREMIEREMENT - slice par la dernière date
  slice_max(date, n = 1, with_ties = TRUE) %>% 
  
  # DEUXIÈMEMENT - s'il y a une égalité, sélectionner la ligne avec l'heure la plus tardive ; égalité interdite
  slice_max(lubridate::hm(time), n = 1, with_ties = FALSE)

Dans l’exemple ci-dessus, il aurait également été possible de slice par le numéro de encounter, mais nous avons montré le slice sur date et time pour illustration.

TIP: Pour utiliser slice_max() ou slice_min() sur une colonne e de “caractères”, mutez-la en une classe de facteurs ordonnée !.

Voir données originales.

Retenir tous les lignes mais les marquer

Si vous voulez retenir tous les evenements mais n’en marquer que certains pour l’analyse, envisagez une approche en deux étapes en utilisant un numéro unique de recordID/encounter :

  1. Reduire/slice le tableau de données original pour n’avoir que les lignes à analyser. Sauvegardez/retenir ce tableau de données réduit.
  2. Dans le tableau de données original, marquez les lignes avec case_when(), selon que leur identifiant unique d’enregistrement (recordID dans cet exemple) est présent ou non dans le tableau de données réduit.
# 1. Definir les lignes de tableau de données à retenir pour l'analyse
obs_keep <- obs %>%
  group_by(name) %>%
  slice_max(encounter, n = 1, with_ties = FALSE) # ne garder que la dernière rencontre par personne


# 2. Marquer le tableau de données original
obs_marked <- obs %>%

  # Créer une nouvelle colonne dup_record
  mutate(dup_record = case_when(
    
    # si record est dans le tableau de données obs_keep
    recordID %in% obs_keep$recordID ~ "For analysis", 
    
    #tout le reste est marqué comme "Ignore" pour l'analyse
    TRUE                            ~ "Ignore"))

# imprimer
obs_marked
   recordID personID    name       date  time encounter purpose symptoms_ever
1         1        1    adam 2020-01-01 09:00         1 contact          <NA>
2         1        1    adam 2020-01-01 09:00         1 contact          <NA>
3         2        2  amrish 2020-01-02 14:20         1 contact            No
4         3        2  amrish 2020-01-02 14:20         1 contact            No
5         4        3  mariah 2020-01-05 12:00         1    case            No
6         5        2  amrish 2020-01-05 16:10         3    case           Yes
7         6        4  nikhil 2020-01-05 13:01         1 contact           Yes
8         7        5   brian 2020-01-05 15:20         1 contact            No
9         8        6   smita 2020-01-05 14:20         1 contact           Yes
10        9        7  raquel 2020-01-05 12:30         1 contact          <NA>
11       10        2  amrish 2020-01-02 10:24         2 contact           Yes
12       11        1    adam 2020-01-05 09:40         2    case            No
13       12        3  mariah 2020-01-06 07:25         2 contact            No
14       13        3  mariah 2020-01-06 08:32         3 contact            No
15       14        4  nikhil 2020-01-06 15:36         2 contact           Yes
16       15        5   brian 2020-01-06 15:31         2 contact           Yes
17       16        5   brian 2020-01-07 07:59         3    case            No
18       17        7  raquel 2020-01-07 11:13         2 contact            No
19       18        8 natalie 2020-01-07 17:12         1    case            No
     dup_record
1        Ignore
2        Ignore
3        Ignore
4        Ignore
5        Ignore
6  For analysis
7        Ignore
8        Ignore
9  For analysis
10       Ignore
11       Ignore
12 For analysis
13       Ignore
14 For analysis
15 For analysis
16       Ignore
17 For analysis
18 For analysis
19 For analysis

Voir données originales.

Calcul de la complétude des lignes

Créez une colonne qui contient une métrique pour la complétude des lignes (pas de valeurs manquantes). Cela peut être utile pour décider des lignes à prioriser par rapport aux autres lors de la déduplication.

Dans cet exemple, les colonnes “clés” sur lesquelles vous voulez mesurer la complétude sont sauvegardées dans un vecteur de noms de colonnes.

Ensuite, la nouvelle colonne key_completeness est créée avec mutate(). La nouvelle valeur dans chaque ligne est définie comme une fraction calculée : le nombre de valeurs non manquantes dans cette ligne parmi les colonnes clés, divisé par le nombre de colonnes clés.

Cela fait appel à la fonction rowSums() de base R. On utilise également ., qui, dans le cadre d’un pipe, fait référence au tableau de données à ce point du pipe (dans ce cas, il est sous-ensemble avec les crochets []).

Défiler vers la droite pour voir plus de lignes.

# créer une colonne "complétude des variables clés".
# il s'agit de la *proportion* des colonnes désignées comme "key_cols" qui ont des valeurs non manquantes.

key_cols = c("personID", "name", "symptoms_ever")

obs %>% 
  mutate(key_completeness = rowSums(!is.na(.[,key_cols]))/length(key_cols)) 

Voir données originales.

15.4 Réunir les valeurs de plusieurs lignes

Cette section décrit :

  1. Comment “réunir” les valeurs de plusieurs lignes en une seule ligne, avec quelques variations.
  2. Une fois les valeurs sont “réunit”, comment remplacer/prioriser les valeurs dans chaque cellule.

Cet onglet utilise le jeu de données d’exemple de l’onglet Préparation.

Réunir les valeurs en une seule ligne

L’exemple de code ci-dessous utilise group_by() et summarise() pour regrouper les lignes par personne, puis rassembler toutes les valeurs uniques dans les lignes groupées. Ainsi, vous obtenez un résumé de ligne par personne. Quelques notes :
* Un suffixe est ajouté à toutes les nouvelles colonnes (“_roll” dans cet exemple).
* Si vous ne voulez afficher que les valeurs uniques par cellule, enveloppez le na.omit() avec unique().
* na.omit() supprime les valeurs NA, mais si cela n’est pas souhaité, il peut être supprimé paste0(.x)

# Réunir les valeurs en une seule ligne par groupe (par "personID") 
cases_rolled <- obs %>% 
  
  # créer des groupes par nom
  group_by(personID) %>% 
  
  # ordonner les lignes à l'intérieur de chaque groupe (par exemple par date)
  arrange(date, .by_group = TRUE) %>% 
  
  # Pour chaque colonne, rassemblez toutes les valeurs des lignes groupées, en les séparant par " ;".
  summarise(
    across(everything(),                           # appliquer à toutes les colonnes
           ~paste0(na.omit(.x), collapse = "; "))) # on définit une fonction qui combine les valeurs non-NA 

Le résultat est une ligne par groupe (ID), avec des entrées classées par date et assemblées. Défiler vers la gauche pour voir plus de lignes

Voir données originales.

Cette variation ne présente que des valeurs uniques:

# Cette variation ne présente que des valeurs uniques 
cases_rolled <- obs %>% 
  group_by(personID) %>% 
  arrange(date, .by_group = TRUE) %>% 
  summarise(
    across(everything(),                                   # appliquer à toutes les colonnes
           ~paste0(unique(na.omit(.x)), collapse = "; "))) # on définit une fonction qui combine les valeurs non-NA 

Cette variation ajoute un suffixe à chaque colonne.
Dans ce cas, “_roll” pour signifier qu’elle a été roulée :

# Cette variation ajoute un suffixe à chaque colonne
cases_rolled <- obs %>% 
  group_by(personID) %>% 
  arrange(date, .by_group = TRUE) %>% 
  summarise(
    across(everything(),                
           list(roll = ~paste0(na.omit(.x), collapse = "; ")))) # _roll est ajouté aux noms des colonnes

Remplacer les valeurs/hiérarchie

Si vous voulez ensuite évaluer toutes les valeurs reunit, et ne garder qu’une valeur spécifique (par exemple la “meilleure” ou la “valeur maximale”), vous pouvez utiliser mutate() sur les colonnes souhaitées, pour implémenter case_when(), qui utilise str_detect() du package stringr pour rechercher séquentiellement des séquences de caractères et remplacer le contenu de la cellule.

# CLEAN CASES
#############
cases_clean <- cases_rolled %>% 
    
    # nettoie les variables Yes-No-Unknown : remplace le texte par la valeur "la plus élevée" présente dans la séquence des caracteres
    mutate(across(c(contains("symptoms_ever")),                     # fonctionne sur les colonnes spécifiées (Y/N/U)
             list(mod = ~case_when(                                 # ajoute le suffixe "_mod" aux nouvelles cols ; implémente case_when() 
               
               str_detect(.x, "Yes")       ~ "Yes",                 # si "Yes" est détecté, alors la valeur de la cellule est convertie en Yes
               str_detect(.x, "No")        ~ "No",                  # # alors, si "No" est détecté, la valeur de la cellule est convertie en No
               str_detect(.x, "Unknown")   ~ "Unknown",             # alors, si "Unknown" est détecté, la valeur de la cellule est convertie en Unknown 
               TRUE                        ~ as.character(.x)))),   # alors, si quelque chose d'autre est retenu comme tel
      .keep = "unused")                                             # anciennes colonnes enlevées, ne laissant que des colonnes _mod

Maintenant vous pouvez voir dans la colonne symptoms_ever que si la personne a JAMAIS dit “Oui” aux symptômes, alors seul “Oui” est affiché.

Voir données originales.

15.5 Déduplication probabiliste

Parfois, vous souhaitez identifier les doublons “probables” en vous basant sur la similarité (par exemple, la sequence des caractères “distance”) entre plusieurs colonnes telles que le nom, l’âge, le sexe, la date de naissance, etc. Vous pouvez appliquer un algorithme de correspondance probabiliste pour identifier les doublons probables.

Voir la page Joindre des données pour une explication de cette méthode. La section sur l’Appariement Probabiliste contient un exemple d’application de ces algorithmes pour comparer un tableau de données à soi-même, effectuant ainsi une déduplication probabiliste.

15.6 Ressources

La plupart des informations contenues dans cette page sont adaptées de ces ressources et des vignettes en ligne :

datanovia

dplyr tidyverse reference

cran janitor vignette