2012-01-17 17 views
6
options(digits.secs = 3); 

> strptime("2007-03-30 15:00:00.007", format = "%Y-%m-%d %H:%M:%OS"); 
[1] "2007-03-30 15:00:00.007" 
> strptime("2007-03-30 15:00:00.008", format = "%Y-%m-%d %H:%M:%OS"); 
[1] "2007-03-30 15:00:00.008" 
> strptime("2007-03-30 15:00:00.009", format = "%Y-%m-%d %H:%M:%OS"); 
[1] "2007-03-30 15:00:00.008" 
> strptime("2007-03-30 15:00:00.010", format = "%Y-%m-%d %H:%M:%OS"); 
[1] "2007-03-30 15:00:00.01" 
> strptime("2007-03-30 15:00:00.011", format = "%Y-%m-%d %H:%M:%OS"); 
[1] "2007-03-30 15:00:00.010" 
> strptime("2007-03-30 15:00:00.999", format = "%Y-%m-%d %H:%M:%OS"); 
[1] "2007-03-30 15:00:00.998" 

Sono confuso perché c'è una differenza di un millisecondo da "009", quindi di nuovo da "011".Errore di millisecondi durante il richiamo del tempo in R

+0

Si potrebbe desiderare di includere l'output di 'sessionInfo', come posso riprodurre questo comportamento, quindi la versione R, il sistema operativo, ecc. potrebbero essere pertinenti. – joran

+0

Funziona per me con R-2.14.1 su Ubuntu 11.10 a 64 bit. Hai provato a riavviare il computer? –

+0

FWIW, ottengo lo stesso comportamento dell'OP, con R-2.14.1 su una casella di Windows. –

risposta

9

Questo è correlato a R-FAQ 7.31, anche se assume un aspetto diverso dal solito.

Il comportamento visualizzato risulta da una combinazione di: (a) la rappresentazione inesatta dei (più) valori decimali da parte di computer binari; e (b) il comportamento documentato di strftime e strptime, che è a troncato anziché arrotondare le parti frazionarie di secondi, al numero specificato di posizioni decimali.

Dal file di aiuto ?strptime (la parola chiave è 'tronco'):

specifico per R è '% OSN', che per l'uscita dà i secondi troncato a '0 < = n < = 6 'decimali (e se'% OS 'non è seguito da una cifra, usa l'impostazione di ' getOption ("digits.secs") ', o se non è impostato,' n = 3 ').

Un esempio sarà probabilmente illustrare ciò che sta succedendo in modo più efficace di ulteriori spiegazioni:

strftime('2011-10-11 07:49:36.3', format="%Y-%m-%d %H:%M:%OS6") 
[1] "2011-10-11 07:49:36.299999" 

strptime('2012-01-16 12:00:00.3', format="%Y-%m-%d %H:%M:%OS1") 
[1] "2012-01-16 12:00:00.2" 

Nell'esempio precedente, il frazionale' 0,3' deve essere meglio approssimata da un numero binario che è un po' meno di '0.300000000000000000' - qualcosa come '0.29999999999999999'. Poiché strptime e strftime vengono troncati anziché arrotondati al decimale specificato, 0.3 verrà convertito in 0,2, se il numero di posizioni decimali è impostato su 1. La stessa logica vale per i tempi di esempio, di cui metà mostra questo comportamento, come sarebbe (in media) è previsto.

+0

Per curiosità, hai qualche idea del perché Joshua e io non siamo riusciti a riprodurlo su Ubuntu e OSX? – joran

+0

@joran: potrebbe essere un problema di architettura a 32 bit contro 64 bit?Posso riprodurre il problema su FC16 32bit, quindi sembra improbabile che sia un problema del sistema operativo ... – nico

+0

@joran - No, non sono così informato, anche se sono incuriosito. Mi chiedo se questo, più avanti nel file di aiuto '? Strftime' sia un indizio:' Il comportamento di altre specifiche di conversione (e anche se altre sequenze di caratteri iniziano con '%' _are_ specifiche di conversione) è specifico del sistema. –

2

So che è stata "risposta" ma questo problema esiste ancora per 32 bit R, c'è un'incongruenza nell'implementazione tra le versioni a 32 bit e 64 bit. Il problema del troncamento è parzialmente vero ma non è il risultato della funzione strptime ma del metodo print.POSIXlt in questo caso particolare.

Ciò può essere dimostrato sovrascrivendo la funzione con una funzione che produce il comportamento previsto. Per esempio.

print.POSIXlt = function(posix) { 
    print(paste0(posix$year+1900,"-",sprintf("%02d",posix$mon+1),"-",sprintf("%02d",posix$mday)," ", 
     sprintf("%02d",posix$hour),":",sprintf("%02d",posix$min),":",sprintf("%002.003f",posix$sec))) 
    } 

Ora le visualizzazioni in tempo come previsto:

> strptime("2007-03-30 15:00:00.009", format = "%Y-%m-%d %H:%M:%OS"); 
[1] "2007-03-30 15:00:0.009" 

Per ulteriori dettagli, ho coperto questo qui R issue with rounding milliseconds

Problemi correlati