187 votes

Remplacer toutes les valeurs 0 par NA

J'ai un cadre de données avec quelques colonnes numériques. Certaines lignes ont une valeur de 0 qui doit être considérée comme nulle dans l'analyse statistique. Quel est le moyen le plus rapide de remplacer toutes les valeurs 0 par NULL dans R ?

312voto

Julius Points 9748

Remplacer tous les zéros par NA :

df[df == 0] <- NA

Explication

1. Ce n'est pas NULL ce par quoi vous voulez remplacer les zéros. Comme il est dit dans ?'NULL' ,

NULL représente l'objet nul dans R

qui est unique et, je suppose, peut être considéré comme l'objet le moins informatif et le plus vide. 1 Il n'est donc pas si surprenant que

data.frame(x = c(1, NULL, 2))
#   x
# 1 1
# 2 2

C'est-à-dire que R ne réserve aucun espace pour cet objet nul. 2 Pendant ce temps, en regardant ?'NA' nous voyons que

NA est une constante logique de longueur 1 qui contient une valeur manquante manquante. NA peut être converti en tout autre type de vecteur, à l'exception de raw.

C'est important, NA est de longueur 1 afin que R lui réserve un espace. Par exemple,

data.frame(x = c(1, NA, 2))
#    x
# 1  1
# 2 NA
# 3  2

De plus, la structure du cadre de données exige que toutes les colonnes aient le même nombre d'éléments afin qu'il n'y ait pas de "trous" (c'est-à-dire, NULL ).

Maintenant, vous pouvez remplacer les zéros par NULL dans un cadre de données au sens où l'on supprime complètement toutes les lignes contenant au moins un zéro. Lors de l'utilisation, par exemple, de var , cov ou cor ce qui équivaut en fait à remplacer d'abord les zéros par NA et en fixant la valeur de use comme "complete.obs" . Toutefois, cette méthode n'est généralement pas satisfaisante car elle entraîne une perte d'information supplémentaire.

2. Au lieu de faire tourner une sorte de boucle, dans la solution, j'utilise df == 0 vectorisation. df == 0 renvoie (essayez-le) une matrice de la même taille que df avec les entrées TRUE et FALSE . De plus, nous sommes également autorisés à passer cette matrice au sous-ensemble [...] (ver ?'[' ). Enfin, si le résultat de df[df == 0] est parfaitement intuitif, il peut sembler étrange que df[df == 0] <- NA donne l'effet désiré. L'opérateur d'affectation <- n'est en effet pas toujours aussi intelligent et ne fonctionne pas de cette manière avec certains autres objets, mais il le fait avec les trames de données ; cf. ?'<-' .

<sup>1 </sup>L'ensemble vide dans la théorie des ensembles est en quelque sorte lié.
<sup>2 </sup>Autre similitude avec la théorie des ensembles : l'ensemble vide est un sous-ensemble de tout ensemble, mais nous ne lui réservons aucun espace.

48voto

user56 Points 659

Je suppose que votre data.frame est un mélange de différents types de données et que toutes les colonnes n'ont pas besoin d'être modifiées.

pour modifier uniquement les colonnes 12 à 18 (sur un total de 21), il suffit de procéder comme suit

df[, 12:18][df[, 12:18] == 0] <- NA

39voto

sbha Points 1948

dplyr::na_if() est une option :

library(dplyr)  

df <- data_frame(col1 = c(1, 2, 3, 0),
                 col2 = c(0, 2, 3, 4),
                 col3 = c(1, 0, 3, 0),
                 col4 = c('a', 'b', 'c', 'd'))

na_if(df, 0)
# A tibble: 4 x 4
   col1  col2  col3 col4 
  <dbl> <dbl> <dbl> <chr>
1     1    NA     1 a    
2     2     2    NA b    
3     3     3     3 c    
4    NA     4    NA d

23voto

Sven Hohenstein Points 36055

Une autre façon de procéder sans le [<- fonction :

Un exemple de base de données dat (copié sans vergogne de la réponse de @Chase) :

dat

  x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0

Les zéros peuvent être remplacés par NA par le is.na<- fonction :

is.na(dat) <- !dat

dat

   x  y
1 NA  2
2  1  2
3  1  1
4  2  1
5 NA NA

14voto

Chase Points 27342
#Sample data
set.seed(1)
dat <- data.frame(x = sample(0:2, 5, TRUE), y = sample(0:2, 5, TRUE))
#-----
  x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0

#replace zeros with NA
dat[dat==0] <- NA
#-----
   x  y
1 NA  2
2  1  2
3  1  1
4  2  1
5 NA NA

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X