0

您好,我有按以下示例组织的数据框。我有一个时间戳、一个分组变量和几个带有每个时间戳的数值的变量。

# dput of subset of data
structure(list(TIMESTAMP = structure(1:15, .Label = c("1/1/2012 11:00", 
"1/1/2012 12:00", "1/1/2012 13:00", "1/1/2012 14:00", "1/1/2012 15:00", 
"1/2/2012 11:00", "1/2/2012 12:00", "1/2/2012 13:00", "1/2/2012 14:00", 
"1/2/2012 15:00", "4/7/2012 11:00", "4/7/2012 12:00", "4/7/2012 13:00", 
"4/7/2012 14:00", "4/7/2012 15:00"), class = "factor"), P = c(992.4, 
992.4, 992.4, 992.4, 992.4, 992.4, 992.4, 992.4, 992.4, 992.4, 
239, 239, 239, 239, 239), WS = c(4.023, 3.576, 4.023, 6.259, 
4.47, 3.576, 3.576, 2.682, 4.023, 3.576, 2.682, 3.129, 2.682, 
2.235, 2.682), WD = c(212L, 200L, 215L, 213L, 204L, 304L, 276L, 
273L, 307L, 270L, 54L, 24L, 304L, 320L, 321L), AT = c(16.11, 
18.89, 20, 20, 19.44, 10.56, 11.11, 11.67, 12.22, 11.11, 17.22, 
18.33, 19.44, 20.56, 21.11), FT = c(17.22, 22.22, 22.78, 22.78, 
20, 11.11, 15.56, 17.22, 17.78, 15.56, 24.44, 25.56, 29.44, 30.56, 
29.44), H = c(50L, 38L, 38L, 39L, 48L, 24L, 19L, 18L, 16L, 18L, 
23L, 20L, 18L, 17L, 15L), B = c(1029L, 1027L, 1026L, 1024L, 1023L, 
1026L, 1025L, 1024L, 1023L, 1023L, 1034L, 1033L, 1032L, 1031L, 
1030L), FM = c(14.9, 14.4, 14, 13.7, 13.6, 13.1, 12.8, 12.3, 
12, 11.7, 12.8, 12, 11.4, 10.9, 10.4), GD = c(204L, 220L, 227L, 
222L, 216L, 338L, 311L, 326L, 310L, 273L, 62L, 13L, 312L, 272L, 
281L), MG = c(8.047, 9.835, 10.28, 13.41, 11.18, 9.388, 8.941, 
8.494, 9.835, 10.73, 6.706, 7.153, 8.047, 8.047, 7.6), SR = c(522L, 
603L, 604L, 526L, 248L, 569L, 653L, 671L, 616L, 487L, 972L, 1053L, 
1061L, 1002L, 865L), WS2 = c(2.235, 3.576, 4.47, 4.47, 5.364, 
4.023, 2.682, 3.576, 3.576, 4.023, 3.129, 3.129, 3.576, 2.682, 
3.129), WD2 = c(200L, 201L, 206L, 210L, 211L, 319L, 315L, 311L, 
302L, 290L, 49L, 39L, 15L, 348L, 329L)), .Names = c("TIMESTAMP", 
"P", "WS", "WD", "AT", "FT", "H", "B", "FM", "GD", "MG", "SR", 
"WS2", "WD2"), class = "data.frame", row.names = c(NA, -15L))

