首页 > 解决方案 > 每日数据的运行总和,当月轮换时重置

问题描述

我有一个 2 列表(tibble),由一个日期对象和一个数值变量组成。每天最多有一个条目,但并非每天都有一个条目(即日期是自然主键)。我正在尝试对数字列和日期进行运行总和,但在月份转动时会重置运行总和(数据按升序日期排序)。我已经在下面复制了我想要得到的结果。

Date         score  monthly.running.sum
10/2/2019       7       7
10/9/2019       6       13
10/16/2019      12      25
10/23/2019      2       27
10/30/2019      13      40
11/6/2019       2       2
11/13/2019      4       6
11/20/2019      15      21
11/27/2019      16      37
12/4/2019       4       4
12/11/2019      24      28
12/18/2019      28      56
12/25/2019      8       64
1/1/2020        1       1
1/8/2020        15      16
1/15/2020       9       25
1/22/2020       8       33

看起来包“runner”可能适合这个,但我真的不明白如何指导它。我知道我可以使用一个join操作加上一个group_byusingdplyr来做到这一点,但是数据集非常非常大,这样做会非常低效。我也可以通过循环手动遍历列表,但这似乎也不优雅。我能想到的最后一个选项是选择一个唯一的yearmon对象向量,然后将原始列表切割成许多较短的列表并在其上运行一个简单cumsum的列表,但这也感觉不理想。我相信这不是第一次有人这样做,并且考虑到有多少工具在tidyverse做事,我想我只需要帮助找到合适的人。我正在寻找一种工具而不是使用我上面描述的方法之一(这比写这篇文章花费更少的时间)的原因是因为这段代码需要非常容易被不熟悉代码的观众阅读。

标签: rdplyrtidyverse

解决方案


我们也可以使用data.table

library(data.table)
setDT(df)[, Date := as.IDate(Date, "%m/%d/%Y")
           ][, monthly.running.sum :=  cumsum(score),format(Date, "%Y-%m")][]
#          Date score monthly.running.sum
# 1: 2019-10-02     7                   7
# 2: 2019-10-09     6                  13
# 3: 2019-10-16    12                  25
# 4: 2019-10-23     2                  27
# 5: 2019-10-30    13                  40
# 6: 2019-11-06     2                   2
# 7: 2019-11-13     4                   6
# 8: 2019-11-20    15                  21
# 9: 2019-11-27    16                  37
#10: 2019-12-04     4                   4
#11: 2019-12-11    24                  28
#12: 2019-12-18    28                  56
#13: 2019-12-25     8                  64
#14: 2020-01-01     1                   1
#15: 2020-01-08    15                  16
#16: 2020-01-15     9                  25
#17: 2020-01-22     8                  33

数据

df <- structure(list(Date = c("10/2/2019", "10/9/2019", "10/16/2019", 
"10/23/2019", "10/30/2019", "11/6/2019", "11/13/2019", "11/20/2019", 
"11/27/2019", "12/4/2019", "12/11/2019", "12/18/2019", "12/25/2019", 
"1/1/2020", "1/8/2020", "1/15/2020", "1/22/2020"), score = c(7L, 
6L, 12L, 2L, 13L, 2L, 4L, 15L, 16L, 4L, 24L, 28L, 8L, 1L, 15L, 
9L, 8L)), row.names = c(NA, -17L), class = "data.frame")

推荐阅读