【发布时间】:2023-04-02 16:22:01
【问题描述】:
我有一个大的持续监控的日期时间列,我需要将其分成半小时的时间段。
我尝试了一些rdata.table 代码将它们分开,但问题仍然存在于从一个时期到另一个时期的过渡时期。
下面的df 数据框是该数据的最小玩具示例。
library(data.table)
library(lubridate)
driver = rep(c("foo", "bar"), each = 10L)
dt = ymd_hm(c(
"2015-05-27 07:11", "2015-05-27 07:25", "2015-05-27 07:35",
"2015-05-27 07:42", "2015-05-27 07:53",
"2015-05-27 08:09", "2015-05-27 08:23", "2015-05-27 08:39",
"2015-05-27 08:52", "2015-05-27 09:12",
"2015-05-27 16:12", "2015-05-27 16:31", "2015-05-27 16:39",
"2015-05-27 16:53", "2015-05-27 17:29",
"2015-05-27 17:41", "2015-05-27 17:58", "2015-05-27 18:09",
"2015-05-27 18:23", "2015-05-27 18:42")
)
df = data.table(driver, dt)
我已尝试使用以下代码将它们分开:
df[,diff := as.integer(difftime(dt, shift(dt, 1), units = "mins")),
by = driver]
df[, diff := {diff[1] = 0L; diff}, driver]
df[,cum_mins := cumsum(diff), driver]
df[,cum_halfhour := round(cum_mins/30, 3), driver]
df[,flag := floor(cum_halfhour), driver]
结果表是
> df
driver dt diff cum_mins cum_halfhour flag
1: foo 2015-05-27 07:11:00 0 0 0.000 0
2: foo 2015-05-27 07:25:00 14 14 0.467 0
3: foo 2015-05-27 07:35:00 10 24 0.800 0
4: foo 2015-05-27 07:42:00 7 31 1.033 1
5: foo 2015-05-27 07:53:00 11 42 1.400 1
6: foo 2015-05-27 08:09:00 16 58 1.933 1
7: foo 2015-05-27 08:23:00 14 72 2.400 2
8: foo 2015-05-27 08:39:00 16 88 2.933 2
9: foo 2015-05-27 08:52:00 13 101 3.367 3
10: foo 2015-05-27 09:12:00 20 121 4.033 4
11: bar 2015-05-27 16:12:00 0 0 0.000 0
12: bar 2015-05-27 16:31:00 19 19 0.633 0
13: bar 2015-05-27 16:39:00 8 27 0.900 0
14: bar 2015-05-27 16:53:00 14 41 1.367 1
15: bar 2015-05-27 17:29:00 36 77 2.567 2
16: bar 2015-05-27 17:41:00 12 89 2.967 2
17: bar 2015-05-27 17:58:00 17 106 3.533 3
18: bar 2015-05-27 18:09:00 11 117 3.900 3
19: bar 2015-05-27 18:23:00 14 131 4.367 4
20: bar 2015-05-27 18:42:00 19 150 5.000 5
flag 列是我想要的,但不完全是。问题出现在flags 之间的过渡行上。例如,在第 3 行和第 4 行,我希望算法将第 4 行标记为 0,因为第 4 行 比第 3 行更接近半小时点(cum_halfhour 是 31 与 24 相比) .第 9 行和第 10 行仍然存在同样的问题。
当前算法的问题在于它总是将累积时间限制为 30 分钟。但在实践中,时间间隔是不规则的,因此实际上将截止点放在最近的 30 分钟点更有意义。如上面第 3 行和第 4 行示例所述。
解决方案可能很简单,但我想不出。有什么建议可以实现这个算法?谢谢!
【问题讨论】:
-
所以你是说你不想要半小时的时间 - 什么是想要的截止时间?
-
@Nova 谢谢你的评论。我确实想要半小时的时间。但日期时间并不完全是半小时,我需要一些近似值。如果您将
cum_mins列分类为半小时,您会改为分隔 0-24、24-58 分钟还是 0-31、31-58 分钟?我使用的算法总是将分钟限制在 30 分钟以下,但在最接近的 30 分钟进行截止对我来说更有意义。
标签: r datetime data.table lubridate