我正在尝试找出处理时间戳以供将来操作的最佳方法。我已经阅读过lubridate(例如这里zooPOSIXt. 但是,我觉得可能存在一些我不知道的 r/timestamp技巧,这会使使用时间戳更容易(即我可能不完全理解时间戳)。

最终,我想做一些事情来创建一个新的数据框,该数据框由某个日期或时间范围内所有这些值的平均值组成。例如,每天 12:00 到 16:00 之间每个变量的平均值。

这三个软件包中的一个是否比另一个更适合执行此类任务?你能给我指出一个可以做我上面写的平均的例子或解决方案吗?或者,这些更适合计算时间(例如,某事之间的小时数、天数等​​ [例如到达和离开])还是可以用于处理其他数据帧任务的时间戳(例如平均)?

4

2 回答 2

4

我正在使用提供的示例数据更新答案。在这篇文章的末尾,旧答案仍然保持不变。

首先,您需要将数据框转换为 xts 对象。

> data.xts <- as.xts(df[,2:14], as.POSIXct(strptime(df[,1], '%m/%d/%Y %H:%S')))
> data.xts
                        P    WS  WD    AT    FT  H    B   FM  GD     MG   SR   WS2 WD2
2012-01-01 11:00:00 992.4 4.023 212 16.11 17.22 50 1029 14.9 204  8.047  522 2.235 200
2012-01-01 12:00:00 992.4 3.576 200 18.89 22.22 38 1027 14.4 220  9.835  603 3.576 201
2012-01-01 13:00:00 992.4 4.023 215 20.00 22.78 38 1026 14.0 227 10.280  604 4.470 206
2012-01-01 14:00:00 992.4 6.259 213 20.00 22.78 39 1024 13.7 222 13.410  526 4.470 210
2012-01-01 15:00:00 992.4 4.470 204 19.44 20.00 48 1023 13.6 216 11.180  248 5.364 211
2012-01-02 11:00:00 992.4 3.576 304 10.56 11.11 24 1026 13.1 338  9.388  569 4.023 319
2012-01-02 12:00:00 992.4 3.576 276 11.11 15.56 19 1025 12.8 311  8.941  653 2.682 315
2012-01-02 13:00:00 992.4 2.682 273 11.67 17.22 18 1024 12.3 326  8.494  671 3.576 311
2012-01-02 14:00:00 992.4 4.023 307 12.22 17.78 16 1023 12.0 310  9.835  616 3.576 302
2012-01-02 15:00:00 992.4 3.576 270 11.11 15.56 18 1023 11.7 273 10.730  487 4.023 290
2012-04-07 11:00:00 239.0 2.682  54 17.22 24.44 23 1034 12.8  62  6.706  972 3.129  49
2012-04-07 12:00:00 239.0 3.129  24 18.33 25.56 20 1033 12.0  13  7.153 1053 3.129  39
2012-04-07 13:00:00 239.0 2.682 304 19.44 29.44 18 1032 11.4 312  8.047 1061 3.576  15
2012-04-07 14:00:00 239.0 2.235 320 20.56 30.56 17 1031 10.9 272  8.047 1002 2.682 348
2012-04-07 15:00:00 239.0 2.682 321 21.11 29.44 15 1030 10.4 281  7.600  865 3.129 329
> data.xts['T12:00:00/T16:00:00']
                        P    WS  WD    AT    FT  H    B   FM  GD     MG   SR   WS2 WD2
2012-01-01 12:00:00 992.4 3.576 200 18.89 22.22 38 1027 14.4 220  9.835  603 3.576 201
2012-01-01 13:00:00 992.4 4.023 215 20.00 22.78 38 1026 14.0 227 10.280  604 4.470 206
2012-01-01 14:00:00 992.4 6.259 213 20.00 22.78 39 1024 13.7 222 13.410  526 4.470 210
2012-01-01 15:00:00 992.4 4.470 204 19.44 20.00 48 1023 13.6 216 11.180  248 5.364 211
2012-01-02 12:00:00 992.4 3.576 276 11.11 15.56 19 1025 12.8 311  8.941  653 2.682 315
2012-01-02 13:00:00 992.4 2.682 273 11.67 17.22 18 1024 12.3 326  8.494  671 3.576 311
2012-01-02 14:00:00 992.4 4.023 307 12.22 17.78 16 1023 12.0 310  9.835  616 3.576 302
2012-01-02 15:00:00 992.4 3.576 270 11.11 15.56 18 1023 11.7 273 10.730  487 4.023 290
2012-04-07 12:00:00 239.0 3.129  24 18.33 25.56 20 1033 12.0  13  7.153 1053 3.129  39
2012-04-07 13:00:00 239.0 2.682 304 19.44 29.44 18 1032 11.4 312  8.047 1061 3.576  15
2012-04-07 14:00:00 239.0 2.235 320 20.56 30.56 17 1031 10.9 272  8.047 1002 2.682 348
2012-04-07 15:00:00 239.0 2.682 321 21.11 29.44 15 1030 10.4 281  7.600  865 3.129 329

现在您可以period.apply按照下面的旧答案所示使用。

旧答案

为此,您可以考虑使用“xts”包。

我将按照您的要求为您提供简短的示例。

假设您有如下 xts 格式的时间序列

> head(EURUSD);tail(EURUSD)
                       Open    High     Low   Close
2009-05-01 00:10:00 1.32436 1.32600 1.32436 1.32587
2009-05-01 00:20:00 1.32589 1.32597 1.32430 1.32431
2009-05-01 00:30:00 1.32441 1.32543 1.32432 1.32479
2009-05-01 00:40:00 1.32484 1.32554 1.32482 1.32543
2009-05-01 00:50:00 1.32551 1.32610 1.32532 1.32538
2009-05-01 01:00:00 1.32538 1.32618 1.32462 1.32462
                       Open    High     Low   Close
2009-05-31 23:10:00 1.41175 1.41281 1.41129 1.41262
2009-05-31 23:20:00 1.41258 1.41259 1.41205 1.41215
2009-05-31 23:30:00 1.41206 1.41210 1.41128 1.41132
2009-05-31 23:40:00 1.41132 1.41147 1.41062 1.41093
2009-05-31 23:50:00 1.41102 1.41102 1.41032 1.41077
2009-06-01 00:00:00 1.41077 1.41099 1.41002 1.41052

然后您可以按时间索引过滤数据,如下所示

> EURUSDfiltered <- EURUSD['T12:00:00/T16:00:00']

> tail(EURUSDfiltered,60)
                       Open    High     Low   Close
2009-05-27 14:30:00 1.39063 1.39121 1.38873 1.39094
2009-05-27 14:40:00 1.39098 1.39120 1.38863 1.39075
2009-05-27 14:50:00 1.39079 1.39107 1.38935 1.39020
2009-05-27 15:00:00 1.39016 1.39343 1.38986 1.39286
2009-05-27 15:10:00 1.39286 1.39293 1.38711 1.38898
2009-05-27 15:20:00 1.38898 1.38961 1.38744 1.38824
2009-05-27 15:30:00 1.38824 1.39157 1.38814 1.39148
2009-05-27 15:40:00 1.39145 1.39281 1.39064 1.39248
2009-05-27 15:50:00 1.39245 1.39276 1.39123 1.39143
2009-05-27 16:00:00 1.39145 1.39251 1.39140 1.39231
2009-05-28 12:00:00 1.38708 1.38715 1.38524 1.38565
2009-05-28 12:10:00 1.38563 1.38633 1.38540 1.38594
2009-05-28 12:20:00 1.38596 1.38750 1.38528 1.38691
2009-05-28 12:30:00 1.38691 1.38754 1.38646 1.38710
2009-05-28 12:40:00 1.38721 1.38976 1.38668 1.38910
2009-05-28 12:50:00 1.38913 1.38962 1.38761 1.38775
2009-05-28 13:00:00 1.38777 1.38811 1.38629 1.38680
....
2009-05-28 15:30:00 1.39660 1.39691 1.39584 1.39643
2009-05-28 15:40:00 1.39646 1.39802 1.39616 1.39643
2009-05-28 15:50:00 1.39643 1.39704 1.39574 1.39668
2009-05-28 16:00:00 1.39666 1.39684 1.39423 1.39467
2009-05-29 12:00:00 1.41076 1.41076 1.40890 1.40967
2009-05-29 12:10:00 1.40965 1.41010 1.40870 1.40874
2009-05-29 12:20:00 1.40874 1.41062 1.40870 1.41010
2009-05-29 12:30:00 1.41008 1.41013 1.40844 1.40940
2009-05-29 12:40:00 1.40933 1.41140 1.40886 1.40985
2009-05-29 12:50:00 1.40985 1.41075 1.40887 1.41073
....

过滤数据后,您可以使用以下方法计算某些聚合preiod.apply函数endpoints

> ep <- endpoints(EURUSDfiltered, on='days')
> aggValues <- period.apply(EURUSDfiltered, INDEX=ep, FUN=mean)
> aggValues
                        Open     High      Low    Close
2009-05-01 16:00:00 1.326569 1.327338 1.325839 1.326445
2009-05-04 16:00:00 1.329267 1.330415 1.328654 1.329759
2009-05-05 16:00:00 1.338648 1.339428 1.337636 1.338623
2009-05-06 16:00:00 1.331870 1.332957 1.330978 1.331909
2009-05-07 16:00:00 1.339542 1.341126 1.337957 1.339760
2009-05-08 16:00:00 1.347692 1.348982 1.346786 1.347995
2009-05-11 16:00:00 1.359852 1.360683 1.359177 1.359987
2009-05-12 16:00:00 1.365657 1.366473 1.364534 1.365473
2009-05-13 16:00:00 1.360978 1.361865 1.359939 1.360888
2009-05-14 16:00:00 1.358187 1.359207 1.357512 1.358386
2009-05-15 16:00:00 1.356786 1.357672 1.355668 1.356690
2009-05-18 16:00:00 1.349660 1.350412 1.349085 1.349679
2009-05-19 16:00:00 1.360091 1.360750 1.359121 1.360065
2009-05-20 16:00:00 1.373703 1.374888 1.373062 1.373990
2009-05-22 16:00:00 1.399224 1.400354 1.398262 1.399429
2009-05-25 16:00:00 1.399991 1.400309 1.399607 1.399976
2009-05-26 16:00:00 1.393970 1.395064 1.393425 1.394333
2009-05-27 16:00:00 1.392505 1.393589 1.391215 1.392552
2009-05-28 16:00:00 1.391658 1.392870 1.390735 1.391952
2009-05-29 16:00:00 1.411398 1.412516 1.410404 1.411468

更新:回应下面的评论

进一步研究?.subset.xts表明,When a raw character vector is used for the i subset argument, it is processed as if it was ISO-8601 compliant. http ://en.wikipedia.org/wiki/ISO_8601提到T前缀用于指定时间

于 2013-01-24T16:45:34.407 回答
1

我认为可能对您最有帮助的过程是将 [TIMESTAMP] 数据变异为分组变量。然后,我建议使用众多数据汇总包之一来创建报告。我个人的偏好是对这两个任务都使用“plyr”包,我在这个例子中使用了它。

第 1 步:使用“as.POSIXct”函数将时间戳数据转换为 POSIX 日期时间,以便与各种日期时间函数一起使用。不使用任何参数,无需任何调整即可简单地转换数据。

data$TIMESTAMP <- as.POSIXct(data$TIMESTAMP)

更新:由于时间不是明确的降序格式(即 YYYY/MM/DD HH:MM:SS),'as.POSIXct' 函数将无法快速转换数据. 仅当您使用明确的格式时才使用“as.POSIXct”。对于其他安排,使用“strptime”函数,指定当前格式,如下所示:

data$TIMESTAMP <- strptime(data$TIMESTAMP, "%m/%d/%Y %H:%M")

这告诉 'strptime' 函数当前正在使用什么格式,并导出与 POSIX 兼容的日期时间。除非您当前的数据不是字符串,否则不需要使用“as.character”函数。

第 2 步:使用“plyr”函数“ddply”(获取数据帧并返回数据帧)创建一个用于分组的新变量。使用“格式”函数从 TIMESTAMP 值中提取所需的数据。查看可用格式的“格式”文档。在这种情况下,以下是创建 [MONTH] 变量的方法:

library(plyr)
data <- ddply(data, .(TIMESTAMP), mutate, MONTH=format(TIMESTAMP, "%m")

第 3 步:使用“plyr”函数“ddply”按新变量汇总数据。

ddply(data, .(MONTH), summarize, V1_AVG=mean(V2), V2_AVG=mean(V2))

如果您还想通过第二个变量(如 [GROUP])进行汇总,只需将其包含在第二个函数变量中,如下所示:

ddply(data, .(MONTH, GROUP), summarize, V1_AVG=mean(V2), V2_AVG=mean(V2))

从技术上讲,你可以在一个声明中做到这一切,但经验告诉我要谨慎。我建议自己做每一步,以确保没有任何事情搞砸。

只要您的时间戳已转换为 POSIX 日期时间,您就可以通过像这样摆弄来解析您的数据。'plyr' 包对于这样的东西非常灵活。

更新:根据 OP 的要求,我包括您将如何进行相同的计算,但仅使用 12p 和 4p 之间的数据。您实际上不必像这样使用任何特定的包来对您的数据进行子集化,因为它是一个直接的数据过滤器。只需更改输入到“ddply”函数中的数据集,如下所示:

# Use one of the following lines, which both do the same thing.
# I'm just including both as different examples of logic that can be used.
data_Subset <- data[format(data$TIMESTAMP, "%H") >= 12 & format(data$TIMESTAMP, "%H") < 16,]
data_Subset <- data[format(data$TIMESTAMP, "%H") %in% 12:15,]

# Then summarize using the new data frame as an input
ddply(data_Subset, .(MONTH, GROUP), summarize, V1_AVG=mean(V2), V2_AVG=mean(V2))

在这里,我们过滤数据框以仅显示小时 (%H) 等于 12 到 15 的行(包含所有列)。这实际上包括从 12:00 到 15:59 的所有时间。如果您开始进入非常大的数据集,您可能需要寻找其他解决方案(例如“data.table”包),但除此之外,这是您最快的选择。

同样,这仅适用,因为我们已将日期时间转换为与 POSIX 兼容的日期时间。

于 2013-01-24T17:06:51.103 回答