【问题标题】:Unexpected behavior with POSIXct datetimes under diff差异下 POSIXct 日期时间的意外行为
【发布时间】:2017-05-03 10:55:24
【问题描述】:

当 diff() 应用于 POSIXct 日期时间时,会得到意想不到的结果。差异的单位并不总是相同的。

在每小时递增的 POSIXct 日期时间中,diff() 按预期工作。如果小时数是连续的,则 diff 会为您提供小时差,如下所示。

beg = ISOdatetime(2016, 11, 6, 1, 0 ,0, tz="Americ/Los_Angeles")
end = ISOdatetime(2016, 11, 7, 23, 0 ,0, tz="Americ/Los_Angeles")
dte = seq(from=beg, to=end, by="hour")
del = diff(dte)
table(del)
del
  1 
 46 

如果有间隔,结果仍然是小时,这是有道理的。

dte = dte[-4]
del = diff(dte)
table(del)
 del
 1  2 
44  1

现在,这是有趣的行为。

dte1 = sort(c(dte, dte[10]))
del = diff(dte1)
table(del)
del
 0 3600 7200 
 1   44    1 

在这里我添加了一个重复的小时,突然间,差异单位现在以秒为单位。

这是一个错误吗?

【问题讨论】:

  • 这可能是不合理的,但由于如果您查看dput(del) 会正确报告单位,因此很难将其视为错误。
  • 也许只有当您认为夏令时是人类社会中的一个错误时,这当然是可以辩护的。 (我假设这种差异的可能性与这个时间段达到 DST 的事实无关。)
  • @joran 不确定为什么与夏令时有关?
  • 这是difftimeunits = "auto" 的行为,这是减去日期时间的默认值。
  • 只是看似巧合,不太可能,仅此而已。

标签: r date datetime time-series posix


【解决方案1】:

有一个 units<- 函数用于 difftime 对象:

> units(del) <- 'hours'
> table(del)
del
 0  1 
 1 46 

?difftime 帮助页面显示:

如果 units = "auto",则选择一组合适的单位,即所有绝对差均大于 1 的最大可能单位(不包括“周”)。

因此,在您的情况下,函数的逻辑可能被 0 值偏离,单位设置为秒。

【讨论】:

  • 我喜欢你的回答;但是,正如@allstaire 指出的那样,不可能将units 参数传递给diff,因此这需要额外的代码行,并且必须在官方文档之外学习该技巧。
  • 我不确定正在提出什么暗示的批评。我建议使用记录的函数设置units 参数,而alistaire 建议使用difftime(而不是diff.difftime)一种允许设置单位的方法:difftime(tail(dte1,-1), head(dte1,-1) ,units="hour")。两者似乎都是合理的(并且“在文档中”),我想说我的建议稍微“紧凑”,因为编码器不需要构造 2 个较短的向量。他在允许滞后论点方面会更笼统。
  • 是的,我将为 POSIXt 推出我自己的自定义 diff。你的建议很好。
【解决方案2】:

如果您阅读了diff.POSIXt 的源代码,它包含代码

r <- r[i1] - r[-length(r):-(length(r) - lag + 1L)]

r 是 POSIXct 序列,i1 定义为

i1 <- -seq_len(lag)

如果lag 参数的默认值为 1,则将仅为 -1。因此,diff(dte1) 等价于

dte1[-1L] - dte1[-length(dte1):-(length(dte1) - 1L + 1L)]

你可以简化为

dte1[-1L] - dte1[-length(dte1)]

如果您查看?difftime,您会看到

日期时间对象的减法给出了这个类的一个对象,通过 使用units =“auto”调用difftime。

units = "auto" 调用difftime 确定单位

如果units = "auto",则选择一组合适的单位,最大的 可能(不包括“周”),其中所有绝对差异都是 大于一。

这可能会有所不同。如果你想要特定的单位,你可以直接用difftime重构操作:

difftime(dte1[-1], dte1[-length(dte1)], units = 'hours')

## Time differences in hours
##  [1] 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [47] 1 1

【讨论】:

    猜你喜欢
    • 2022-11-15
    • 2021-06-02
    • 2021-01-18
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多