首页 > 解决方案 > R中具有多个条件的累积和?

问题描述

我试图弄清楚如何根据几个条件在 R 中创建累积或滚动总和。

有问题的数据集是对图书馆借阅的几百万次观察,问题是确定需要多少份给定书籍/标题才能满足需求。

因此,对于每个 Title.ID,从第一个实例 (ID.Index) 的 1 个副本开始。然后对于之后的每个实例,根据 REQUEST.DATE 是否在前一个请求的 16 周(112 天)内确定是否需要另一个副本。

# A tibble: 15 x 3
# Groups:   Title.ID [2]
   REQUEST.DATE Title.ID ID.Index
   <date>          <int>    <int>
 1 2013-07-09          2        1
 2 2013-08-07          2        2
 3 2013-08-20          2        3
 4 2013-09-08          2        4
 5 2013-09-28          2        5
 6 2013-12-27          2        6
 7 2014-02-10          2        7
 8 2014-03-12          2        8
 9 2014-03-14          2        9
10 2014-08-27          2       10
11 2014-04-27          6        1
12 2014-08-01          6        2
13 2014-11-13          6        3
14 2015-02-14          6        4
15 2015-05-14          6        5

棘手的部分是,确定是否需要新副本不仅基于请求的数量(ID.Index)和一些先前贷款的 REQUEST.DATE,而且还基于先前的累积总和。

比如第三次请求title 2(Title.ID 2, ID.Index 3),现在有两个副本,所以要判断是否需要新的副本,就得看REQUEST.DATE是否在112以内第一个(不是第二个)请求(ID.Index 1)的天数。相比之下,对于标题 6 的第三次请求(Title.ID 6,ID.Index 3),只有一个可用副本(因为请求 2 不在 112 天内),因此确定是否需要新副本是基于回顾 ID.Index 2 的 REQUEST.DATE。

所需的输出(“Copies”)将获取每个新请求(ID.Index),然后根据可用副本的数量回顾相关的 REQUEST.DATE,这样做意味着查看前面计算的累积总和. (注意:最大副本数为 10。)

我为下面的示例提供了所需的输出(“副本”)。

# A tibble: 15 x 4
# Groups:   Title.ID [2]
   REQUEST.DATE Title.ID ID.Index Copies
   <date>          <int>    <int>  <dbl>
 1 2013-07-09          2        1      1
 2 2013-08-07          2        2      2
 3 2013-08-20          2        3      3
 4 2013-09-08          2        4      4
 5 2013-09-28          2        5      5
 6 2013-12-27          2        6      5
 7 2014-02-10          2        7      5
 8 2014-03-12          2        8      5
 9 2014-03-14          2        9      5
10 2014-08-27          2       10      5
11 2014-04-27          6        1      1
12 2014-08-01          6        2      2
13 2014-11-13          6        3      2
14 2015-02-14          6        4      2
15 2015-05-14          6        5      2
> 

我认识到解决方案将超出我的能力范围,因此我将非常感谢有关将来如何解决此类问题的任何解决方案或建议。

太感谢了!

*4/19 更新:新示例可能会延迟添加新副本,即不按顺序添加。我还添加了显示自给定先前请求以来的天数的列,这有助于根据有多少副本来检查是否应该添加新副本。

示例 2:应在第三次请求时添加新副本,因为距离上次请求仅 96 天(并且只有一个副本)

REQUEST.NUMBER REQUEST.DATE Title.ID ID.Index Days.Since Days.Since2 Days.Since3 Days.Since4 Days.Since5 Copies
  <fct>          <date>          <int>    <int> <drtn>     <drtn>      <drtn>      <drtn>      <drtn>       <int>
1 BRO-10680332   2013-10-17          6        1  NA days    NA days     NA days     NA days     NA days         1
2 PEN-10835735   2014-04-27          6        2 192 days    NA days     NA days     NA days     NA days         1
3 PEN-10873506   2014-08-01          6        3  96 days   288 days     NA days     NA days     NA days         1
4 PEN-10951264   2014-11-13          6        4 104 days   200 days    392 days     NA days     NA days         1
5 PEN-11029526   2015-02-14          6        5  93 days   197 days    293 days    485 days     NA days         1
6 PEN-11106581   2015-05-14          6        6  89 days   182 days    286 days    382 days    574 days         1

示例 3:新副本应与最后一个请求一起添加,因为有两个副本,最早的请求是 45 天。

REQUEST.NUMBER REQUEST.DATE Title.ID ID.Index Days.Since Days.Since2 Days.Since3 Days.Since4 Days.Since5 Copies
  <fct>          <date>          <int>    <int> <drtn>     <drtn>      <drtn>      <drtn>      <drtn>       <int>
1 BRO-10999392   2015-01-20         76        1  NA days    NA days     NA days     NA days     NA days         1
2 YAL-11004302   2015-01-22         76        2   2 days    NA days     NA days     NA days     NA days         2
3 COR-11108471   2015-05-18         76        3 116 days   118 days     NA days     NA days     NA days         2
4 HVD-11136632   2015-07-27         76        4  70 days   186 days    188 days     NA days     NA days         2
5 MIT-11164843   2015-09-09         76        5  44 days   114 days    230 days    232 days     NA days         2
6 HVD-11166239   2015-09-10         76        6   1 days    45 days    115 days    231 days    233 days         2

标签: rcumsumrolling-sum

解决方案


您可以使用runner包在累积窗口上应用任何 R 函数。这次我们f使用x = REQUEST.DATE. 我们只计算 内的观察次数min(x) + 112

library(dplyr)
library(runner)

data %>%
  group_by(Title.ID) %>%
  mutate(
    Copies = runner(
      x = REQUEST.DATE,
      f = function(x) {
        length(x[x <= (min(x + 112))])
      }
    )
  )

# # A tibble: 15 x 4
# # Groups:   Title.ID [2]
#        REQUEST.DATE Title.ID ID.Index Copies
#        <date>          <int>    <int>  <int>
#    1 2013-07-09          2        1      1
#    2 2013-08-07          2        2      2
#    3 2013-08-20          2        3      3
#    4 2013-09-08          2        4      4
#    5 2013-09-28          2        5      5
#    6 2013-12-27          2        6      5
#    7 2014-02-10          2        7      5
#    8 2014-03-12          2        8      5
#    9 2014-03-14          2        9      5
#   10 2014-08-27          2       10      5
#   11 2014-04-27          6        1      1
#   12 2014-08-01          6        2      2
#   13 2014-11-13          6        3      2
#   14 2015-02-14          6        4      2
#   15 2015-05-14          6        5      2


数据

data <- read.table(
  text = "   REQUEST.DATE Title.ID ID.Index
 1 2013-07-09          2        1
 2 2013-08-07          2        2
 3 2013-08-20          2        3
 4 2013-09-08          2        4
 5 2013-09-28          2        5
 6 2013-12-27          2        6
 7 2014-02-10          2        7
 8 2014-03-12          2        8
 9 2014-03-14          2        9
10 2014-08-27          2       10
11 2014-04-27          6        1
12 2014-08-01          6        2
13 2014-11-13          6        3
14 2015-02-14          6        4
15 2015-05-14          6        5", 
  header = TRUE)

data$REQUEST.DATE <- as.Date(as.character(data$REQUEST.DATE))


推荐阅读