J'ai un bloc de données et certaines colonnes ont des NA
valeurs.
Comment remplacer ces NA
valeurs par des zéros?
r
dataframe
na
missing-data
imputation
Renato Dinhani
la source
la source
Réponses:
Voir mon commentaire dans la réponse @ gsk3. Un exemple simple:
Il n'est pas nécessaire de postuler
apply
. =)ÉDITER
Vous devriez également jeter un œil au
norm
package. Il a beaucoup de fonctionnalités intéressantes pour l'analyse des données manquantes. =)la source
df[19:28][is.na(df[19:28])] <- 0
Les options hybrides dplyr sont désormais environ 30% plus rapides que le sous-ensemble Base R réaffecté. Sur un point de données de 100 M, la trame de données
mutate_all(~replace(., is.na(.), 0))
s'exécute une demi-seconde plus rapidement que l'd[is.na(d)] <- 0
option R de base . Ce que l'on veut éviter spécifiquement, c'est utiliser unifelse()
ou unif_else()
. (L'analyse complète de 600 essais a duré plus de 4,5 heures, principalement en raison de l'inclusion de ces approches.) Veuillez consulter les analyses de référence ci-dessous pour les résultats complets.Si vous rencontrez des difficultés avec des trames de données massives,
data.table
c'est l'option la plus rapide de toutes: 40% plus rapide que l' approche Base R standard . Il modifie également les données en place, ce qui vous permet de travailler avec presque deux fois plus de données à la fois.Un regroupement d'autres approches de remplacement bidirectionnelles utiles
Localisation:
mutate_at(c(5:10), ~replace(., is.na(.), 0))
mutate_at(vars(var5:var10), ~replace(., is.na(.), 0))
mutate_at(vars(contains("1")), ~replace(., is.na(.), 0))
contains()
, essayezends_with()
,starts_with()
mutate_at(vars(matches("\\d{2}")), ~replace(., is.na(.), 0))
Conditionnellement:
(changez juste un seul type et laissez les autres types seuls.)
mutate_if(is.integer, ~replace(., is.na(.), 0))
mutate_if(is.numeric, ~replace(., is.na(.), 0))
mutate_if(is.character, ~replace(., is.na(.), 0))
L'analyse complète -
Mise à jour pour dplyr 0.8.0: les fonctions utilisent des
~
symboles au format purrr : remplacement desfuns()
arguments obsolètes .Approches testées:
Le code de cette analyse:
Résumé des résultats
Boxplot of Results
Diagramme de dispersion des essais à code couleur (avec axe y sur une échelle logarithmique)
Une note sur les autres performants
Lorsque les ensembles de données deviennent plus grands, Tidyr 's
replace_na
s'était historiquement retiré devant. Avec la collection actuelle de 100 millions de points de données à parcourir, il fonctionne presque exactement ainsi qu'une base R pour boucle. Je suis curieux de voir ce qui se passe pour les trames de données de différentes tailles.Des exemples supplémentaires pour les variantes de fonction
mutate
etsummarize
_at
et_all
peuvent être trouvés ici: https://rdrr.io/cran/dplyr/man/summarise_all.html De plus, j'ai trouvé des démonstrations utiles et des collections d'exemples ici: https: //blog.exploratory. io / dplyr-0-5-is-awesome-heres-why-be095fd4eb8aAttributions et appréciations
Un merci spécial à:
local()
(et avec l'aide du patient de Frank aussi) le rôle de la coercition silencieuse dans l'accélération de bon nombre de ces approches.coalesce()
fonction et de mettre à jour l'analyse.data.table
fonctions assez bien pour enfin les inclure dans la programmation.is.numeric()
qui teste vraiment.(Bien sûr, veuillez nous contacter et leur donner également des votes positifs si vous trouvez ces approches utiles.)
Remarque sur mon utilisation de Numerics: Si vous disposez d'un ensemble de données purement entier, toutes vos fonctions s'exécuteront plus rapidement. Veuillez consulter le travail de alexiz_laz pour plus d'informations. IRL, je ne me souviens pas avoir rencontré un ensemble de données contenant plus de 10 à 15% d'entiers, donc j'exécute ces tests sur des trames de données entièrement numériques.
Matériel utilisé 3,9 GHz CPU avec 24 Go de RAM
la source
df1[j][is.na(df1[j])] = 0
c'est faux, devrait l'êtredf1[[j]][is.na(df1[[j]])] = 0
forLp_Sbst
cela ne semble pas être un moyen pour quiconque d'envisager de l'approcher vsforLp_smplfSbst
coalesce()
option et réexécuté tout le temps. Merci pour le coup de pouce à mettre à jour.Pour un seul vecteur:
Pour un data.frame, créez une fonction à partir de ce qui précède, puis ajoutez-
apply
la aux colonnes.Veuillez fournir un exemple reproductible la prochaine fois comme détaillé ici:
Comment faire un excellent exemple reproductible R?
la source
is.na
est une fonction générique et possède des méthodes pour les objets dedata.frame
classe. donc celui-ci fonctionnera également surdata.frame
s!methods(is.na)
pour la première fois, j'étais comme whaaa?!? . J'adore quand des trucs comme ça arrivent! =)exemple dplyr:
Note: Cela fonctionne par colonne sélectionnée, si nous devons le faire pour toutes les colonnes, voir @reidjax réponse de l' utilisation mutate_each .
la source
Si nous essayons de remplacer
NA
s lors de l'exportation, par exemple lors de l'écriture vers csv, nous pouvons utiliser:la source
Je sais que la question est déjà répondue, mais le faire de cette façon pourrait être plus utile pour certains:
Définissez cette fonction:
Maintenant, chaque fois que vous avez besoin de convertir les NA d'un vecteur en zéro, vous pouvez le faire:
la source
Avec
dplyr
0.5.0, vous pouvez utiliser unecoalesce
fonction qui peut être facilement intégrée dans le%>%
pipeline en faisantcoalesce(vec, 0)
. Cela remplace toutes les NAvec
avec 0:Disons que nous avons une trame de données avec
NA
s:la source
Une approche plus générale de l' utilisation
replace()
dans la matrice ou d'un vecteur pour remplacerNA
à0
Par exemple:
C'est aussi une alternative à l'utilisation
ifelse()
dansdplyr
la source
levels(A$x) <- append(levels(A$x), "notAnswered") A$x <- replace(A$x,which(is.na(A$x)),"notAnswered")
which
n'est pas nécessaire ici, vous pouvez utiliserx1 <- replace(x,is.na(x),1)
.NA
à0
en une seule colonne spécifique dans une grande trame de données et cette fonction areplace()
travaillé le plus efficacement tout aussi le plus simplement.Il est également possible d'utiliser
tidyr::replace_na
.la source
Un autre exemple utilisant le paquet imputeTS :
la source
Si vous souhaitez remplacer les NA dans les variables de facteur, cela peut être utile:
Il transforme un facteur-vecteur en vecteur numérique et ajoute un autre niveau de facteur numérique artificiel, qui est ensuite retransformé en un vecteur-facteur avec un "niveau NA" supplémentaire de votre choix.
la source
Aurait commenté le post de @ ianmunoz mais je n'ai pas assez de réputation. Vous pouvez combiner
dplyr
« smutate_each
etreplace
de prendre soin deNA
de0
remplacement. Utilisation de la trame de données de la réponse de @ aL3xa ...Nous utilisons l'évaluation standard (SE) ici, c'est pourquoi nous avons besoin du trait de soulignement sur "
funs_
." Nous utilisons égalementlazyeval
'sinterp
/~
et les.
références "tout ce avec quoi nous travaillons", c'est-à-dire la trame de données. Maintenant, il y a des zéros!la source
Vous pouvez utiliser
replace()
Par exemple:
la source
NA
s dans votre vecteur. C'est bien pour les petits vecteurs comme dans votre exemple.x1 <- replace(x,is.na(x),1)
fonctionnera sans lister explicitement les valeurs d'index.Une autre
dplyr
option compatible avec les tuyaux avec unetidyr
méthodereplace_na
qui fonctionne pour plusieurs colonnes:Vous pouvez facilement limiter par exemple aux colonnes numériques:
la source
La fonction dédiée (
nafill
/setnafill
) à cet effet est dans ladata.table
version récentela source
Cette simple fonction extraite de Datacamp pourrait aider:
alors
la source
Un moyen simple de l'écrire est
if_na
dehablar
:qui renvoie:
la source
Pour remplacer toutes les AN dans une trame de données, vous pouvez utiliser:
df %>% replace(is.na(.), 0)
la source
si vous souhaitez attribuer un nouveau nom après avoir modifié les NA dans une colonne spécifique dans ce cas, la colonne V3, utilisez vous pouvez également faire comme ceci
la source