我有一个包含4列的数据表:ID,Cat,Date和Val。我想在此表中创建2个新列,其中包含3个月和12个月Val的滚动总和,按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)
答案 0 :(得分: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)]