将时间序列数据子集到定义的间隔中
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】:
使用cut
和plyr::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 首先,ddply
将df
拆分为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。以上是关于将时间序列数据子集到定义的间隔中的主要内容,如果未能解决你的问题,请参考以下文章