【问题标题】:Milliseconds puzzle when calling strptime in R在 R 中调用 strptime 时的毫秒难题
【发布时间】:2012-01-17 04:13:47
【问题描述】:
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”相差一毫秒。

【问题讨论】:

  • 您可能希望包含来自 sessionInfo 的输出,因为我无法重现此行为,因此您的 R 版本、操作系统等可能是相关的。
  • 在 64 位 Ubuntu 11.10 上使用 R-2.14.1 为我工作。您是否尝试过重新启动计算机?
  • FWIW,我得到与 OP 相同的行为,在 Windows 机器上使用 R-2.14.1。
  • 我可以在 32 位 Windows XP 上使用 R-2.14.1 进行复制。
  • stackoverflow.com/q/7726034/210673stackoverflow.com/q/15383057/210673 这个问题的未来读者可能也会感兴趣

标签: r strptime


【解决方案1】:

这与R-FAQ 7.31 相关,尽管它采用了不同寻常的伪装。

您看到的行为是以下因素的组合结果:(a) 二进制计算机对(大多数)十进制值的不精确表示; (b) strftimestrptime 的记录行为,即截断而不是舍入秒的小数部分到指定的小数位数。

来自?strptime 帮助文件(关键字被“截断”):

特定于 R 的是“%OSn”,用于输出秒数 截断为“0

一个例子可能会比进一步解释更有效地说明正在发生的事情:

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"

在上面的示例中,小数“.3”必须用一个略小于“0.300000000000000000”的二进制数来近似,比如“0.29999999999999999”。因为 strptimestrftime 截断而不是舍入到指定的小数位,如果小数位数设置为 1,0.3 将转换为 0.2。同样的逻辑适用于您的示例时间,其中一半表现出这一点行为,正如(平均而言)预期的那样。

【讨论】:

  • 出于好奇,您知道为什么 Joshua 和我无法在 Ubuntu 和 OSX 上重现它吗?
  • @joran:会不会是 32 位与 64 位架构的问题?我可以在 FC16 32bit 上重现该问题,因此这似乎不太可能是操作系统问题...
  • @joran -- 不,虽然我很感兴趣,但我的知识并不那么渊博。我想知道从?strftime 帮助文件的更下方是否有线索:The behaviour of other conversion specifications (and even if other character sequences commencing with ‘%’ _are_ conversion specifications) is system-specific.
  • @nico -- 这是一个有趣的想法。尽管如此,我认为同样的基本限制应该适用于 64 位机器上的二进制表示,尽管将被截断的特定值很容易不同。我想知道 joran 或 Joshua Ulrich 是否在 OP 的问题中看到 any 小数秒的截断。
  • 我无法在 OSX(Lion 或 SL)中使用 R 2.14.0 或 2.14.1(均为 64 位)复制它(对于任何示例)。所以也许这是一个 32 对 64 位的东西。我将不得不尝试使用 32 位构建的 OSX...
【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 2021-03-27
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多