【问题标题】:R - Calculate Time Elapsed Since Last Event with Multiple Event TypesR - 使用多种事件类型计算自上次事件以来经过的时间
【发布时间】:2015-12-19 17:10:32
【问题描述】:

我有一个数据框,其中包含多种类型事件的日期。

df <- data.frame(date=as.Date(c("06/07/2000","15/09/2000","15/10/2000"
                            ,"03/01/2001","17/03/2001","23/04/2001",
                            "26/05/2001","01/06/2001",
                            "30/06/2001","02/07/2001","15/07/2001"
                            ,"21/12/2001"), "%d/%m/%Y"), 
             event_type=c(0,4,1,2,4,1,0,2,3,3,4,3))

   date                event_type
   ----------------    ----------
1  2000-07-06          0
2  2000-09-15          4
3  2000-10-15          1
4  2001-01-03          2
5  2001-03-17          4
6  2001-04-23          1
7  2001-05-26          0
8  2001-06-01          2
9  2001-06-30          3
10 2001-07-02          3
11 2001-07-15          4
12 2001-12-21          3

我正在尝试计算每种事件类型之间的天数,因此输出如下所示:

   date                event_type          days_since_last_event
   ----------------    ----------          ---------------------
1  2000-07-06          0                    NA
2  2000-09-15          4                    NA
3  2000-10-15          1                    NA
4  2001-01-03          2                    NA
5  2001-03-17          4                   183
6  2001-04-23          1                   190
7  2001-05-26          0                   324
8  2001-06-01          2                   149
9  2001-06-30          3                    NA
10 2001-07-02          3                     2
11 2001-07-15          4                   120
12 2001-12-21          3                   172

我从前两篇文章的答案中受益,但未能解决我在 R 中的具体问题;多种事件类型。

Calculate elapsed time since last event

Calculate days since last event in R

以下是我所了解的。我无法利用最后一个事件索引来计算最后一个事件日期。

df <- cbind(df, as.vector(data.frame(count=ave(df$event_type==df$event_type,
                                           df$event_type, FUN=cumsum))))
df <- rename(df, c("count" = "last_event_index"))

   date                event_type      last_event_index
   ---------------     -------------   ----------------
1  2000-07-06          0                1
2  2000-09-15          4                1
3  2000-10-15          1                1
4  2001-01-03          2                1
5  2001-03-17          4                2
6  2001-04-23          1                2
7  2001-05-26          0                2
8  2001-06-01          2                2
9  2001-06-30          3                1
10 2001-07-02          3                2
11 2001-07-15          4                3
12 2001-12-21          3                3

【问题讨论】:

    标签: r time


    【解决方案1】:

    我们可以使用diff 来获取按'event_type' 分组后相邻'date' 之间的差异。在这里,我使用data.table 方法,将'data.frame' 转换为'data.table' (setDT(df)),按'event_type' 分组,我们得到'date' 的diff

    library(data.table)
    setDT(df)[,days_since_last_event :=c(NA,diff(date)) , by = event_type]
    df
    #          date event_type days_since_last_event
    # 1: 2000-07-06          0                    NA
    # 2: 2000-09-15          4                    NA
    # 3: 2000-10-15          1                    NA
    # 4: 2001-01-03          2                    NA
    # 5: 2001-03-17          4                   183
    # 6: 2001-04-23          1                   190
    # 7: 2001-05-26          0                   324
    # 8: 2001-06-01          2                   149
    # 9: 2001-06-30          3                    NA
    #10: 2001-07-02          3                     2
    #11: 2001-07-15          4                   120
    #12: 2001-12-21          3                   172
    

    或者正如 @Frank 在 cmets 中提到的那样,我们也可以使用 shift(从版本 v1.9.5+ 开始)获取“日期”的 lag(默认为 type='lag')并从“日期”。

    setDT(df)[, days_since_last_event := as.numeric(date-shift(date,type="lag")), 
                                      by = event_type]
    

    【讨论】:

    • 或者date-shift(date,type="lag")
    • @akrun data.table 选项确实对我有用,所以我给了你一个赞成票。我最终使用了 dplyr 选项,因为我发现它是最干净的。感谢您在这里的洞察力。
    【解决方案2】:

    基本 R 版本是使用 split/lapply/rbi​​nd 生成新列。

    > do.call(rbind,
        lapply(
          split(df, df$event_type),
          function(d) {
            d$dsle <- c(NA, diff(d$date)); d
          }
        )
      )
               date event_type dsle
    0.1  2000-07-06          0   NA
    0.7  2001-05-26          0  324
    1.3  2000-10-15          1   NA
    1.6  2001-04-23          1  190
    2.4  2001-01-03          2   NA
    2.8  2001-06-01          2  149
    3.9  2001-06-30          3   NA
    3.10 2001-07-02          3    2
    3.12 2001-12-21          3  172
    4.2  2000-09-15          4   NA
    4.5  2001-03-17          4  183
    4.11 2001-07-15          4  120
    

    请注意,这会以与提供的顺序不同的顺序返回数据;如果要保留该顺序,可以按日期重新排序或保存原始索引。

    上面,@akrun 发布了 data.tables 方法,并行的 dplyr 方法也很简单:

    library(dplyr)
    df %>% group_by(event_type) %>% mutate(days_since_last_event=date - lag(date, 1))
    

    来源:本地数据框 [12 x 3] 组:event_type [5]

             date event_type days_since_last_event
           (date)      (dbl)                (dfft)
    1  2000-07-06          0               NA days
    2  2000-09-15          4               NA days
    3  2000-10-15          1               NA days
    4  2001-01-03          2               NA days
    5  2001-03-17          4              183 days
    6  2001-04-23          1              190 days
    7  2001-05-26          0              324 days
    8  2001-06-01          2              149 days
    9  2001-06-30          3               NA days
    10 2001-07-02          3                2 days
    11 2001-07-15          4              120 days
    12 2001-12-21          3              172 days
    

    【讨论】:

    • 我接受了你的回答,因为我在这里使用了 dplyr 选项。我发现它是最干净的。谢谢!
    • 在基础R版本中,有一个split&lt;-函数,可以避免do.call(rbind(,df$dsle &lt;- NA; split(df$dsle, df$event_type) &lt;- lapply(split(df$date, df$event_type), function(d) c(NA, diff(d)))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    • 1970-01-01
    • 2015-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-15
    相关资源
    最近更新 更多