2015-12-03 10 views
16

Recentemente, ho affrontato un comportamento in table funzione che non era quello che ci si aspettava:comportamento imprevisto di tabella funzione con "nan" Valori

Per esempio, per non prendere il seguente vettore:

ex_vec <- c("Non", "Non", "Nan", "Oui", "NaN", NA) 

Se controllo per NA valori nel mio vettore, "NaN" non è considerato uno (come previsto):

is.na(ex_vec) 
# [1] FALSE FALSE FALSE FALSE FALSE TRUE 

Ma se ho provato per ottenere i diversi valori di frequenze:

table(ex_vec) 
#ex_vec 
#Nan Non Oui 
# 1 2 1 

"NaN" non appare nella tabella.

Tuttavia, se "chiedere" table per mostrare i valori NA, ottengo questo:

table(ex_vec, useNA="ifany") 
#ex_vec 
# Nan NaN Non Oui <NA> 
# 1 1 2 1 1 

Così, le stringhe di caratteri "NaN" è trattata come una chiamata NA valore all'interno table, durante il trattamento nel uscita come valore non NA.

Lo so (sarebbe meglio e) Potrei risolvere il mio problema convertendo il mio vettore in un factor ma ciò nonostante, mi piacerebbe davvero sapere cosa sta succedendo qui. Qualcuno ha un'idea?

+1

questo è solo l'uso di base .. come "perché fa' somma (c (1, NA)) 'return NA?" 'table (..., exclude = if (useNA ==" no ") c (NA, NaN), useNA = c (" no "," ifany "," always ")" Non capisco lo scopo di queste risposte – rawr

+4

@rawr per spiegare perché una * stringa * è considerata come un valore 'NaN'? Questo non è l'uso richiesto, ma il perché: è meno ovvio del tuo esempio di somma che è coperto dal documento. Voglio dire: 'NaN! =" NaN "' quindi perché '' "NaN" 'escluso poiché non fa parte del vettore di esclusione) – Tensibai

+0

@Tensibai di nuovo, i documenti dicono' escludi: i livelli da rimuovere per tutti i fattori' _levels_ non sono 'NA' e non sono' NaN', sono _strings_ .. away_strings_ try 'table (1, exclude = 1)' – rawr

risposta

13

Quando factor corrisponda livelli per un vettore converte sua lista exclude allo stesso tipo del vettore di ingresso:

exclude <- as.vector(exclude, typeof(x)) 

quindi se l'elenco escludere trovi NaN e proprio vettore è personaggio, questo accade:

as.vector(exclude, typeof(letters)) 
[1] NA "NaN" 

Oh caro. Ora le vere stringhe "NaN" saranno escluse.

Per risolvere il problema, utilizzare exclude=NA in table (e factor se si stanno facendo dei fattori che potrebbero colpirlo).

Io amo questo nella documentazione per factor:

There are some anomalies associated with factors that have ‘NA’ as 
a level. It is suggested to use them sparingly, e.g., only for 
tabulation purposes. 

Rassicurante ...

+0

Grazie mille per questa risposta molto chiara (adoro anche la citazione del fattore doc!) – Cath

5

prima idea venuta in mente era di avere uno sguardo a table definizione che Iniziamo:

> table 
function (..., exclude = if (useNA == "no") c(NA, NaN), useNA = c("no", 
    "ifany", "always"), dnn = list.names(...), deparse.level = 1) 
{ 

sembra logico, da tabella predefinita escludono NA e NaN.

Scavando all'interno del codice tabella vediamo che se x non è un fattore lo costringe a un fattore (nulla di nuovo qui, è detto nel documento).

else { 
     a <- factor(a, exclude = exclude) 

non ho trovato altro che possa hanno avuto un impatto l'ingresso di costringere "NaN" in NA valori.

Quindi esaminando fattore per ottenere il motivo per cui si trova la causa principale:

> factor 
function (x = character(), levels, labels = levels, exclude = NA, 
    ordered = is.ordered(x), nmax = NA) 
{ 
[...] # Snipped for brievety 
    exclude <- as.vector(exclude, typeof(x)) 
    x <- as.character(x) 
    levels <- levels[is.na(match(levels, exclude))] # defined in the snipped part above, is the sorted unique values of input vector, coerced to char. 
    f <- match(x, levels) 
[...] 
    f 
} 

Qui abbiamo ottenuto, il parametro di escludere, pur essendo NA valori è costretto in un vettore di carattere.

Quindi, ciò che accade è:

> ex_vec <- c("Non", "Non", "Nan", "Oui", "NaN", NA) 
> excludes<-c(NA,NaN) 
> as.vector(excludes,"character") 
[1] NA "NaN" 
> match(ex_vec,as.vector(excludes,"character")) 
[1] NA NA NA NA 2 1 

Facciamo partita carattere "nan" come il vettore escludere come stato costretto a carattere prima del confronto.

+0

Grazie a @Tensibai per la spiegazione! Perché "NaN" rimane ordinato nei risultati 'table' come un valore normale e non alla fine con' '? – Cath

+1

@CathG Poiché i livelli sono ordinati alla creazione;) Vedere il commento nel codice fattore sulla riga 'levels', una volta non esclusi diventano normali voci – Tensibai

+1

@CathG quando parametro tabella è impostato su qualcos'altro che 'no' non vengono rimossi e trattati come normali stringhe senza significato speciale – Tensibai