J'ai un dataframe avec quelques colonnes numériques. Certaines lignes ont une valeur 0 qui doit être considérée comme nulle dans l'analyse statistique. Quel est le moyen le plus rapide de remplacer toute la valeur 0 par NULL dans R?
J'ai un dataframe avec quelques colonnes numériques. Certaines lignes ont une valeur 0 qui doit être considérée comme nulle dans l'analyse statistique. Quel est le moyen le plus rapide de remplacer toute la valeur 0 par NULL dans R?
Réponses:
Remplacement de tous les zéros par NA:
df[df == 0] <- NA
Explication
1. Ce n'est pas NULLce que vous devriez vouloir remplacer par des zéros. Comme il est dit dans ?'NULL',
NULL représente l'objet nul dans R
ce qui est unique et, je suppose, peut être considéré comme l'objet le moins informatif et le plus vide. 1 Il n'est alors pas si surprenant que
data.frame(x = c(1, NULL, 2))
# x
# 1 1
# 2 2
Autrement dit, 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 un indicateur de valeur manquante. NA peut être contraint à n'importe quel autre type de vecteur sauf brut.
Surtout, NAest de longueur 1 pour que R lui réserve de l'espace. Par exemple,
data.frame(x = c(1, NA, 2))
# x
# 1 1
# 2 NA
# 3 2
De plus, la structure de la trame 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. NULL valeurs).
Vous pouvez maintenant remplacer les zéros par NULLdans un bloc de données dans le sens de supprimer complètement toutes les lignes contenant au moins un zéro. Lors de l' utilisation, par exemple var, covou cor, qui est en fait équivalent à la première substitution , avec des zéros NAet le réglage de la valeur de useque"complete.obs" . Cependant, cela n'est généralement 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 df == 0vectorisation. df == 0renvoie (essayez-le) une matrice de même taille que df, avec les entrées TRUEet FALSE. De plus, nous sommes également autorisés à passer cette matrice au sous-ensemble [...](voir ?'['). Enfin, si le résultat de df[df == 0]est parfaitement intuitif, il peut sembler étrange que cela df[df == 0] <- NAdonne 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 objets, mais il le fait avec des blocs de données; voir ?'<-'.
1 L'ensemble vide dans la théorie des ensembles se sent en quelque sorte lié.
2 Autre similitude avec la théorie des ensembles: l'ensemble vide est un sous-ensemble de chaque ensemble, mais nous ne lui réservons aucun espace.
Laissez-moi supposer 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 (du total 21), il suffit de faire ceci
df[, 12:18][df[, 12:18] == 0] <- NA
Une manière alternative sans le [<- fonction:
Un exemple de cadre de données dat(copié sans vergogne à partir 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 NApar la 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
Parce que quelqu'un a demandé la version Data.Table de ceci, et parce que la solution data.frame donnée ne fonctionne pas avec data.table, je propose la solution ci-dessous.
En gros, 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
Vous pouvez remplacer 0par NAuniquement dans les champs numériques (c'est-à-dire en excluant des éléments tels que les facteurs), mais cela fonctionne colonne par colonne:
col[col == 0 & is.numeric(col)] <- NA
Avec une fonction, vous pouvez l'appliquer à l'ensemble de votre bloc de 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:5par le nombre de colonnes de votre bloc de données ou par 1:ncol(df).
1:5par 1:ncol(df)à la fin. Je ne voulais pas rendre l'équation trop complexe ou difficile à lire.
1:5les numéros de colonne que vous voulez modifiés, comme 12:15, mais si vous vouliez confirmer qu'il n'affectera les colonnes numériques puis juste envelopper la deuxième ligne de la fonction dans une instruction if, comme ceci: if (is.numeric(col)) { col[col == -1 & is.numeric(col)] <- NA }.