优化切片和计算的 data.table 代码
Optimising data.table code for slicing and computation
这里有一个小例子来说明我的任务。我有一个大数据集,假设数据 table dt,包含日期列、到期日(到期日)和价格 X(例如到期日的交货价格)。
date exdate X
1999-01-01 1999-02-01 100
1999-01-01 1999-01-17 50
1999-01-01 1999-05-01 75
1999-01-02 1999-01-17 60
1999-01-02 1999-04-02 50
... ... ...
等等。
我现在要进行某些分析:
- 对于每个日期和每个日期,我想将函数应用于与日期相对应的所有价格 比当前日期大。 (例如,检查价格是否更高:
sapply(dt[date==date[1] & exdate > exdate[1],X],function(x) x>dt[date==date[1] & exdate = exdate[1],X])
- 与 1. 相同,但现在采用相同的日期并查找对应于价格大于当前价格的所有产品并再次应用某些公式。
我已经尝试过将 data.table 方法与 1 中所示的组合进行切片,并在每一列上迭代一个嵌套的 for 循环。不用说,这需要相当长的时间。
我的下一个想法是使用多维数组同时执行分析,但我无法让它工作。
我最后的尝试是探索 data.tables .SD 和 .GRP 选项,但这种方法也没有取得成果,尽管我认为我只是在这里遗漏了一些东西,这可能是一个选项。
我在这个论坛上阅读了很多关于切片和优化的内容,但考虑到我应用的公式并不简单(例如 mean/sum/average 可以考虑),我无法应用给定的解决方案。
因此,如果有人曾经处理过这样的 problem/task 或者知道这件事,我将非常感谢我能得到的任何帮助!
谢谢!
关于第一个问题,可以使用data.table
的非相等自连接:
来解决
library(data.table) # CRAN version 1.10.4 used
# coerce to data.table and order data for later comparisons
setorder(setDT(DT), date, exdate, X)
# non-equi self-join
DT[DT, on = c("date", "exdate>=exdate"),
# aggregate
.(min.X = min(X), min.exdate = x.exdate[which.min(X)], n.lt.1st = sum(X < first(X)),
max.X = max(X), max.exdate = x.exdate[which.max(X)], n.gt.1st = sum(X > first(X))),
# for each join group
by = .EACHI]
date exdate min.X min.exdate n.lt.1st max.X max.exdate n.gt.1st
1: 1999-01-01 1999-01-17 50 1999-01-17 0 100 1999-02-01 2
2: 1999-01-01 1999-02-01 75 1999-05-01 1 100 1999-02-01 0
3: 1999-01-01 1999-05-01 75 1999-05-01 0 75 1999-05-01 0
4: 1999-01-02 1999-01-17 50 1999-04-02 1 60 1999-01-17 0
5: 1999-01-02 1999-04-02 50 1999-04-02 0 50 1999-04-02 0
聚合只是例子,显示最小值,最小值的exdate
,小于第一个值的数值,最大对应相同。
注意条件是exdate>=exdate
,不是exdate>exdate
。这是为了在结果集中包含“参考行”以便与其进行比较,即 X < first(X)
.
第二个问题,不清楚product指的是什么
数据
library(data.table)
DT <- fread(
"date exdate X
1999-01-01 1999-02-01 100
1999-01-01 1999-01-17 50
1999-01-01 1999-05-01 75
1999-01-02 1999-01-17 60
1999-01-02 1999-04-02 50"
)
cols <- c("date", "exdate")
DT[, (cols) := lapply(.SD, as.IDate), .SDcols = cols]
str(DT)
Classes ‘data.table’ and 'data.frame': 5 obs. of 4 variables:
$ date : IDate, format: "1999-01-01" "1999-01-01" "1999-01-01" "1999-01-02" ...
$ exdate : IDate, format: "1999-01-17" "1999-02-01" "1999-05-01" "1999-01-17" ...
$ X : int 50 100 75 60 50
$ refdate: IDate, format: "1999-01-17" "1999-02-01" "1999-05-01" "1999-01-17" ...
- attr(*, ".internal.selfref")=<externalptr>
注意 datatable
自己的日期 class IDate
使用整数存储。
这里有一个小例子来说明我的任务。我有一个大数据集,假设数据 table dt,包含日期列、到期日(到期日)和价格 X(例如到期日的交货价格)。
date exdate X
1999-01-01 1999-02-01 100
1999-01-01 1999-01-17 50
1999-01-01 1999-05-01 75
1999-01-02 1999-01-17 60
1999-01-02 1999-04-02 50
... ... ...
等等。 我现在要进行某些分析:
- 对于每个日期和每个日期,我想将函数应用于与日期相对应的所有价格 比当前日期大。 (例如,检查价格是否更高:
sapply(dt[date==date[1] & exdate > exdate[1],X],function(x) x>dt[date==date[1] & exdate = exdate[1],X])
- 与 1. 相同,但现在采用相同的日期并查找对应于价格大于当前价格的所有产品并再次应用某些公式。
我已经尝试过将 data.table 方法与 1 中所示的组合进行切片,并在每一列上迭代一个嵌套的 for 循环。不用说,这需要相当长的时间。
我的下一个想法是使用多维数组同时执行分析,但我无法让它工作。
我最后的尝试是探索 data.tables .SD 和 .GRP 选项,但这种方法也没有取得成果,尽管我认为我只是在这里遗漏了一些东西,这可能是一个选项。
我在这个论坛上阅读了很多关于切片和优化的内容,但考虑到我应用的公式并不简单(例如 mean/sum/average 可以考虑),我无法应用给定的解决方案。
因此,如果有人曾经处理过这样的 problem/task 或者知道这件事,我将非常感谢我能得到的任何帮助!
谢谢!
关于第一个问题,可以使用data.table
的非相等自连接:
library(data.table) # CRAN version 1.10.4 used
# coerce to data.table and order data for later comparisons
setorder(setDT(DT), date, exdate, X)
# non-equi self-join
DT[DT, on = c("date", "exdate>=exdate"),
# aggregate
.(min.X = min(X), min.exdate = x.exdate[which.min(X)], n.lt.1st = sum(X < first(X)),
max.X = max(X), max.exdate = x.exdate[which.max(X)], n.gt.1st = sum(X > first(X))),
# for each join group
by = .EACHI]
date exdate min.X min.exdate n.lt.1st max.X max.exdate n.gt.1st 1: 1999-01-01 1999-01-17 50 1999-01-17 0 100 1999-02-01 2 2: 1999-01-01 1999-02-01 75 1999-05-01 1 100 1999-02-01 0 3: 1999-01-01 1999-05-01 75 1999-05-01 0 75 1999-05-01 0 4: 1999-01-02 1999-01-17 50 1999-04-02 1 60 1999-01-17 0 5: 1999-01-02 1999-04-02 50 1999-04-02 0 50 1999-04-02 0
聚合只是例子,显示最小值,最小值的exdate
,小于第一个值的数值,最大对应相同。
注意条件是exdate>=exdate
,不是exdate>exdate
。这是为了在结果集中包含“参考行”以便与其进行比较,即 X < first(X)
.
第二个问题,不清楚product指的是什么
数据
library(data.table)
DT <- fread(
"date exdate X
1999-01-01 1999-02-01 100
1999-01-01 1999-01-17 50
1999-01-01 1999-05-01 75
1999-01-02 1999-01-17 60
1999-01-02 1999-04-02 50"
)
cols <- c("date", "exdate")
DT[, (cols) := lapply(.SD, as.IDate), .SDcols = cols]
str(DT)
Classes ‘data.table’ and 'data.frame': 5 obs. of 4 variables: $ date : IDate, format: "1999-01-01" "1999-01-01" "1999-01-01" "1999-01-02" ... $ exdate : IDate, format: "1999-01-17" "1999-02-01" "1999-05-01" "1999-01-17" ... $ X : int 50 100 75 60 50 $ refdate: IDate, format: "1999-01-17" "1999-02-01" "1999-05-01" "1999-01-17" ... - attr(*, ".internal.selfref")=<externalptr>
注意 datatable
自己的日期 class IDate
使用整数存储。