根据输入数据的结构和预期结果,OP 有多种选择。
从问题和示例数据集来看,如果输入数据包含间隙(即没有记录数据的时间间隔超过 15 分钟),预期结果应该是什么样子并不完全清楚. OP 希望输入数据中的差距如何反映在结果中?
编辑: OP 提供了两个略有不同的数据集。下面使用两者来演示输入数据对结果的影响。
以下变体将使用lubridate 和data.table。假设df已经被Timesstamp订购。
准备
这是所有变体都需要的:
library(lubridate)
library(data.table)
setDT(df)[, Timestamp := mdy_hms(Timestamp)]
聚合到下一个 15 分钟间隔(结果有间隙)
最简单的解决方案是聚合到下一个 15 分钟间隔:
df[, .SD[.N], by = .(Interval = ceiling_date(Timestamp, "15 min"))]
Interval Value..kW.
1: 2018-08-12 23:00:00 51
2: 2018-08-13 00:00:00 52
3: 2018-08-13 00:15:00 55
4: 2018-08-13 00:30:00 57
5: 2018-08-13 00:45:00 60
6: 2018-08-13 01:00:00 61
7: 2018-08-13 01:15:00 62
请注意,第 1 行和第 2 行之间有 1 小时的间隔,其中缺少 3 个间隔。
为了完整起见,这里有一个变体,它也适用于无序数据。
df[, .SD[which.max(Timestamp)], keyby = .(Interval = ceiling_date(Timestamp, "15 min"))]
编辑:我们得到另一个数据集(没有截断秒数)
df0[, .SD[.N], by = .(Interval = ceiling_date(Timestamp, "15 min"))]
1: 2018-08-12 23:15:00 51
2: 2018-08-13 00:15:00 55
3: 2018-08-13 00:30:00 57
4: 2018-08-13 00:45:00 60
5: 2018-08-13 01:00:00 61
6: 2018-08-13 01:15:00 62
请注意,在没有截断秒数的情况下,这些值将移动到下一个间隔。
汇总到下一个 15 分钟间隔,结果中没有间隙
step <- "15 min"
df[, .SD[.N], by = .(Interval = ceiling_date(Timestamp, step))][
.(seq(min(Interval), max(Interval), step)), on = .(Interval = V1)]
这里我们加入一系列时间戳来完成缺失的间隔:
Interval Value..kW.
1: 2018-08-12 23:00:00 51
2: 2018-08-12 23:15:00 NA
3: 2018-08-12 23:30:00 NA
4: 2018-08-12 23:45:00 NA
5: 2018-08-13 00:00:00 52
6: 2018-08-13 00:15:00 55
7: 2018-08-13 00:30:00 57
8: 2018-08-13 00:45:00 60
9: 2018-08-13 01:00:00 61
10: 2018-08-13 01:15:00 62
现在,NA 值可以在结果中看到差距。
编辑:我们得到另一个数据集(没有截断秒数)
df0[, .SD[.N], by = .(Interval = ceiling_date(Timestamp, step))][
.(seq(min(Interval), max(Interval), step)), on = .(Interval = V1)]
Interval Value..kW.
1: 2018-08-12 23:15:00 51
2: 2018-08-12 23:30:00 NA
3: 2018-08-12 23:45:00 NA
4: 2018-08-13 00:00:00 NA
5: 2018-08-13 00:15:00 55
6: 2018-08-13 00:30:00 57
7: 2018-08-13 00:45:00 60
8: 2018-08-13 01:00:00 61
9: 2018-08-13 01:15:00 62
滚动连接(结果中的数据填充间隙)
这是Matt's approach的精简版
step = "15 min"
df[.(seq(floor_date(min(Timestamp), step), ceiling_date(max(Timestamp), step),by = step)),
on = .(Timestamp = V1), roll = TRUE]
Timestamp Value..kW.
1: 2018-08-12 23:00:00 51
2: 2018-08-12 23:15:00 51
3: 2018-08-12 23:30:00 51
4: 2018-08-12 23:45:00 51
5: 2018-08-13 00:00:00 52
6: 2018-08-13 00:15:00 55
7: 2018-08-13 00:30:00 57
8: 2018-08-13 00:45:00 60
9: 2018-08-13 01:00:00 61
10: 2018-08-13 01:15:00 62
在这里,空白填充了从最新可用值复制的数据。从结果来看,已经看不出输入数据有差距。
编辑:我们得到另一个数据集(没有截断秒数)
df0[.(seq(floor_date(min(Timestamp), step), ceiling_date(max(Timestamp), step),by = step)),
on = .(Timestamp = V1), roll = TRUE]
Timestamp Value..kW.
1: 2018-08-12 23:00:00 NA
2: 2018-08-12 23:15:00 51
3: 2018-08-12 23:30:00 51
4: 2018-08-12 23:45:00 51
5: 2018-08-13 00:00:00 51
6: 2018-08-13 00:15:00 55
7: 2018-08-13 00:30:00 57
8: 2018-08-13 00:45:00 60
9: 2018-08-13 01:00:00 61
10: 2018-08-13 01:15:00 62
在这里,我们在第一行有一个未填补的空白。这是由间隔序列的构造方式引起的。稍作修改即可避免
df0[.(seq(ceiling_date(min(Timestamp), step), ceiling_date(max(Timestamp), step),by = step)),
on = .(Timestamp = V1), roll = TRUE]
Timestamp Value..kW.
1: 2018-08-12 23:15:00 51
2: 2018-08-12 23:30:00 51
3: 2018-08-12 23:45:00 51
4: 2018-08-13 00:00:00 51
5: 2018-08-13 00:15:00 55
6: 2018-08-13 00:30:00 57
7: 2018-08-13 00:45:00 60
8: 2018-08-13 01:00:00 61
9: 2018-08-13 01:15:00 62
数据
OP 提供的数据为dput()
df <-
structure(list(Timestamp = c("8/12/2018 23:00:00", "8/13/2018 0:00:00",
"8/13/2018 0:10:00", "8/13/2018 0:14:00", "8/13/2018 0:15:00",
"8/13/2018 0:19:00", "8/13/2018 0:29:00", "8/13/2018 0:38:00",
"8/13/2018 0:44:00", "8/13/2018 0:45:00", "8/13/2018 0:58:00",
"8/13/2018 1:01:00"), Value..kW. = 51:62), .Names = c("Timestamp",
"Value..kW."), class = "data.frame", row.names = c(NA, -12L))
编辑: OP 提供了两个略有不同的数据集:
- 如
dput() 截断秒数(此答案为df)
- 在没有截断秒的问题中打印
df(此答案中为df0)
这种细微的差异会影响结果。所以,这里是打印出来的数据集:
df0 <- data.frame(
readr::read_table(" Timestamp Value.(kW)
8/12/2018 23:00:06 51
8/13/2018 0:00:16 52
8/13/2018 0:10:26 53
8/13/2018 0:14:36 54
8/13/2018 0:15:00 55
8/13/2018 0:19:57 56
8/13/2018 0:29:09 57
8/13/2018 0:38:17 58
8/13/2018 0:44:59 59
8/13/2018 0:45:00 60
8/13/2018 0:58:47 61
8/13/2018 1:01:57 62
"))
# prepare
library(lubridate)
library(data.table)
setDT(df0)[, Timestamp := mdy_hms(Timestamp)]