需要帮助计算R中的滚动总和

问题描述 投票:1回答:1

我有一个包含4列的数据表:ID,Cat,Date和Val。我想在这个表中创建2个新列,它们具有Val的3个月和12个月的滚动总和,按ID和Cat分组。理想情况下,我想要一个data.table解决方案,因为我有一个非常大的数据集。此外,对于特定的ID / Cat组,我可能在某些月份缺少数据,因此应在计算中跳过该月份。

这将创建一个可供使用的样本数据表。

sample_data <- as.data.frame(matrix(nrow =34, ncol = 4))

colnames(sample_data) <- c("ID", "Cat", "Date", "Val")

sample_data$ID <- c("PMM", "PMM", "PMM", "PMM", "PMM", 
                    "PMM", "PMM", "PMM", "PMM", "PMM", 
                    "PMM", "PMM", "PMM", "LCG", "LCG", 
                    "LCG", "LCG", "LCG", "LCG", "LCG", 
                    "LCG", "LCG", "LCG", "LCG", "LCG", 
                    "LCG", "LCG", "LCG", "LCG", "LCG", 
                    "LCG", "LCG", "LCG", "LCG")

sample_data$Cat <- c("MM", "MM", "MM", "MM", "MM", 
                      "MM", "MM", "MM", "MM", "MM", 
                      "MM", "MM", "MM", "OE", "OE", 
                      "OE", "OE", "OE", "OE", "OE", 
                      "OE", "OE", "OE", "OE", "OE", 
                      "OE", "OE", "OE", "OE", "OE", 
                      "OE", "OE", "OE", "OE")

sample_data$Date <- c(
"2018-12-31", "2018-11-30", "2018-10-31", "2018-09-30", "2018-08-31",
"2018-07-31", "2018-06-30", "2018-05-31", "2018-04-30", "2018-03-31",
"2018-02-28", "2018-01-31", "2017-12-31", "2018-12-31", "2018-11-30",
"2018-10-31", "2018-09-30", "2018-08-31", "2018-07-31", "2018-06-30",
"2018-05-31", "2018-04-30", "2018-03-31", "2018-02-28", "2018-01-31",
"2017-12-31", "2017-11-30", "2017-10-31", "2017-09-30", "2017-08-31",
"2017-07-31", "2017-06-30", "2017-05-31", "2017-04-30")

sample_data$Val <- c(-11, 84, 74, 80, -9, 
                     -40, -76, -47, -50, -50, 
                     97, 42, 44, 53, 1, 
                     13, 65, 52, -5, 75, 
                     -41, -6, 8, -79, 53, 
                     22, -100, -57, -89, 28, 
                     37, -24, 17, -53)

我搜索过各种stackoverflow解决方案,但无法得到任何工作。大多数解决方案只处理一个列,而不是多个列,只处理一个滚动总和,而不是多个。

这是我开始的,但无法正确实现。

sample_data <- sample_data[, cumsum3mo := sample_data[.(ID, Cat, Date, (Date - day(Date)+1) %m-% months(2) - 1), 
                       on = .(ID = V1, Cat = V2, Date <= V3, Date > V4), 
                       sum(Val), by = .EACHI]][]

这是预期的输出:

sample_data <- as.data.frame(matrix(nrow =34, ncol = 6))

colnames(sample_data) <- c("ID", "Cat", "Date", "Val", "cumsum3mo", "cumsum12mo")

sample_data$ID <- c("PMM", "PMM", "PMM", "PMM", "PMM", 
                    "PMM", "PMM", "PMM", "PMM", "PMM", 
                    "PMM", "PMM", "PMM", "LCG", "LCG", 
                    "LCG", "LCG", "LCG", "LCG", "LCG", 
                    "LCG", "LCG", "LCG", "LCG", "LCG", 
                    "LCG", "LCG", "LCG", "LCG", "LCG", 
                    "LCG", "LCG", "LCG", "LCG")

sample_data$Cat <- c("MM", "MM", "MM", "MM", "MM", 
                      "MM", "MM", "MM", "MM", "MM", 
                      "MM", "MM", "MM", "OE", "OE", 
                      "OE", "OE", "OE", "OE", "OE", 
                      "OE", "OE", "OE", "OE", "OE", 
                      "OE", "OE", "OE", "OE", "OE", 
                      "OE", "OE", "OE", "OE")

sample_data$Date <- c("2018-12-31", "2018-11-30", "2018-10-31", "2018-09-30", "2018-08-31", 
                      "2018-07-31", "2018-06-30", "2018-05-31", "2018-04-30", "2018-03-31", 
                      "2018-02-28", "2018-01-31", "2017-12-31", "2018-12-31", "2018-11-30", 
                      "2018-10-31", "2018-09-30", "2018-08-31", "2018-07-31", "2018-06-30", 
                      "2018-05-31", "2018-04-30", "2018-03-31", "2018-02-28", "2018-01-31", 
                      "2017-12-31", "2017-11-30", "2017-10-31", "2017-09-30", "2017-08-31", 
                      "2017-07-31", "2017-06-30", "2017-05-31", "2017-04-30")

sample_data$Val <- c(-11, 84, 74, 80, -9, 
                     -40, -76, -47, -50, -50, 
                     97, 42, 44, 53, 1, 
                     13, 65, 52, -5, 75, 
                     -41, -6, 8, -79, 53, 
                     22, -100, -57, -89, 28, 
                     37, -24, 17, -53)

sample_data$cumsum3mo <- c(147, 238, 145, 31, -125, 
                     -163, -173, -147, -3, 89, 
                     183, 86, 44, 67, 79, 
                     130, 112, 122, 29, 28, 
                     -39, -77, -18, -4, -25, 
                     -135, -246, -118, -24, 41, 
                     30, -60, -36, -53)

sample_data$cumsum12mo <- c(94, 149, 65, -9, -89, 
                      -80, -40, 36, 83, 133, 
                      183, 86, 44, 189, 158, 
                      57, -13, -167, -191, -149, 
                      -248, -190, -237, -245, -166, 
                      -219, -241, -141, -84, 5, 
                      -23, -60, -36, -53)
r data.table
1个回答
0
投票

假设您的数据是月末,这应该让您开始:

library(data.table)
setDT(sample_data)
sample_data[, Date := as.Date(Date, format="%Y-%m-%d")]
sample_data[, c("cumsum3mo", "cumsum12mo") := .(
        sapply(Date, function(d) sum(Val[between(Date, seq(d+1L, by="-3 month", len=2L)[2L], d)])), 
        sapply(Date, function(d) sum(Val[between(Date, seq(d+1L, by="-12 months", len=2L)[2L], d)]))
    ),
    by=.(ID, Cat)]
© www.soinside.com 2019 - 2024. All rights reserved.