Confronti numerici con valori NA che causano sottoinsiemi errati in R
-
21-12-2019 - |
Domanda
Qualcuno può spiegarmi perché le valutazioni logiche che si risolvono in NA producono righe fasulle in sottoinsiemi basati sul confronto vettoriale?Per esempio:
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
Dato questo comportamento inaspettato, qual è il modo migliore per contare i dipendenti che guadagnano più di 100.000 nell'esempio precedente?
Soluzione
Prima di tutto, probabilmente non vuoi cbind()
primo: questo costringerà tutte le tue variabili al carattere.
emp_salary <- data.frame(employee,salary)
Due possibili soluzioni:
subset
esclude automaticamente i casi in cui il criterio èNA
:
nrow(subset(emp_salary,salary>1e5))
- contare i risultati direttamente e utilizzarli
na.rm=TRUE
:
sum(salary>1e5,na.rm=TRUE)
Per quanto riguarda la logica dietro le righe fasulle:
bigsal <- salary>1e5
è un vettore logico che contieneNA
s, come deve (perché non c'è modo di sapere se anNA
valore soddisfa il criterio oppure no).- quando si indicizzano le righe di un frame di dati con un vettore logico contenente
NA
s, questo è probabilmente il pezzo più saliente del documento (dahelp("[")
):Durante l'estrazione, un indice "NA" numerico, logico o di caratteri seleziona un elemento sconosciuto e quindi restituisce "NA" nell'elemento corrispondente di un risultato logico, intero, numerico, complesso o di caratteri e "NULL" per un elenco.
help("[.data.frame")
e non sono riuscito a trovare nulla di più utile.)
La cosa da ricordare è che una volta eseguita l'indicizzazione, R non sa più che il vettore logico è stato creato dal salary
colonna, quindi non c'è modo di fare ciò che potresti desiderare, ovvero mantenere i valori nelle altre colonne.Ecco un modo di pensare al comportamento apparentemente strano di riempire tutte le colonne del file NA
fila con NA
S:se R lasciasse completamente fuori la riga, ciò corrisponderebbe al criterio essendo FALSE
.Se lo conserva (e ricorda che non può conservare solo poche colonne e eliminare le altre), ciò corrisponderebbe al criterio essendo TRUE
.Se il criterio non è nessuno dei due FALSE
né TRUE
, allora è difficile capire quale altro comportamento abbia senso...