r - 在带时间戳的事务的 data.table 中使用 zoo 的 rollsum

标签 r data.table zoo

this questionthis one 有点相关,我无法计算滚动总和。与这些问题不同的是,我想尝试使用 zoo:rollsum 类似于 rollapply 答案 here 。 (但如果有更多 data.table 的方法来做到这一点,无论如何。)

让我们从一些数据开始:

set.seed(123)
some_dates <- function(){as.Date('1980-01-01') + sort(sample.int(1e4,100))}
d <- data.table(cust_id = c(rep(123,100),rep(456,100)),
                purch_dt = c(some_dates(), some_dates()),
                purch_amt = round(runif(200, 1, 100),2) )

head(d)
#    cust_id   purch_dt purch_amt
# 1:     123 1980-01-08     24.63
# 2:     123 1980-09-03     96.27
# 3:     123 1981-02-24     60.54

我想为每个客户做一个滚动的 365 天购买金额,在每个交易日计算。

答案 here 建议采用以下方法:

首先,使用交叉连接为所有客户日期对创建虚拟行,即:
setkey(d, cust_id, purch_dt)
dummy <- d[ CJ(unique(cust_id), seq(min(purch_dt), max(purch_dt), by='day') ) ]
#    cust_id   purch_dt purch_amt
# 1:     123 1980-01-08     24.63
# 2:     123 1980-01-09        NA
# 3:     123 1980-01-10        NA

到目前为止,一切都很好(尽管我确信有一种方法可以将这个虚拟表收紧到客户级别的 min/max purch_dt)。

我的问题是如何使用 rollsumr 来计算尾随 365 天的总和。

我试过:
dummy[, purch_365 := rollsumr(x=purch_amt, k=365, na.rm=TRUE) , by=cust_id]

但这会像所有 purch_365 一样创建 NA 并给出两个警告,例如:
Warning messages:
1: In `[.data.table`(dummy, , `:=`(purch_365, rollsumr(x = purch_amt,  :
  Supplied 9550 items to be assigned to group 1 of size 9914 in column 'purch_365' (recycled leaving remainder of 364 items).

我得到 364 = k-1,以及 2 个 cust_id 的 2 个警告。除此之外我一无所获。
# Desired output:
#    cust_id   purch_dt purch_amt purch_365
# 1:     123 1980-01-08     24.63     24.63
# 2:     123 1980-09-03     96.27    120.90
# 3:     123 1981-02-24     60.54    156.81

提前致谢!

最佳答案

这是一种方法。首先,添加一个包含您关心的最后日期的列,以及一个用于跟踪事物的索引:

d[, old.date := purch_dt - 365]
d[, idx := .I]

然后在该日期进行滚动连接(假设版本为 1.9.5+),并提取每个匹配项的索引范围(即通过 .EACHI ):
res = d[d, .(idx = i.idx, seq = idx:i.idx), by = .EACHI, roll = -Inf,
        on = c(cust_id = 'cust_id', purch_dt = 'old.date')]

最后,对原始 data.table 进行适当范围的子集化,并计算总和:
d[, purch_365 := d[res$seq, sum(purch_amt), by = res$idx]$V1][]
#     cust_id   purch_dt purch_amt idx   old.date purch_365
#  1:     123 1980-01-08     24.63   1 1979-01-08     24.63
#  2:     123 1980-09-03     96.27   2 1979-09-04    120.90
#  3:     123 1981-02-24     60.54   3 1980-02-25    156.81
#  4:     123 1981-04-01     51.99   4 1980-04-01    208.80
#  5:     123 1981-04-02     40.85   5 1980-04-02    249.65
# ---                                                      
#196:     456 2006-01-29     24.72 196 2005-01-29    187.81
#197:     456 2006-02-15     27.78 197 2005-02-15    215.59
#198:     456 2006-09-22     11.00 198 2005-09-22     74.94
#199:     456 2006-09-27     12.67 199 2005-09-27     87.61
#200:     456 2006-11-18     99.13 200 2005-11-18    186.74

关于r - 在带时间戳的事务的 data.table 中使用 zoo 的 rollsum,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32618803/

相关文章:

r - 在 R heatmap() 函数中增加行高

r - data.table v.1.11.0+ 不再读取由 v.1.10.4-3 读取的数据文件

R 四舍五入时间

r - 在对某些值进行操作时通过重叠的时间段进行连接

r - 仅将时间序列中的 NA 填充到有限数量

r - 如何分析 R 中的不规则时间序列

r - 如何删除每个多面图上 geom_text 生成的重复标​​签?

java - 在 R studio 中更改 Java 版本

r - Shiny 和 ggplot - 使小组变得 react 困难

r - 从返回多个输出的函数创建聚合输出 data.table