Я считаю, что R некорректно форматирует типы POSIXct с дробными секундами. Я отправил это через R-bugs в качестве запроса на повышение и получил отмывку: "мы считаем, что текущее поведение верное - ошибка удалена". Хотя я очень благодарен за работу, которую они проделали и продолжают делать, я хотел, чтобы другие люди взяли на себя эту конкретную проблему и, возможно, посоветовали, как сделать этот пункт более эффективным.
Вот пример:
> tt <- as.POSIXct('2011-10-11 07:49:36.3')
> strftime(tt,'%Y-%m-%d %H:%M:%OS1')
[1] "2011-10-11 07:49:36.2"
То есть, tt создается как время POSIXct с дробной частью .3 секунды. Когда он печатается с десятичной цифрой, указанное значение равно .2. Я много работаю со временными отметками миллисекундной точности, и это вызывает у меня много головных болей, которые часто печатаются на одну ступень ниже, чем фактическое значение.
Вот что происходит: POSIXct - это число с плавающей запятой секунд с эпохи. Все целые значения обрабатываются точно, но в плавающей запятой base-2 самое близкое значение к .3 очень немного меньше .3. Указанное поведение strftime()
для формата %OSn
- округление до запрошенного числа десятичных цифр, поэтому отображаемый результат равен .2. Для других дробных частей значение с плавающей запятой немного превышает введенное значение, и дисплей дает ожидаемый результат:
> tt <- as.POSIXct('2011-10-11 07:49:36.4')
> strftime(tt,'%Y-%m-%d %H:%M:%OS1')
[1] "2011-10-11 07:49:36.4"
Аргумент разработчиков заключается в том, что для типов времени мы всегда должны округлять до требуемой точности. Например, если время 11: 59: 59,8, то печать его с форматом %H:%M
должна давать "11:59" не "12:00", а %H:%M:%S
должна указывать "11:59:59" не "12: 00: 00". Я согласен с этим для целых чисел секунд и для флага формата %S
, но я думаю, что поведение должно отличаться для флагов формата, которые предназначены для дробных частей секунд. Я бы хотел, чтобы %OSn
применял округленное к ближайшему поведению даже для n = 0
, а %S
использовал округление, так что печать 11: 59: 59.8 с форматом %H:%M:%OS0
дала бы "12:00:00". Это не повлияло бы на целые числа секунд, потому что они всегда представлены точно, но это более естественно обрабатывало бы ошибки округления для дробных секунд.
Так печатает дробные части, например C, потому что округление целых чисел:
double x = 9.97;
printf("%d\n",(int) x); // 9
printf("%.0f\n",x); // 10
printf("%.1f\n",x); // 10.0
printf("%.2f\n",x); // 9.97
Я быстро просмотрел, как дробные секунды обрабатываются на других языках и в разных средах, и, похоже, не существует консенсуса. Большинство конструкций рассчитаны на целые числа секунд, а дробные части - это запоздалая мысль. Мне кажется, что в этом случае разработчики R сделали выбор, который не совсем необоснован, но на самом деле не самый лучший, и не согласуется с соглашениями в других местах для отображения чисел с плавающей запятой.
Каковы мысли людей? Правильно ли поведение R? Так вы сами это разработали?