При тестировании я заметил, что эта проблема все еще существует для 32-разрядной версии R 3.01 и что это связано с усечением данных с плавающей запятой, которое характерно для 32-разрядной реализации операторов печати, формата и as.character для даты и времени POSIXlt.
Базовые данные не были сохранены в другом типе, который приводит к усечению в одном случае (32 бита), а не в другом (64 бита), но функции «печать», «формат» и «как.символ» для Тип POSIXlt, который используется для отображения данных POSIXlt в виде отображаемой строки.
Хотя задокументированное поведение заключается в том, что эти функции усекают (игнорируют) лишние цифры (как упоминал @Gavin Simpson), это не так для 32- и 64-битных версий. Показывать; мы сгенерируем 1000 разных значений времени и выполним несколько операций сравнения:
> options(digits.sec=3)
> x = as.POSIXlt("13:29:56.061", format='%H:%M:%OS', tz='UTC')
> for (i in 0:999) {
> x[i+1] = as.POSIXlt(paste0("13:29:56.",sprintf("%03d",i)),format='%H:%M:%OS',tz='UTC')
> }
> sum(x[2:1000]>x[1:999])
[1] 999
Как в 32-битной, так и в 64-битной версии операторы сравнения одинаковы, однако в 32-битной я вижу:
> x[1:6]
[1] "2015-10-16 13:29:56.000 UTC" "2015-10-16 13:29:56.000 UTC"
[3] "2015-10-16 13:29:56.002 UTC" "2015-10-16 13:29:56.003 UTC"
[5] "2015-10-16 13:29:56.003 UTC" "2015-10-16 13:29:56.005 UTC"
Так что проблема явно в дисплее. Глядя на фактические числа в типе данных POSIXlt, особенно на секунды, мы видим, что происходит:
> y = (x[1:6]$sec)
> y
[1] 56.000 56.001 56.002 56.003 56.004 56.005
> trunc(y*1000)/1000
[1] 56.000 56.001 56.002 56.003 56.004 56.005
> trunc((y-floor(y))*1000)/1000
[1] 0.000 0.000 0.002 0.003 0.003 0.005
Я бы предположил, что это ошибка, которую следует исправить в базовой базовой библиотеке, хотя в качестве временного исправления вы можете перезаписать функции «print», «as.character» и «format», чтобы изменить вывод на желаемый результат. например
format.POSIXlt = function(posix) {
return(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)))
}
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)))
}
as.character.POSIXlt = function(posix) {
return(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)))
}
person
SuaveIncompetence
schedule
16.10.2015
format = '%H:%M:%OS'
. - person Gavin Simpson   schedule 07.06.2012