Comparaisons numériques avec des valeurs NA provoquant de mauvais sous-ensembles dans R
-
21-12-2019 - |
Question
Quelqu'un peut-il m'expliquer pourquoi les évaluations logiques qui aboutissent à NA produisent de fausses lignes dans des sous-ensembles basés sur une comparaison vectorielle ?Par exemple:
employee <- c("Big Shot CEO", "Programmer","Intern","Guy Who Got Fired Last Week")
salary <- c( 10000000, 50000, 0, NA)
emp_salary <- data.frame(employee,salary)
# how many employees paid over 100K?
nrow(emp_salary[salary>100000,]) # Returns 2 instead of 1 -- why?
emp_salary[salary>100000,]
# returns a bogus row of all NA's (not "Guy Who Got Fired")
# employee salary
# 1 Big Shot CEO 1e+07
# NA <NA> <NA>
salary[salary>100000]
# returns:
# [1] 1e+07 NA
NA > 100000 #returns NA
Compte tenu de ce comportement inattendu, quelle est la meilleure façon de compter les employés gagnant plus de 100 000 $ dans l'exemple ci-dessus ?
La solution
Tout d'abord, vous ne voulez probablement pas cbind()
d'abord - cela contraindra toutes vos variables au caractère.
emp_salary <- data.frame(employee,salary)
Deux solutions possibles :
subset
exclut automatiquement les cas où le critère estNA
:
nrow(subset(emp_salary,salary>1e5))
- compter les résultats directement et utiliser
na.rm=TRUE
:
sum(salary>1e5,na.rm=TRUE)
Quant à la logique derrière les fausses lignes :
bigsal <- salary>1e5
est un vecteur logique qui contientNA
s, comme il se doit (car il n'y a aucun moyen de savoir si unNA
la valeur satisfait ou non au critère).- lors de l'indexation des lignes d'une trame de données avec un vecteur logique contenant
NA
s, c'est probablement le morceau de document le plus important (depuishelp("[")
):Lors de l'extraction, un index numérique, logique ou caractère « NA » sélectionne un élément inconnu et renvoie ainsi « NA » dans l'élément correspondant d'un résultat logique, entier, numérique, complexe ou caractère, et « NULL » pour une liste.
help("[.data.frame")
et je n'ai rien vu de plus utile.)
Ce qu'il faut retenir, c'est qu'une fois l'indexation effectuée, R ne sait plus que le vecteur logique a été créé à partir du salary
colonne, il n'y a donc aucun moyen pour lui de faire ce que vous pourriez vouloir, c'est-à-dire conserver les valeurs dans les autres colonnes.Voici une façon de réfléchir au comportement apparemment étrange du remplissage de toutes les colonnes du NA
rangée avec NA
s :si R laisse entièrement la ligne de côté, cela correspondrait au critère étant FALSE
.S'il le conserve (et rappelez-vous qu'il ne peut pas conserver quelques colonnes et supprimer les autres), alors cela correspondrait au critère étant TRUE
.Si le critère n'est ni l'un ni l'autre FALSE
ni TRUE
, alors il est difficile de voir quel autre comportement a du sens...