我有一个类似以下的数据集:
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)。我知道我可以将
shift
与data.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已询问
V1
,V2
和V3
来自何处。表达式
.(urn, date, date %m-% months(12))
可以动态创建一个新的data.table。 (.()
是data.table
的list()
缩写)。由于未指定任何列名,因此data.table
会创建默认的列名V1
,V2
等。不太草率地,可以使用显式命名的列重写表达式
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/