【问题标题】:r - compute rolling sum by id within specific time framer - 在特定时间范围内按 id 计算滚动总和
【发布时间】:2018-06-20 16:24:43
【问题描述】:

我想通过 id 计算前 1 年窗口中当前行之前的行数。

这是我的数据:

df <- structure(list(id = c("1", "1", "1", "1", 
                                   "2", "2", "2", "2", "2", "2", "2", 
                                   "2", "2"), flag = c(1, 1, 0, 1, 0, 0, 1, 1, 
                                                                         1, 1, 1, 1, 1), date = structure(c(15425, 15456, 16613, 
                                                                                                                       16959, 15513, 15513, 15625, 15635, 15649, 15663, 15670, 16051, 
                                                                                                                       16052), class = "Date")), sorted = "id", class = c("data.table", 
                                                                                                                                                             "data.frame"), row.names = c(NA, -13L))




roll_sum <- c(0, 1, 0, 1, 0, 1, 2, 3, 4, 5, 6, 0, 1)
flag_sum <- c(0, 1, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 1)

df_desired <- cbind(df, roll_sum) # roll_sum: number of rows excluding current row in 1 year time frame rolling
df_desired <- cbind(df_desired, flag_sum) # flag_sum: number of rows excluding current row in 1 year time frame rolling where flag was 1

数据:

id flag       date
 1:  1    1 2012-03-26
 2:  1    1 2012-04-26
 3:  1    0 2015-06-27
 4:  1    1 2016-06-07
 5:  2    0 2012-06-22
 6:  2    0 2012-06-22
 7:  2    1 2012-10-12
 8:  2    1 2012-10-22
 9:  2    1 2012-11-05
10:  2    1 2012-11-19
11:  2    1 2012-11-26
12:  2    1 2013-12-12
13:  2    1 2013-12-13

输出:

df_desired
    id flag       date roll_sum flag_sum
 1:  1    1 2012-03-26        0        0
 2:  1    1 2012-04-26        1        1
 3:  1    0 2015-06-27        0        0
 4:  1    1 2016-06-07        1        0
 5:  2    0 2012-06-22        0        0
 6:  2    0 2012-06-22        1        0
 7:  2    1 2012-10-12        2        0
 8:  2    1 2012-10-22        3        1
 9:  2    1 2012-11-05        4        2
10:  2    1 2012-11-19        5        3
11:  2    1 2012-11-26        6        4
12:  2    1 2013-12-12        0        0
13:  2    1 2013-12-13        1        1

我尝试了 G. Grothendieck 在Compute rolling sum by id variables, with missing timepoints 中使用zoo 给出的解决方案,但它给了我一个错误:

merge.zoo(z, g) 中的错误: 系列不能与系列中的非唯一索引条目合并 另外:警告信息: 在动物园(计数,日期):

我使用make.index.uniquemake.time.unique 使日期列独一无二。

任何有关优化解决方案的帮助都将不胜感激。谢谢。

【问题讨论】:

  • 没试过这个,但它的名字 uts 包应该做你需要的:github.com/andreas50/uts 否则你需要为每个日期插入 NA 行(可能是id)然后做定期滚动总和。快速滚动总和 (frollsum) 计划用于 data.table 1.12.0 版本。
  • 我查看了uts,无法真正弄清楚如何使用它来解决我的问题。

标签: r data.table zoo rollapply


【解决方案1】:

不确定这对您的数据维度有帮助。

首先,创建运行索引来处理重复日期和滚动总和不得包括上一个重复日期并且还创建一年前的日期(我认为 365 更好,但似乎 OP 想要 366)。

然后,执行非等自连接,同时确保不使用上一个重复日期并且日期在一年内。

df[, c("rn", "oneYrAgo") := .(.I, date - 366)]

df[df, 
    .(roll_sum=.N, flag_sum=sum(flag, na.rm=TRUE)), 
    on=.(date >= oneYrAgo, rn < rn, id, date <= date), 
    by=.EACHI][, 
        -seq_len(2L)]

结果:

    id       date roll_sum flag_sum
 1:  1 2012-03-26        0        0
 2:  1 2012-04-26        1        1
 3:  1 2015-06-27        0        0
 4:  1 2016-06-07        1        0
 5:  2 2012-06-22        0        0
 6:  2 2012-06-22        1        0
 7:  2 2012-10-12        2        0
 8:  2 2012-10-22        3        1
 9:  2 2012-11-05        4        2
10:  2 2012-11-19        5        3
11:  2 2012-11-26        6        4
12:  2 2013-12-12        0        0
13:  2 2013-12-13        1        1

【讨论】:

  • 我猜它在我的数据集上运行良好。我正在处理的数据集并不大,大约 75 Mbs。我同意你的观点,365 天是一个更好的选择,它很灵活。我对此解决方案有两个问题: 1. 如何保留第二行代码之后的所有列?我可以将roll_sumflag_sum 加入到rn 设置的原始数据中,但最好保留所有列。 2. 同名date 的重复列将是一个问题。我将不得不过滤一个日期为一年前的列。否则,我真的很喜欢你的解决方案,它运行良好。
  • 所有列,因为您的列比您发布的示例数据集中的列多得多?无论如何,我发布了一个没有额外列的新版本
  • 否则,您可以按照您所说的进行左连接更新或进行 2 更新连接
  • 是的,它是我在此处发布的列的子集。还有很多列。但是,最好在输出中没有重复的 date 列。为了保留你提到的所有列,我可以做一个left_join。那会奏效。感谢您的帮助。
  • 您的实际数据集中存在重复连接。您需要在代码中添加allow.cartesian=TRUE
猜你喜欢
  • 2018-05-19
  • 2015-03-13
  • 2020-12-23
  • 2018-12-28
  • 2018-03-05
  • 1970-01-01
  • 2017-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多