R等效于通过行首进行SQL SUM OVER PARTITION的操作

The*_*ake 1 sql r data.table

我在尝试在R中复制SQL窗口函数时遇到麻烦,尤其是与创建指定我要求和的前几个月数的求和的关系。

尽管R中的sqldf包允许进行数据操作,但它似乎不支持窗口功能。

我在R中有一些模拟数据

set.seed(10)
data_1 <- data.table(Cust_ID = c(1,1,1,1,2,2,2,2,3,3,3,3),Month=c(4,3,2,1,4,3,2,1,4,3,2,1),
                          StatusCode=LETTERS[4:6],SalesValue=round(runif(12,50,1500)))

Cust_ID Month StatusCode SalesValue
   1     4          D        786
   1     3          E        495
   1     2          F        669
   1     1          D       1055
   2     4          E        173
   2     3          F        377
   2     2          D        448
   2     1          E        445
   3     4          F        943
   3     3          D        673
   3     2          E        995
   3     1          F        873
Run Code Online (Sandbox Code Playgroud)

对于每一行,我想为前两个月(不包括当月)创建与客户有关的累积值总和(Cust_ID)。

这意味着对于每个客户,第1个月和第2个月的行应为空(鉴于前两个月没有2个月),第3个月应包含该客户的第1个月和第2个月的SalesValue总和,第4个月应包含销售的总和第2个月和第3个月的价值。

在SQL中,我将使用类似于以下的语法:SUM(SalesValue)OVER(按CUST_ID排序或按月排序的行在2个PRECEDING和1个PRECEDING之间进行排序)为PAST_3Y_SALES

是否有在R中实现这一目标-理想情况下使用data.table(为了提高效率)?任何指导将不胜感激。

PS注意:这是模拟数据,在我的“真实”数据中,客户拥有不同的数据量-即某些客户拥有5个月的数据,其他客户具有> 36个月的数据,依此类推。

MKR*_*MKR 5

由于OP已使用data.table,因此使用RcppRoll::roll_sumr范围为的解决方案data.table可以是:

library(data.table)
library(RcppRoll)

# Order on 'Cust_ID' and 'Month'
setkeyv(data_1,c("Cust_ID","Month"))

data_1[, Sum_prev:=shift(roll_sumr(SalesValue, n=2)), by=Cust_ID]

data_1
#    Cust_ID Month StatusCode SalesValue Sum_prev
# 1:       1     1          D       1055       NA
# 2:       1     2          F        669       NA
# 3:       1     3          E        495     1724
# 4:       1     4          D        786     1164
# 5:       2     1          E        445       NA
# 6:       2     2          D        448       NA
# 7:       2     3          F        377      893
# 8:       2     4          E        173      825
# 9:       3     1          F        873       NA
# 10:       3     2          E        995       NA
# 11:       3     3          D        673     1868
# 12:       3     4          F        943     1668
Run Code Online (Sandbox Code Playgroud)

该方法是首先计算宽度为a的2和,然后对具有前2行之和的当前行使用data.table::shiftwith lag来使用先前的值。