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 NULL
ce 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, NA
est 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 NULL
dans 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
, cov
ou cor
, qui est en fait équivalent à la première substitution , avec des zéros NA
et le réglage de la valeur de use
que"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 == 0
vectorisation. df == 0
renvoie (essayez-le) une matrice de 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 [...]
(voir ?'['
). Enfin, si le résultat de df[df == 0]
est parfaitement intuitif, il peut sembler étrange que cela 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 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 NA
par 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 0
par NA
uniquement 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:5
par le nombre de colonnes de votre bloc de données ou par 1:ncol(df)
.
1:5
par 1:ncol(df)
à la fin. Je ne voulais pas rendre l'équation trop complexe ou difficile à lire.
1:5
les 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 }
.