计算以零为底的累计总和总和

问题描述

我想修改cumsum函数。我希望将负值更改为0。另外,当有一个新的D值不同于0时,请使用D-S

以下示例:

TD <- data.frame(product = rep("A",7),data = seq(as.Date("2020-01-01"),as.Date("2020-01-07"),by = "day"),D = c(74,20,10),S = c(20,30,5,2,4,5))

TD <- TD %>% group_by(product) %>%  mutate(result = cumsum(D) - cumsum(S))

> TD
# A tibble: 6 x 5
# Groups:   product [1]
  product data           D     S result      I expected
  <chr>   <date>     <dbl> <dbl>  <dbl>
1 A       2020-01-01    74    20     54          54
2 A       2020-01-02     0    30     24          24
3 A       2020-01-03     0    20      4           4
4 A       2020-01-04     0     5     -1           0
5 A       2020-01-05     0     2     -3           0
6 A       2020-01-06    20     4     13          16
7 A       2020-01-07    10     5     18          21

解决方法

我认为此功能可以满足您的需求

pos_cumsum <- function(x) {
  cs <- cumsum(x)
  cm <- cummin(cs)
  return (cs - pmin(cm,0))
}

TD<- TD%>% group_by(product) %>%  mutate(result = pos_cumsum(D-S))
TD
#> # A tibble: 7 x 5
#> # Groups:   product [1]
#>   product data           D     S result
#>   <chr>   <date>     <dbl> <dbl>  <dbl>
#> 1 A       2020-01-01    74    20     54
#> 2 A       2020-01-02     0    30     24
#> 3 A       2020-01-03     0    20      4
#> 4 A       2020-01-04     0     5      0
#> 5 A       2020-01-05     0     2      0
#> 6 A       2020-01-06    20     4     16
#> 7 A       2020-01-07    10     5     21

尽管我想知道D是发生在S之前还是之后...

,

您可以通过accumulate()中的purrr自定义累积和的规则。

library(dplyr)
library(purrr)

TD %>%
  group_by(product) %>% 
  mutate(result = accumulate(D-S,~ pmax(0,.x + .y),.init = 0)[-1])

# # A tibble: 7 x 5
# # Groups:   product [1]
#   product data           D     S result
#   <chr>   <date>     <dbl> <dbl>  <dbl>
# 1 A       2020-01-01    74    20     54
# 2 A       2020-01-02     0    30     24
# 3 A       2020-01-03     0    20      4
# 4 A       2020-01-04     0     5      0
# 5 A       2020-01-05     0     2      0
# 6 A       2020-01-06    20     4     16
# 7 A       2020-01-07    10     5     21