Comment remplacer les valeurs manquantes (NA) dans R : na.omit et na.rm
โก Rรฉsumรฉ intelligent
Ce tutoriel sur le remplacement des valeurs manquantes dans R explique comment dรฉtecter les valeurs NA, supprimer les lignes incomplรจtes avec `na.omit()` et les imputer avec la moyenne ou la mรฉdiane grรขce ร `mutate()`. Il utilise le jeu de donnรฉes Titanic, oรน les variables `age` et `fare` comportent des valeurs manquantes.

Que sont les valeurs manquantes en R ?
Les valeurs manquantes apparaissent lorsqu'aucune valeur n'est enregistrรฉe dans une colonne pour une observation donnรฉe, ou lorsqu'une valeur non numรฉrique remplace un nombre. Elles doivent รชtre supprimรฉes ou remplacรฉes avant tout calcul, car la plupart des fonctions R renvoient NA dรจs qu'une valeur manquante est prรฉsente.
Ce tutoriel explique comment gรฉrer les valeurs manquantes avec la bibliothรจque dplyr, qui fait partie de l'รฉcosystรจme tidyverse pour l'analyse de donnรฉes.
La premiรจre รฉtape consiste toujours ร dรฉterminer combien de valeurs sont manquantes et oรน.
Comment dรฉtecter et compter les valeurs manquantes en R
Avant de dรฉcider comment traiter les valeurs manquantes, il est nรฉcessaire de connaรฎtre leur nombre et leur emplacement. R propose quatre mรฉthodes de vรฉrification, allant d'une simple rรฉponse par oui ou par non ร un dรฉcompte complet par colonne.
# 1. Is there any NA at all? anyNA(df_titanic) # 2. How many in total? sum(is.na(df_titanic)) # 3. How many per column, the most useful view colSums(is.na(df_titanic)) # 4. Percentage missing per column round(colMeans(is.na(df_titanic)) * 100, 1)
En pratique, c'est la fonction `colSums()` qu'il faut privilรฉgier. Elle renvoie un vecteur nommรฉ avec un comptage par colonne, ce qui permet de voir immรฉdiatement si une variable comporte quelques valeurs manquantes ou si elle est presque vide.
Comptage des lignes complรจtes. La fonction `complete.cases()` renvoie `TRUE` pour les lignes ne contenant aucune valeur manquante, ce qui vous indique ร l'avance la quantitรฉ de donnรฉes que `na.omit()` supprimerait :
sum(complete.cases(df_titanic)) # rows that would survive sum(!complete.cases(df_titanic)) # rows that would be dropped
Avertissement concernant les espaces rรฉservรฉs. R ne reconnaรฎt que les valeurs manquantes (NA). Les jeux de donnรฉes encodent frรฉquemment les valeurs manquantes sous forme de chaรฎne vide, d'espace, de ยซ N/A ยป, de tiret (ยซ - ยป) ou d'un nombre sentinelle tel que -99 ou 999. Ces valeurs passent inaperรงues lors des vรฉrifications prรฉcรฉdentes. Il est donc nรฉcessaire de les convertir lors de l'importation afin d'assurer le bon fonctionnement du reste du flux de travail.
df <- read.csv(PATH, na.strings = c("", " ", "NA", "N/A", "-", "-99"))
Aprรจs l'importation, vรฉrifiez toujours la plage de valeurs de chaque colonne numรฉrique. Une valeur d'รขge de -99 ou un tarif de 9999 sont bien plus problรฉmatiques qu'une valeur NA lรฉgitime, car aucune fonction ne vous avertira.
Types de donnรฉes manquantes : MCAR, MAR et MNAR
La raison pour laquelle une valeur est manquante dรฉtermine si son imputation est sans risque. Les statisticiens identifient trois mรฉcanismes.
- MCAR, manquant de maniรจre totalement alรฉatoire. La probabilitรฉ de disparition est indรฉpendante de tout facteur, observรฉ ou non, par exemple un capteur qui tombe en panne de faรงon alรฉatoire.ping ou l'imputation de ces lignes n'introduit aucun biais, seulement une perte de prรฉcision.
- MAR, manquant au hasard. La probabilitรฉ dรฉpend d'autres variables observรฉes, mais pas de la valeur manquante elle-mรชme. Si l'รขge des passagers plus รขgรฉs รฉtait moins susceptible d'รชtre enregistrรฉ, l'รขge est considรฉrรฉ comme MAR (moyenne aberrante) compte tenu des autres colonnes. L'imputation utilisant ces colonnes permet de gรฉrer efficacement ce cas.
- MNAR, manquant non alรฉatoirement. La probabilitรฉ dรฉpend de la valeur non observรฉe elle-mรชme ; par exemple, les personnes ร hauts revenus peuvent refuser de dรฉclarer leurs revenus. Aucune mรฉthode dโimputation ne peut corriger ce problรจme ร partir des seules donnรฉes, et lโabsence de donnรฉes recรจle des informations quโil est pertinent dโenregistrer dans une colonne dโindicateur.
L'imputation par la moyenne, telle qu'utilisรฉe dans ce tutoriel, n'est acceptable que dans le cas d'une imputation MCAR (MCAR) et d'une imputation MAR (Marginal Added Rate) simple. Mรชme dans ces cas, elle prรฉsente un inconvรฉnient majeur : remplacer chaque valeur manquante par la mรชme valeur rรฉduit la variance de la colonne et affaiblit sa corrรฉlation avec toutes les autres. Pour des applications plus rigoureuses, il est recommandรฉ d'utiliser une mรฉthode basรฉe sur un modรจle, comme celle proposรฉe par le package mice, et de toujours conserver une colonne d'indicateurs signalant les valeurs imputรฉes.
subir une mutation()
mutate() est le dรฉplyr verbe qui crรฉe une nouvelle variable ou รฉcrase une variable existante, ce qui en fait l'outil naturel pour construire une copie propre d'une colonne.
Nous procรฉderons en deux parties. Nous apprendrons comment :
- exclure les valeurs manquantes d'un bloc de donnรฉes
- imputer les valeurs manquantes avec la moyenne et la mรฉdiane
Le verbe mutate() est trรจs simple ร utiliser. Nous pouvons crรฉer une nouvelle variable en suivant cette syntaxe :
mutate(df, name_variable_1 = condition, ...) arguments: -df: Data frame used to create a new variable -name_variable_1: Name and the formula to create the new variable -...: No limit constraint. Possibility to create more than one variable inside mutate()
Exclure les valeurs manquantes (NA)
La fonction `na.omit()` est une fonction de base de R, et non une fonction de dplyr, mais elle s'utilise tout aussi bien. Elle supprime toutes les lignes contenant au moins une valeur manquante (NA). C'est l'option la plus rapide, mais rarement la meilleure, car une seule valeur manquante suffit ร invalider l'observation entiรจre.
Pour rรฉsoudre le problรจme des observations manquantes, nous utiliserons lโensemble de donnรฉes titanesque. Dans cet ensemble de donnรฉes, nous avons accรจs aux informations des passagers ร bord lors du drame. Cet ensemble de donnรฉes contient de nombreuses NA qui doivent รชtre prises en compte.
Chargez le fichier CSV depuis Internet, puis listez les colonnes contenant des valeurs NA :
PATH <- "https://raw.githubusercontent.com/guru99-edu/R-Programming/master/test.csv" df_titanic <- read.csv(PATH, sep = ",") # Return the column names containing missing observations list_na <- colnames(df_titanic)[ apply(df_titanic, 2, anyNA) ] list_na
Sortie :
## [1] "age" "fare"
Ici,
colnames(df_titanic)[apply(df_titanic, 2, anyNA)]
renvoie les noms des colonnes contenant au moins une valeur manquante.
Les colonnes รขge et tarif comportent des valeurs manquantes.
Nous pouvons les supprimer avec na.omit().
library(dplyr) # Exclude the missing observations df_titanic_drop <-df_titanic %>% na.omit() dim(df_titanic_drop)
Sortie :
## [1] 1045 13
Le nouvel ensemble de donnรฉes contient 1045 1309 lignes, contre pour lโensemble de donnรฉes dโorigine.
Imputer les donnรฉes manquantes avec la moyenne et la mรฉdiane
Il est รฉgalement possible d'imputer, c'est-ร -dire de remplacer les valeurs manquantes par la moyenne ou la mรฉdiane. Il est recommandรฉ de crรฉer deux variables distinctes pour la moyenne et la mรฉdiane. Une fois ces variables crรฉรฉes, on peut remplacer les valeurs manquantes par celles-ci.
Nous utiliserons la mรฉthode apply pour calculer la moyenne de la colonne avec NA. Voyons un exemple
รtape 1) Plus tรดt dans le didacticiel, nous avons stockรฉ le nom des colonnes avec les valeurs manquantes dans la liste appelรฉe list_na. Nous utiliserons cette liste
รtape 2) Calculez la moyenne avec l'argument na.rm = TRUE. Cet argument est obligatoire car les colonnes contiennent des donnรฉes manquantes ; il indique ร R de les ignorer.
# Create mean average_missing <- apply(df_titanic[,colnames(df_titanic) %in% list_na], 2, mean, na.rm = TRUE) average_missing
Code Explication:
Nous passons 4 arguments dans la mรฉthode apply.
- df : df_titanic[,colnames(df_titanic) %in% list_na]. Ce code renverra le nom des colonnes de l'objet list_na (c'est-ร -dire ยซ รขge ยป et ยซ tarif ยป)
- 2 : Calculer la fonction sur les colonnes
- moyenne : Calculer la moyenne
- na.rm = TRUE : ignorer les valeurs manquantes
Sortie :
## age fare ## 29.88113 33.29548
Nous avons rรฉussi ร crรฉer la moyenne des colonnes contenant les observations manquantes. Ces deux valeurs serviront ร remplacer les observations manquantes.
รtape 3) Remplacer les valeurs NA
Le verbe muter de la bibliothรจque dplyr est utile pour crรฉer une nouvelle variable. Nous ne voulons pas nรฉcessairement changer la colonne d'origine pour pouvoir crรฉer une nouvelle variable sans le NA. mutate est facile ร utiliser, il suffit de choisir un nom de variable et de dรฉfinir comment crรฉer cette variable. Voici le code complet
# Create a new variable with the mean and median df_titanic_replace <- df_titanic %>% mutate(replace_mean_age = ifelse(is.na(age), average_missing[1], age), replace_mean_fare = ifelse(is.na(fare), average_missing[2], fare))
Code Explication:
Nous crรฉons deux variables, replace_mean_age et replace_mean_fare comme suit :
- replace_mean_age = ifelse(is.na(age), Average_missing[1], age)
- replace_mean_fare = ifelse(is.na(tarif), Average_missing[2],tarif)
Si la colonne age a des valeurs manquantes, remplacez-la par le premier รฉlรฉment de Average_missing (moyenne de l'รขge), sinon conservez les valeurs d'origine. Mรชme logique pour le tarif
sum(is.na(df_titanic_replace$age))
Sortie :
## [1] 263
Aprรจs le remplacement, la nouvelle colonne ne contient plus aucune valeur manquante :
sum(is.na(df_titanic_replace$replace_mean_age))
Sortie :
## [1] 0
La colonne d'รขge d'origine contient 263 valeurs manquantes, tandis que la nouvelle colonne replace_mean_age les a toutes remplies avec l'รขge moyen.
รtape 4) Nous pouvons รฉgalement remplacer les observations manquantes par la mรฉdiane.
median_missing <- apply(df_titanic[,colnames(df_titanic) %in% list_na], 2, median, na.rm = TRUE) df_titanic_replace <- df_titanic %>% mutate(replace_median_age = ifelse(is.na(age), median_missing[1], age), replace_median_fare = ifelse(is.na(fare), median_missing[2], fare)) head(df_titanic_replace)
Sortie :
รtape 5) Sur un vaste ensemble de donnรฉes, la mรฉthode pas ร pas devient fastidieuse. La fonction `sapply()` condense toute la procรฉdure en une seule instruction, au prix de ne jamais visualiser les valeurs imputรฉes.
sapply ne crรฉe pas de trame de donnรฉes, nous pouvons donc envelopper la fonction sapply() dans data.frame() pour crรฉer un objet de bloc de donnรฉes.
# Quick code to replace missing values with the mean df_titanic_impute_mean <- data.frame( sapply( df_titanic, function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x)))
Imputation moderne avec replace_na() et across()
Les approches apply() et sapply() ci-dessus fonctionnent toujours, mais tidyr et dplyr expriment dรฉsormais les mรชmes opรฉrations de maniรจre plus sรปre et plus lisible.
replace_na() pour les valeurs fixes. tidyr::replace_na() prend une liste nommรฉe de colonnes et leurs remplacements :
library(tidyr) df_titanic %>% replace_na(list(age = 29.88, fare = 33.30))
Pour chaque colonne numรฉrique, utilisez la fonction across(). Il s'agit du remplacement direct et sรปr en termes de types pour la fonction sapply() en une seule ligne, et contrairement ร sapply(), elle ne touche jamais aux colonnes de caractรจres ou de facteurs :
library(dplyr) # Mean-impute every numeric column df_titanic %>% mutate(across(where(is.numeric), ~ ifelse(is.na(.x), mean(.x, na.rm = TRUE), .x))) # Median-impute instead df_titanic %>% mutate(across(where(is.numeric), ~ ifelse(is.na(.x), median(.x, na.rm = TRUE), .x)))
โ ๏ธ Pourquoi le raccourci sapply() est risquรฉ : l'exemple sapply() en une seule ligne s'exรฉcute sur chaque La colonne, y compris les colonnes de type caractรจre et facteur, est affectรฉe par la fonction mean() qui renvoie NA avec un avertissement. La fonction sapply() convertit ensuite l'ensemble du rรฉsultat en caractรจre. La version across(where(is.numeric), โฆ) prรฉsentรฉe ci-dessus รฉvite complรจtement ce problรจme.
coalesce() pour les colonnes de repli. Lorsqu'une deuxiรจme colonne peut fournir la valeur manquante, coalesce() renvoie la premiรจre entrรฉe non manquante parmi ses arguments :
df %>% mutate(age_final = coalesce(age, age_estimated, 0))
Notez ce que vous avez modifiรฉ. Ajoutez un indicateur avant l'imputation, afin que tout modรจle ultรฉrieur puisse tirer des enseignements du fait qu'une valeur รฉtait manquante :
df_titanic %>%
mutate(age_was_missing = is.na(age),
age = ifelse(is.na(age), mean(age, na.rm = TRUE), age))
Gestion des valeurs manquantes en R : Rรฉfรฉrence de la mรฉthode
Ce tutoriel aborde trois approches :
- Exclure toutes les observations manquantes
- Imputer avec la moyenne
- Imputer avec la mรฉdiane
Le tableau ci-dessous rรฉcapitule la dรฉtection et la suppression :
| Bibliothรจque | Objectif | Code |
|---|---|---|
| base | Liste des observations manquantes |
colnames(df)[apply(df, 2, anyNA)] |
| base | Supprimez toutes les lignes contenant NA. |
na.omit(df) |
L'imputation avec moyenne ou mรฉdiane peut รชtre effectuรฉe de deux maniรจres
- Utiliser Appliquer
- Utiliser sapply
| Mรฉthode | DรTAILS | Avantages | Dรฉsavantages |
|---|---|---|---|
| รtape par รฉtape avec postuler | Vรฉrifiez les colonnes manquantes, calculez la moyenne/mรฉdiane, stockez la valeur, remplacez par mutate() | Vous pouvez voir la moyenne ou la mรฉdiane imputรฉe | Plus de temps d'exรฉcution. Peut รชtre lent avec un grand ensemble de donnรฉes |
| Mรฉthode rapide avec sapply | Utilisez sapply() et data.frame() pour rechercher et remplacer automatiquement les valeurs manquantes par la moyenne/mรฉdiane | Code court et rapide | Les valeurs imputรฉes ne sont jamais affichรฉes. |



