将时间序列数据子集到定义的间隔中

Posted

技术标签:

【中文标题】将时间序列数据子集到定义的间隔中【英文标题】:Subset time series data into defined intervals 【发布时间】:2014-03-08 13:19:14 【问题描述】:

我正在尝试将数据子集或过滤到定义的时间间隔中。你能帮我将以下数据分成 2 分钟的时间间隔吗?我查看了 Lubridate、split() 和 cut(),但无法弄清楚如何正确执行此操作。

我查看了this post on SO,但它似乎不是我需要的。

请注意,第 1 列和第 2 列是字符类,第 3 列是 POSIXct 类。如果可能的话,我想让解决方案使用日期时间列 (POSIXct)。

         date  time            datetime use..kW.     gen..kW. Grid..kW.
120 12/31/2013 21:59 2013-12-31 21:59:00 1.495833 -0.003083333  1.495833
121 12/31/2013 21:58 2013-12-31 21:58:00 1.829583 -0.003400000  1.829583
122 12/31/2013 21:57 2013-12-31 21:57:00 1.977283 -0.003450000  1.977283
123 12/31/2013 21:56 2013-12-31 21:56:00 2.494750 -0.003350000  2.494750
124 12/31/2013 21:55 2013-12-31 21:55:00 2.218283 -0.003500000  2.218283
125 12/31/2013 21:54 2013-12-31 21:54:00 2.008283 -0.003566667  2.008283
126 12/31/2013 21:53 2013-12-31 21:53:00 2.010917 -0.003600000  2.010917
127 12/31/2013 21:52 2013-12-31 21:52:00 2.011867 -0.003583333  2.011867
128 12/31/2013 21:51 2013-12-31 21:51:00 2.015033 -0.003600000  2.015033
129 12/31/2013 21:50 2013-12-31 21:50:00 2.096550 -0.003850000  2.096550

新的子集只会从每两分钟间隔获取数据,如下所示:

      date  time            datetime use..kW.     gen..kW. Grid..kW.
121 12/31/2013 21:58 2013-12-31 21:58:00 1.829583 -0.003400000  1.829583
123 12/31/2013 21:56 2013-12-31 21:56:00 2.494750 -0.003350000  2.494750
125 12/31/2013 21:54 2013-12-31 21:54:00 2.008283 -0.003566667  2.008283
127 12/31/2013 21:52 2013-12-31 21:52:00 2.011867 -0.003583333  2.011867
129 12/31/2013 21:50 2013-12-31 21:50:00 2.096550 -0.003850000  2.096550

对于我的数据,我实际上将执行 5 和 15 分钟的间隔。但是如果我对上面的数据和 2 分钟的时间间隔有一个好的解决方案,我应该能够适当地调整代码以满足我的需要。

【问题讨论】:

不清楚您要做什么,为什么它与时间相关,或者为什么Data[c(FALSE,TRUE),] 不起作用。 我想根据时间间隔过滤我的数据。在我上面提供的示例数据中,我只想每 2 分钟进行一次观察 - 不是每两分钟计算一次任何函数,只是在时间间隔内对观察进行子集化。这有帮助吗? 简单的子集规则,结合正则表达式,在这里可能就足够了。例如。对于 data.frame d: d[grep('[02468]$', d$time), ]。该模式匹配任何以 0、2、4、6 或 8 结尾的字符串(时间)。 【参考方案1】:

使用cutplyr::ddply

groups <- cut(as.POSIXct(df$datetime), breaks="2 min")
library(plyr)
ddply(df, "groups", tail, 1)[, -1]
#         date  time            datetime use..kW.     gen..kW. Grid..kW.
# 1 12/31/2013 21:50 2013-12-31 21:50:00 2.096550 -0.003850000  2.096550
# 2 12/31/2013 21:52 2013-12-31 21:52:00 2.011867 -0.003583333  2.011867
# 3 12/31/2013 21:54 2013-12-31 21:54:00 2.008283 -0.003566667  2.008283
# 4 12/31/2013 21:56 2013-12-31 21:56:00 2.494750 -0.003350000  2.494750
# 5 12/31/2013 21:58 2013-12-31 21:58:00 1.829583 -0.003400000  1.829583

或者

arrange(ddply(df, "groups", tail, 1)[, -1], datetime, decreasing=TRUE)

如果你想反过来排序。

【讨论】:

谢谢@lukeA!这似乎接近我所需要的。但是,当我调用 ddply() 时,它会用 NA 填充前两行(21:50 和 21:52)。你知道它为什么这样做吗?你也可以告诉我你的 ddply 函数的语法吗? NVM,问题是我的 df 只有六行(原始数据的头部)。代码现在适用于这个小例子。我正在使用包含 299,466 个观察值的原始数据框对其进行测试,这需要一段时间……您还能指导我了解 ddply 函数的语法吗? @stokeinfo 首先,ddplydf 拆分为groups 的子数据帧,其中包含每个观察的时间间隔。然后ddply 将参数为1 的tail 函数应用于每个子数据帧。这仅返回每个的最后一行。之后,ddply 将结果绑定在一起并返回一个数据框。 groups 将是第一列,[, -1] 将其排除在外。不知道这是否真的是你需要的,但这是一个尝试。 感谢@lukeA 的解释。它工作得很好。多亏了你,我才能将我的数据从 478,000 行(分钟级观察)减少到只有 20,899 行(15 分钟间隔)。这将使我的分析更快。为了速度,使用正则表达式对像 jbaums 所暗示的那样子集可能会更快,但我想学习一个使用 POSIXct 格式的解决方案 - 所以非常感谢您的回答。谢谢! @stokeinfo 很高兴它有效。 PS:plyr的作者最近发布了dplyr,速度快多了。也许你也想看看:blog.rstudio.org/2014/01/30/dplyr-0-1-1。

以上是关于将时间序列数据子集到定义的间隔中的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearches Timelion是Kibana中时间序列的可视化工具

熊猫将时间间隔重叠到时间序列

数组中时间戳之间的平均间隔

R中时间序列数据的拆分应用聚合

将时间序列数据拆分为时间间隔(比如一小时),然后绘制计数

将时间序列数据拆分为时间间隔(比如一小时),然后绘制计数