Remplacer toutes les valeurs 0 par NA

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

Remplacer tous les zéros par NA:

df[df == 0] <- NA 

Explication

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

NULL représente l'object null dans R

ce qui est unique et, je suppose, peut être considéré comme l’object le moins informatif et le plus vide. 1 Alors ça devient 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 object nul. 2 Pendant ce temps, en regardant ?'NA' nous voyons que

NA est une constante logique de longueur 1 qui contient un indicateur de valeur manquante. NA peut être contraint à tout autre type de vecteur, sauf le brut.

Il est important de noter que NA est de longueur 1, de sorte que R réserve de la place pour cela. Par exemple,

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

En outre, la structure du bloc de données nécessite que toutes les colonnes aient le même nombre d'éléments, de sorte qu'il ne puisse y avoir de "trous" (c'est-à-dire des valeurs NULL ).

Vous pouvez maintenant remplacer les zéros par NULL dans un NULL de données dans le sens d'une suppression complète de toutes les lignes contenant au moins un zéro. Lorsque vous utilisez, par exemple, var , cov ou cor , cela revient en fait à remplacer d'abord les zéros par NA et à définir la valeur use comme "complete.obs" . En règle générale, cependant, cela n'est pas satisfaisant car cela entraîne une perte d'informations supplémentaire.

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

1 L'ensemble vide dans la théorie des ensembles est en quelque sorte lié.
2 Une autre similitude avec la théorie des ensembles: l'ensemble vide est un sous-ensemble de chaque ensemble, mais nous ne réservons aucun espace pour celui-ci.

Supposons que votre data.frame soit un mélange de différents types de données et que toutes les colonnes ne doivent pas être modifiées.

pour ne modifier que les colonnes 12 à 18 (sur un total de 21), il suffit de le faire

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

Une alternative sans la fonction [<- :

Un exemple de firebase database (copié sans vergogne de la réponse de @ Chase):

 dat xy 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 la fonction is.na<- :

 is.na(dat) <- !dat dat xy 1 NA 2 2 1 2 3 1 1 4 2 1 5 NA NA 
 #Sample data set.seed(1) dat <- data.frame(x = sample(0:2, 5, TRUE), y = sample(0:2, 5, TRUE)) #----- xy 1 0 2 2 1 2 3 1 1 4 2 1 5 0 0 #replace zeros with NA dat[dat==0] <- NA #----- xy 1 NA 2 2 1 2 3 1 1 4 2 1 5 NA NA 

Parce que quelqu’un a demandé la version de Data.Table et que la solution donnée data.frame ne fonctionne pas avec data.table, je fournis la solution ci-dessous.

Fondamentalement, utilisez l’opérateur :=DT[x == 0, x := NA]

 library("data.table") status = as.data.table(occupationalStatus) head(status, 10) origin destination N 1: 1 1 50 2: 2 1 16 3: 3 1 12 4: 4 1 11 5: 5 1 2 6: 6 1 12 7: 7 1 0 8: 8 1 0 9: 1 2 19 10: 2 2 40 status[N == 0, N := NA] head(status, 10) origin destination N 1: 1 1 50 2: 2 1 16 3: 3 1 12 4: 4 1 11 5: 5 1 2 6: 6 1 12 7: 7 1 NA 8: 8 1 NA 9: 1 2 19 10: 2 2 40 

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     1 1 NA 1 a 2 2 2 NA b 3 3 3 3 c 4 NA 4 NA d 

Vous pouvez remplacer 0 par NA uniquement dans les champs numériques (c.-à-d. Exclure des choses comme des facteurs), mais cela fonctionne sur une base colonne par colonne:

 col[col == 0 & is.numeric(col)] <- NA 

Avec une fonction, vous pouvez l'appliquer à l'ensemble de vos données:

 changetoNA <- function(colnum,df) { col <- df[,colnum] if (is.numeric(col)) { #edit: verifying column is numeric col[col == -1 & is.numeric(col)] <- NA } return(col) } df <- data.frame(sapply(1:5, changetoNA, df)) 

Bien que vous puissiez remplacer le 1:5 par le nombre de colonnes de votre 1:ncol(df) données ou par 1:ncol(df) .