gpt4 book ai didi

r - 基于 R 中的条件的窗口中的累积总和(或运行窗口总和)

转载 作者:行者123 更新时间:2023-12-04 03:42:06 35 4
gpt4 key购买 nike

我正在尝试根据条件计算给定窗口的累积总和。我见过解决方案执行条件累积总和( Calculate a conditional running sum in R for every row in data frame )和滚动总和( Rolling Sum by Another Variable in R )的线程,但我找不到两者在一起。我还看到 data.tableR data.table sliding window 处没有滚动窗口函数。所以,这个问题对我来说非常具有挑战性。

此外,滚动总和的 solution posted by Mike Grahan 超出了我的理解。我正在寻找基于 data.table 的方法,主要是为了速度。但是,如果可以理解,我对其他方法持开放态度。

这是我的输入数据:

DFI <- structure(list(FY = c(2011, 2012, 2013, 2015, 2016, 2011, 2011, 
2012, 2013, 2014, 2015, 2010, 2016, 2013, 2014, 2015, 2010),
Customer = c(13575, 13575, 13575, 13575, 13575, 13575, 13575,
13575, 13575, 13575, 13575, 13578, 13578, 13578, 13578, 13578,
13578), Product = c("A", "A", "A", "A", "A", "B", "B", "B",
"B", "B", "B", "A", "A", "B", "C", "D", "E"), Rev = c(4,
3, 3, 1, 2, 1, 2, 3, 4, 5, 6, 3, 2, 2, 4, 2, 2)), .Names = c("FY",
"Customer", "Product", "Rev"), row.names = c(NA, 17L), class = "data.frame")

这是我的预期输出:(手动创建;如果出现手动错误,我深表歉意)
DFO <- structure(list(FY = c(2011, 2012, 2013, 2015, 2016, 2011, 2012, 
2013, 2014, 2015, 2010, 2016, 2013, 2014, 2015, 2010), Customer = c(13575,
13575, 13575, 13575, 13575, 13575, 13575, 13575, 13575, 13575,
13578, 13578, 13578, 13578, 13578, 13578), Product = c("A", "A",
"A", "A", "A", "B", "B", "B", "B", "B", "A", "A", "B", "C", "D",
"E"), Rev = c(4, 3, 3, 1, 2, 3, 3, 4, 5, 6, 3, 2, 2, 4, 2, 2),
cumsum = c(4, 7, 10, 11, 9, 3, 6, 10, 15, 21, 3, 2, 2, 4,
2, 2)), .Names = c("FY", "Customer", "Product", "Rev", "cumsum"
), row.names = c(NA, 16L), class = "data.frame")

关于逻辑的一些评论:

1) 我想在 5 年内找到滚动总和。理想情况下,我希望这个 5 年期间是可变的,即我可以在代码的其他地方指定的东西。这样,我可以自由地在以后更改窗口以进行分析。

2) Window 的结束基于最大年份(即上例中的 FY)。在上面的例子中, FY 中的最大 DFI2016 。因此,对于 2016 - 5 + 1 = 2012 中的所有条目,窗口的起始年份将为 2016

3) 窗口总和(或运行总和)由 Customer 和特定的 Product 计算。

我试过的:

我想在发布之前尝试一些东西。这是我的代码:
  DFI <- data.table::as.data.table(DFI)

#Sort it first
DFI<-DFI[order(Customer,FY),]

#find cumulative sum; remove Rev column; order rows
DFOTest<-DFI[,cumsum := cumsum(Rev),by=.(Customer,Product)][,.SD[which.max(cumsum)],by=.(FY,Customer,Product)][,("Rev"):=NULL][order(Customer,Product,FY)]

此代码计算累积总和,但我无法定义 5 年窗口,然后计算运行总和。我有两个问题:

问题 1) 如何计算 5 年的运行总和?

问题 2) 有人可以解释一下 Mike's method on this thread 吗?它似乎很快。但是,我不确定那里发生了什么。我确实看到有人要求提供一些评论,但我不确定它是否不言自明。

提前致谢。我已经在这个问题上挣扎了两天。

最佳答案

1) rollapply 创建一个 Sum 函数,该函数将 FYRev 作为一个 2 列矩阵(或者如果没有将其设为一个),然后将 075 年的那些年的最后 104 年的收入相加然后将 k 转换为数据表,汇总具有相同客户/产品/年份的行,并为每个客户/产品组运行 DFIrollapplyr

library(data.table)
library(zoo)

k <- 5
Sum <- function(x) {
x <- matrix(x,, 2)
FY <- x[, 1]
Rev <- x[, 2]
ok <- FY >= tail(FY, 1) - k + 1
sum(Rev[ok])
}
DT <- as.data.table(DFI)
DT <- DT[, list(Rev = sum(Rev)), by = c("Customer", "Product", "FY")]
DT[, cumsum := rollapplyr(.SD, k, Sum, by.column = FALSE, partial = TRUE),
by = c("Customer", "Product"), .SDcols = c("FY", "Rev")]

给予:
 > DT
Customer Product FY Rev cumsum
1: 13575 A 2011 4 4
2: 13575 A 2012 3 7
3: 13575 A 2013 3 10
4: 13575 A 2015 1 11
5: 13575 A 2016 2 9
6: 13575 B 2011 3 3
7: 13575 B 2012 3 6
8: 13575 B 2013 4 10
9: 13575 B 2014 5 15
10: 13575 B 2015 6 21
11: 13578 A 2010 3 3
12: 13578 A 2016 2 2
13: 13578 B 2013 2 2
14: 13578 C 2014 4 4
15: 13578 D 2015 2 2
16: 13578 E 2010 2 2

2) 仅数据表

首先对具有相同 Customer/Product/FY 的行求和,然后按 Customer/Product 分组,对于每个 FY 值 Sum ,挑出 FY 值在 fyRev 之间的 fy-k+1 值和 sum。
library(data.table)

k <- 5
DT <- as.data.table(DFI)
DT <- DT[, list(Rev = sum(Rev)), by = c("Customer", "Product", "FY")]
DT[, cumsum := sapply(FY, function(fy) sum(Rev[between(FY, fy-k+1, fy)])),
by = c("Customer", "Product")]

给予:
> DT
Customer Product FY Rev cumsum
1: 13575 A 2011 4 4
2: 13575 A 2012 3 7
3: 13575 A 2013 3 10
4: 13575 A 2015 1 11
5: 13575 A 2016 2 9
6: 13575 B 2011 3 3
7: 13575 B 2012 3 6
8: 13575 B 2013 4 10
9: 13575 B 2014 5 15
10: 13575 B 2015 6 21
11: 13578 A 2010 3 3
12: 13578 A 2016 2 2
13: 13578 B 2013 2 2
14: 13578 C 2014 4 4
15: 13578 D 2015 2 2
16: 13578 E 2010 2 2

关于r - 基于 R 中的条件的窗口中的累积总和(或运行窗口总和),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48434157/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com