【问题标题】:R: cumulative sum over rolling date rangeR:滚动日期范围内的累积总和
【发布时间】:2018-03-05 21:42:15
【问题描述】:

在 R 中,如何在计算行之前计算定义时间段的 cumsum?如果可能,首选 dplyr。

例如,如果周期是10天,那么函数会实现cum_rolling10:

date    value   cumsum  cum_rolling10
1/01/2000   9   9       9
2/01/2000   1   10      10
5/01/2000   9   19      19
6/01/2000   3   22      22
7/01/2000   4   26      26
8/01/2000   3   29      29
13/01/2000  10  39      29
14/01/2000  9   48      38
18/01/2000  2   50      21
19/01/2000  9   59      30
21/01/2000  8   67      38
25/01/2000  5   72      24
26/01/2000  1   73      25
30/01/2000  6   79      20
31/01/2000  6   85      18

【问题讨论】:

    标签: r dplyr cumsum


    【解决方案1】:

    我建议使用 runner 包,该包旨在计算滚动/运行窗口上的函数。您可以通过使用sum_run 来实现这一点 - 这里有一个衬里:

    library(runner)
    library(dplyr)
    
    df %>%
      mutate(
        cum_rolling_10 = sum_run(
          x = df$value, 
          k = 10, 
          idx = as.Date(df$date, format = "%d/%m/%Y"))
      )
    
    
    df
    
    #          date value cum_rolling_10
    # 1   1/01/2000     9              9
    # 2   2/01/2000     1             10
    # 3   5/01/2000     9             19
    # 4   6/01/2000     3             22
    # 5   7/01/2000     4             26
    # 6   8/01/2000     3             29
    # 7  13/01/2000    10             29
    # 8  14/01/2000     9             38
    # 9  18/01/2000     2             21
    # 10 19/01/2000     9             30
    # 11 21/01/2000     8             38
    # 12 25/01/2000     5             24
    # 13 26/01/2000     1             25
    # 14 30/01/2000     6             20
    # 15 31/01/2000     6             18
    

    享受吧!

    【讨论】:

      【解决方案2】:

      此解决方案将避免内存开销,并且迁移到sparklyr 将很容易。

      滞后 = 7

          dt %>%
        mutate(date = dmy(date)) %>%
        mutate(order = datediff(date,min(date)) %>% 
        arrange(desc(order)) %>% 
        mutate(n_order = lag(order + lag,1L,default = 0)) %>% 
        mutate(b_order = ifelse(order - n_order >= 0,order,-1)) %>% 
        mutate(m_order = cummax(b_order)) %>% 
        group_by(m_order) %>% 
        mutate(rolling_value = cumsum(value))
      

      【讨论】:

        【解决方案3】:

        使用dplyrtidyrlubridatezoo 的解决方案。

        library(dplyr)
        library(tidyr)
        library(lubridate)
        library(zoo)
        
        dt2 <- dt %>%
          mutate(date = dmy(date)) %>%
          mutate(cumsum = cumsum(value)) %>%
          complete(date = full_seq(date, period = 1), fill = list(value = 0)) %>%
          mutate(cum_rolling10 = rollapplyr(value, width = 10, FUN = sum, partial = TRUE)) %>%
          drop_na(cumsum)
        dt2
        # A tibble: 15 x 4
                 date value cumsum cum_rolling10
               <date> <dbl>  <int>         <dbl>
         1 2000-01-01     9      9             9
         2 2000-01-02     1     10            10
         3 2000-01-05     9     19            19
         4 2000-01-06     3     22            22
         5 2000-01-07     4     26            26
         6 2000-01-08     3     29            29
         7 2000-01-13    10     39            29
         8 2000-01-14     9     48            38
         9 2000-01-18     2     50            21
        10 2000-01-19     9     59            30
        11 2000-01-21     8     67            38
        12 2000-01-25     5     72            24
        13 2000-01-26     1     73            25
        14 2000-01-30     6     79            20
        15 2000-01-31     6     85            18
        

        数据

        dt <- structure(list(date = c("1/01/2000", "2/01/2000", "5/01/2000", 
        "6/01/2000", "7/01/2000", "8/01/2000", "13/01/2000", "14/01/2000", 
        "18/01/2000", "19/01/2000", "21/01/2000", "25/01/2000", "26/01/2000", 
        "30/01/2000", "31/01/2000"), value = c(9L, 1L, 9L, 3L, 4L, 3L, 
        10L, 9L, 2L, 9L, 8L, 5L, 1L, 6L, 6L)), .Names = c("date", "value"
        ), row.names = c(NA, -15L), class = "data.frame")
        

        【讨论】:

        • 这对我也很有用,但是在将其应用于具有指示组的附加字段的数据时,我遇到了错误。我添加 group_by(id) 其中 id 是指包含组 ID 的字段。关于如何解决这个问题的任何想法?
        • 非常好的例子。为了让它更“现实世界的问题”,假设我们在 person x date grain 有记录。然后,我们需要按人分组,按日期排列,而不是在 mutate() 中应用 rollapply(),这仍然是个人粒度。此外,如果我们想要一个试用窗口类型的视图,那么我们需要首先应用一个 lag() 函数。
        猜你喜欢
        • 1970-01-01
        • 2022-06-10
        • 2012-09-24
        • 2021-04-02
        • 2021-05-27
        • 1970-01-01
        • 2019-07-20
        • 2021-09-12
        • 1970-01-01
        相关资源
        最近更新 更多