diff 下 POSIXct 日期时间的意外行为
Unexpected behavior with POSIXct datetimes under diff
将 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
我在这里添加了一个重复的小时,突然之间,diff 单位现在变成了秒。
这是一个错误吗?
difftime 对象有一个 units<-
函数:
> units(del) <- 'hours'
> table(del)
del
0 1
1 46
?difftime
帮助页面说:
If units = "auto", a suitable set of units is chosen, the largest possible (excluding "weeks") in which all the absolute differences are greater than one.
因此,在您的案例中,函数的逻辑可能被 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
,您会看到
Subtraction of date-time objects gives an object of this class, by
calling difftime with units = "auto".
用 units = "auto"
调用 difftime
通过
确定单位
If units = "auto", a suitable set of units is chosen, the largest
possible (excluding "weeks") in which all the absolute differences are
greater than one.
这可能会有所不同。如果你想要特定的单位,你可以直接用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
将 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
我在这里添加了一个重复的小时,突然之间,diff 单位现在变成了秒。
这是一个错误吗?
difftime 对象有一个 units<-
函数:
> units(del) <- 'hours'
> table(del)
del
0 1
1 46
?difftime
帮助页面说:
If units = "auto", a suitable set of units is chosen, the largest possible (excluding "weeks") in which all the absolute differences are greater than one.
因此,在您的案例中,函数的逻辑可能被 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
,您会看到
Subtraction of date-time objects gives an object of this class, by calling difftime with units = "auto".
用 units = "auto"
调用 difftime
通过
If units = "auto", a suitable set of units is chosen, the largest possible (excluding "weeks") in which all the absolute differences are greater than one.
这可能会有所不同。如果你想要特定的单位,你可以直接用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