diff

时间:2016-12-18 01:57:08

标签: r date datetime time-series posix

当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 

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

这是一个错误吗?

2 个答案:

答案 0 :(得分:2)

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

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

?difftime帮助页面上写着:

  

如果单位=&#34; auto&#34;,则选择一组合适的单位,尽可能大(不包括&#34;周&#34;),其中所有绝对差异都大于一。

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

答案 1 :(得分:0)

如果您阅读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 =&#34; auto&#34;。

调用difftime

使用difftime致电units = "auto"确定

的单位
  

如果单位=&#34; auto&#34;,则选择一组合适的单位,最大单位   可能(排除&#34;周&#34;),其中所有的绝对差异都是   大于一。

可能会有所不同。如果您需要特定单位,可以直接使用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