2012-01-17 2 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" 

Я смущен, почему существует разница в миллисекундах от «009», а затем снова от «011».Миллисекунды головоломки при вызове strptime в R

+0

Вы можете включить вывод 'sessionInfo', как я могу Не воспроизводите это поведение, поэтому ваша версия R, ОС и т. д. может быть релевантной. – joran

+0

Работает для меня с R-2.14.1 на 64-битном Ubuntu 11.10. Вы пытались перезагрузить компьютер? –

+0

FWIW, я получаю то же поведение, что и OP, с R-2.14.1 в окне Windows. –

ответ

9

Это связано с R-FAQ 7.31, хотя оно принимает не обычный образ.

Поведение, которое вы видите, получается из комбинации: (a) неточного представления (большинства) десятичных значений двоичными компьютерами; и (b) документированное поведение strftime и strptime, которое составляет , а не округлять до дробных частей секунд, до указанного количества знаков после запятой.

С помощью файла ?strptime (ключевого слова является 'усеченным'):

Специфических для R является '% OSn', который на выход дает секунды укорочены до «0 < = п < = 6 'после запятой (и если «% OS» не , за которым следует цифра, она использует настройку ' getOption («digits.secs») ', или если это не задано, «n = 3»).

пример, вероятно, показывают, что более эффективно происходит, чем дальнейшие объяснения:

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" 

В примере выше, дробно»0,3' должно быть лучше аппроксимируется двоичным числом, которое немного меньше чем «0.300000000000000000» - что-то вроде «0.29999999999999999». Поскольку strptime и strftime усекают, а не округляют до указанного десятичного знака, 0,3 будут преобразованы в 0,2, если число десятичных знаков установлено равным 1. Эта же логика выполняется для ваших примерных времен, из которых половина демонстрирует это поведение, как и (в среднем).

+0

Из любопытства, есть ли у вас какие-либо идеи, почему Джошуа и я не могли воспроизвести его на Ubuntu и OSX? – joran

+0

@joran: может быть проблема 32-битной архитектуры с 64-битной архитектурой?Я могу воспроизвести проблему на FC16 32bit, поэтому кажется маловероятным, что это проблема ОС ... – nico

+0

@joran - Нет, я не настолько осведомлен, хотя я заинтригован. Интересно, что это из дальнейшего в файле справки '? Strftime' является подсказкой:' Поведение других спецификаций преобразования (и даже если другие последовательности символов, начинающиеся с спецификаций преобразования% '_are_), зависят от конкретной системы. ' –

2

Я знаю, что это было «ответило», но эти проблемы все еще существуют для 32-битного R, существует несогласованность в реализации между 32-битными и 64-разрядными версиями. Проблема усечения частично верна, но это не результат функции strptime, а метод print.POSIXlt в этом конкретном случае.

Это можно продемонстрировать, перезаписав функцию функцией, которая производит ожидаемое поведение. Например.

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))) 
    } 

Теперь время отображается, как ожидалось:

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

Для получения более подробной информации, я покрыл это здесь R issue with rounding milliseconds

Смежные вопросы