首页 > 解决方案 > 日期“参差不齐”的事件的条件滚动总和

问题描述

介绍

我正在使用 R 来分析非洲抗议运动的“势头”。为此,我正在分析个别抗议事件。我想在一段时间内创建滚动数量(总和)的滚动度量。

Stack Overflow 上的大多数答案都处理以固定间隔观察的数据集(每天或每月一次等)。但是我的数据是“参差不齐的”,因为它们以不同的时间间隔出现。有时观察之间有一天。其他时间有两周。

我想创造什么

过去 10 天内在给定国家/地区发生的抗议事件数量的滚动总和。这将是一个变量的形式,它简单地将过去十天内的事件数量相加,包括当前事件。

数据

这是一组可重现的数据:

df1 <- data.frame(date = c("8/1/2019", "8/2/2019", "8/3/2019", "8/6/2019", "8/15/2019", "8/16/2019", "8/30/2019", "9/1/2019", "9/2/2019", "9/3/2019", "9/4/2019", "6/1/2019", "6/26/2019", "7/1/2019", "7/2/2019", "7/9/2019", "7/10/2019", "8/1/2019", "8/2/2019", "8/15/2019", "8/28/2019", "9/1/2019"),
country = c(rep("Algeria", 11), rep("Benin", 11)),
event = rep("Protest", 22))

我希望数据看起来像什么

date       country   event     roll_sum
--------   -------   -------   --------
8/1/2019   Algeria   Protest   1
8/2/2019   Algeria   Protest   2
8/3/2019   Algeria   Protest   3
8/6/2019   Algeria   Protest   4
8/15/2019  Algeria   Protest   2
8/16/2019  Algeria   Protest   3
8/30/2019  Algeria   Protest   1
9/1/2019   Algeria   Protest   2
9/2/2019   Algeria   Protest   3
9/3/2019   Algeria   Protest   4 
9/4/2019   Algeria   Protest   5
6/1/2019   Benin     Protest   1
6/26/2019  Benin     Protest   1
7/1/2019   Benin     Protest   2
7/2/2019   Benin     Protest   3
7/9/2019   Benin     Protest   3
7/10/2019  Benin     Protest   4
8/1/2019   Benin     Protest   1
8/2/2019   Benin     Protest   2
8/15/2019  Benin     Protest   1
8/28/2019  Benin     Protest   1
9/1/2019   Benin     Protest   2

这一切可能都很简单,但我不知道该怎么做。先感谢您!

标签: rrolling-sum

解决方案


用于lubridate将日期字符串转换为使用函数date创建间隔。是一个返回给定日期向量是否在区间内的函数。interval%within%lubridate

创建一个dates列,每行是一个存储该国家/地区所有日期的列表。并用于purrr::pmap()迭代修改后的数据框中的所有行。

library(lubridate)
library(dplyr)
library(purrr)
df1 <- data.frame(date = c("8/1/2019", "8/2/2019", "8/3/2019", "8/6/2019", "8/15/2019", "8/16/2019", "8/30/2019", "9/1/2019", "9/2/2019", "9/3/2019", "9/4/2019", "6/1/2019", "6/26/2019", "7/1/2019", "7/2/2019", "7/9/2019", "7/10/2019", "8/1/2019", "8/2/2019", "8/15/2019", "8/28/2019", "9/1/2019"),
                  country = c(rep("Algeria", 11), rep("Benin", 11)),
                  event = rep("Protest", 22))

df2 <- df1 %>%
    mutate(
        date = mdy(date),
        interval = interval(date -days(10),date)
    ) %>%
    group_by(country) %>%
    mutate(dates = list(date)) %>%
    ungroup()

df2["roll_sum"] <- pmap_dbl(df2,function(...){
    values <- list(...)
    sum(values$dates %within% values$interval)
}) 
df2 %>%
    select(-interval,-dates)
# A tibble: 22 x 4
   date       country event   roll_sum
   <date>     <fct>   <fct>      <dbl>
 1 2019-08-01 Algeria Protest        1
 2 2019-08-02 Algeria Protest        2
 3 2019-08-03 Algeria Protest        3
 4 2019-08-06 Algeria Protest        4
 5 2019-08-15 Algeria Protest        2
 6 2019-08-16 Algeria Protest        3
 7 2019-08-30 Algeria Protest        1
 8 2019-09-01 Algeria Protest        2
 9 2019-09-02 Algeria Protest        3
10 2019-09-03 Algeria Protest        4
# ... with 12 more rows

推荐阅读