2015-01-09 11 views
6

Si possono creare date in R da tipi numerici, anche valori frazionari. Non è molto comune, ma accade per esempio quando si calcola la media delle date. Purtroppo, sembrano rompere splitperché divide coerce di divisione in numero intero in R e c'è una soluzione alternativa

> as.Date(-1, origin = "1970-01-01") 
[1] "1969-12-31" 
> as.Date(-1.0001, origin = "1970-01-01") 
[1] "1969-12-30" 
> split(as.Date(-1, origin = "1970-01-01"), 1)[[1]] 
[1] "1969-12-31" 
> split(as.Date(-1.0001, origin = "1970-01-01"), 1)[[1]] 
[1] "1969-12-31" #this is wrong 
> unclass(split(as.Date(-1, origin = "1970-01-01"), 1)[[1]]) 
[1] -1 
> unclass(split(as.Date(-1.0001, origin = "1970-01-01"), 1)[[1]]) 
[1] -1 #this is "why" 

Così due date che erano differenti sono fatti uguali da un split. Le persone sono d'accordo che questo è un bug o mi manca la ragione profonda? Qualche soluzione alternativa? Grazie

+0

Soluzione di lavoro: 'lapply (split (as.character (date), index) as.Date)'. Conserva la data ma modifica la rappresentazione sottostante. Ha bisogno di un 'lapply', lento in certi casi. – piccolbo

risposta

6

Per qualsiasi motivo, split.Date costringe il Date ingresso intero:

> split.Date 
function (x, f, drop = FALSE, ...) 
{ 
    y <- split.default(as.integer(x), f, drop = drop) 
    for (i in seq_along(y)) class(y[[i]]) <- "Date" 
    y 
} 
<bytecode: 0x2effb98> 
<environment: namespace:base> 

Questo è al minimo l'infelicità tra la funzione e la relativa documentazione, in quanto ?Date dice: "la data dovrebbe essere un numero intero, ma questo non è applicato nella rappresentazione interna. ". Alcuni potrebbero considerarlo un bug. Non ne sono sicuro.

È possibile evitare ciò chiamando direttamente split.default.

> split.default(as.Date(-1.0001, origin = "1970-01-01"), 1)[[1]] 
[1] "1969-12-30" 
+0

In nessun modo !! Sembra che l'unico obiettivo di scrivere questo metodo fosse introdurre questo bug. L'impostazione predefinita funziona bene. Grazie – piccolbo

+1

@piccolbo 'svn annotate src/library/base/R/dates.R' mi portano a https://stat.ethz.ch/pipermail/r-devel/2008-July/050134.html con la motivazione per l'introduzione essere prestazioni (ancora sostanziali per i vettori di> 1e6 elementi). Anche se ovviamente corretto è più importante. –

+0

grazie @MartinMorgan, che ha risparmiato più dolore. Sembra che tutto il tempo sia speso da split.default nell'assegnazione del ciclo for, riga prima dell'ultimo. Non sono sicuro del perché sia ​​così lento. Il compromesso potrebbe essere sostituito come sempre con un valore numerico, ma ciò renderebbe più comune l'uso delle doppie date e, come hai detto, è meglio se possibile. Un compromesso migliore potrebbe essere x = if (is.double (x)) x else as.integer (x). Dato il mio record di segnalazione di bug, lascerò ad altri di inviare questo. – piccolbo

Problemi correlati