R data.table使用日期的组子集的总和

标签 r data.table

我有一个类似以下的数据集:

library(data.table)    
dt1 <- data.table(urn = c(rep("a", 5), rep("b", 4)),
                  amount = c(10, 12, 23, 15, 19, 42, 11, 5, 10),
                  date = as.Date(c("2016-01-01", "2017-01-02", "2017-02-04",
                                   "2017-04-19", "2018-02-11", "2016-02-14",
                                   "2017-05-06", "2017-05-12", "2017-12-12")))
dt1
#    urn amount       date
# 1:   a     10 2016-01-01
# 2:   a     12 2017-01-02
# 3:   a     23 2017-02-04
# 4:   a     15 2017-04-19
# 5:   a     19 2018-02-11
# 6:   b     42 2016-02-14
# 7:   b     11 2017-05-06
# 8:   b      5 2017-05-12
# 9:   b     10 2017-12-12

我正在尝试确定一个组在过去12个月中的累计值(value)。我知道我可以将shiftdata.table一起使用来向后或向前扫描,我无法理解的最大挑战是如何根据每个urn拥有的记录数来更改数量可以改变的记录总数。

我要寻找的结果类型是:
dt1
#    urn amount       date summed12m
# 1:   a     10 2016-01-01        10
# 2:   a     12 2017-01-02        12
# 3:   a     23 2017-02-04        35
# 4:   a     15 2017-04-19        50
# 5:   a     19 2018-02-11        34
# 6:   b     42 2016-02-14        42
# 7:   b     11 2017-05-06        11
# 8:   b      5 2017-05-12        16
# 9:   b     10 2017-12-12        26   

由于数据量大,我最好在寻找一种data.table解决方案,但是如果它在大约有1200万条记录的表上可能比较有效,那么我也愿意接受其他选择。

最佳答案

作为foverlaps()的替代方法,这也可以通过聚合非等额联接来解决:

library(lubridate)
dt1[, summed12m := dt1[.(urn, date, date %m-% months(12)), 
                       on = .(urn = V1, date <= V2, date >= V3), 
                       sum(amount), by = .EACHI]$V1][]
   urn amount       date summed12m
1:   a     10 2016-01-01        10
2:   a     12 2017-01-02        12
3:   a     23 2017-02-04        35
4:   a     15 2017-04-19        50
5:   a     19 2018-02-11        34
6:   b     42 2016-02-14        42
7:   b     11 2017-05-06        11
8:   b      5 2017-05-12        16
9:   b     10 2017-12-12        26
lubridate用于日期算术,以防万一其中一个日期是2月29日,导致事故发生。
必不可少的部分是非等额联接
dt1[.(urn, date, date %m-% months(12)), 
    on = .(urn = V1, date <= V2, date >= V3), 
    sum(amount), by = .EACHI]
   urn       date       date V1
1:   a 2016-01-01 2015-01-01 10
2:   a 2017-01-02 2016-01-02 12
3:   a 2017-02-04 2016-02-04 35
4:   a 2017-04-19 2016-04-19 50
5:   a 2018-02-11 2017-02-11 34
6:   b 2016-02-14 2015-02-14 42
7:   b 2017-05-06 2016-05-06 11
8:   b 2017-05-12 2016-05-12 16
9:   b 2017-12-12 2016-12-12 26

选择最后一列以在summed12m中创建新的dt1列。
补充说明
OP已询问V1V2V3来自何处。
表达式.(urn, date, date %m-% months(12))可以动态创建一个新的data.table。 (.()data.tablelist()缩写)。由于未指定任何列名,因此data.table会创建默认的列名V1V2等。
不太草率地,可以使用显式命名的列重写表达式
dt1[.(urn = urn, end = date, start = date %m-% months(12)), 
    on = .(urn, date <= end, date >= start), 
    sum(amount), by = .EACHI]

关于R data.table使用日期的组子集的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48779667/

相关文章:

r - 如何在给定特定行顺序的情况下对 R data.table 中的行重新排序

r - 使用变量指定 `data.table` 范围内的列名

r - Azure Notebooks 中插入符号包安装失败且退出状态为非零

r - 转换 data.table 中的一组列

r - R中的多核和data.table

r - 为什么添加新列后 data.table 的列名会发生变化?

r - 使用 lapply 拟合多个模型——如何在 lm 对象中保持模型公式自包含

RODBC 命令 'sqlQuery' 在 t-SQL 中存在表变量问题

r - R : Legend size and creating a square plot 中的 pheatmap 格式

r - R Leaflet 标记弹出窗口中的图像