如何在一天中的给定时间内查找data.table中列的最大值或最小值

时间:2017-03-19 04:34:36

标签: r data.table

我有一分钟的金融时间序列(“酒吧”)。因为我将处理一些大型系列,我正在学习使用data.table,而我还不习惯以data.table方式思考。
在我导入data.table的数据中(为简单起见,我们将其称为DT),除了与此问题无关的其他内容之外,我还有一个名为Date的列YYYYMMDD格式,Time格式的HH:MM列,以及名为Price的列(假设它是该分钟的最终价格),这是一个整数。我正在简化一点,但如果有人能帮助我解决我在这里提出的问题,我可以根据我的数据细节进行调整。这是一个例子:

Date     Time  Price
20151028 09:00 47675
20151028 09:01 47650
20151028 09:02 47670
20151028 09:03 47685
20151028 09:04 47690
...

我想要做的是,每分钟计算直到那一分钟的Price的最大值和最小值。我们继续将我想要计算的内容添加为其他列,我将在此处调用DayMaxDayMin。结果将如下所示:

Date     Time  Price DayMax DayMin
20151028 09:00 47675 47675  47675
20151028 09:01 47650 47675  47650
20151028 09:02 47670 47675  47650
20151028 09:03 47685 47685  47650
20151028 09:04 47690 47690  47650
...

我很确定我的by(我理解为SQL中的GROUP BY)应该是Date,而我认为我理解的是如何理解设置我的i(就像SQL中的WHERE),主要是因为我不确定如何在语法中使用相同的列两种不同的方式。对于每一行,我想计算最大值(以及“在哪里”,我认为我的意思是WHERETime小于或等于该特定值中Time的值行,我在GROUP(ing)BY日期,所以它取决于该行在特定日期的时间。如何使用data.table以快速且符合内存的方式执行此操作? 顺便说一句,谈到“快速和内存效率”,我假设我应该使用:=运算符来创建新列。如果我错了,请纠正我。

1 个答案:

答案 0 :(得分:2)

As suggested by Frankcummin()cummax()会为您做到这一点。 (在SQL中,这在ORACLE中称为窗口函数分析函数,我相信)。

DT[order(Date, Time), `:=`(DayMax = cummax(Price), DayMin = cummin(Price)), by = Date]
DT
#       Date  Time Price DayMax DayMin
#1: 20151028 09:00 47675  47675  47675
#2: 20151028 09:01 47650  47675  47650
#3: 20151028 09:02 47670  47675  47650
#4: 20151028 09:03 47685  47685  47650
#5: 20151028 09:04 47690  47690  47650

为了确保数据的顺序正确,DTDateTime排序。如果前面的步骤确保了这一点,则可以跳过此步骤。两个新列在一个表达式中计算,根据请求分别为每个Date计算。

使用链接,可以将其重写为

res <- DT[order(Date, Time)][, DayMax := cummax(Price), by = Date][, DayMin := cummin(Price), by = Date][]

但缺点是创建DT的副本而不是DT通过引用修改,并需要额外的分组操作(感谢Frank用于指出this

数据

library(data.table)
DT <- fread ("Date     Time  Price
         20151028 09:00 47675
         20151028 09:01 47650
         20151028 09:02 47670
         20151028 09:03 47685
         20151028 09:04 47690")