【问题标题】:R - Number of days since last occurrenceR - 自上次发生以来的天数
【发布时间】:2014-11-23 15:30:27
【问题描述】:

我有一个如下所示的数据框:

 id     date
 1001   2012-10-11
 1005   2013-02-20
 1005   2012-11-21
 1005   2014-03-14
 1003   2013-10-25
 1003   2013-11-30

我需要为每一行查找自上次出现该 ID 以来经过的天数。对于上面的例子,答案应该是这样的:

 id     date        no_of_days
 1001   2012-10-11  NA
 1005   2013-02-20  91
 1005   2012-11-21  NA
 1005   2014-03-14  387
 1003   2013-10-25  NA
 1003   2013-11-30  36

经过一番搜索,我可以添加一个新列,其中包含通过对子组应用函数生成的值(R 相当于 STATA 的“bysort”):

df$no_of_days<-with(df,ave(id,id,FUN=days_passed,na.rm=TRUE))

然而,定义新函数 days_passed 被证明是棘手的,因为我必须找到该 uniqid 的最后一次出现,然后相应地制定函数。

我是 R 新手,因此非常感谢您对此提供任何帮助。谢谢!

【问题讨论】:

    标签: r


    【解决方案1】:

    使用data.table 包,您可以尝试以下操作(尽管它不会保留顺序)。假设 df 是您的数据集

    library(data.table)
    setkey(setDT(df)[, date := as.Date(date)], id, date) # If `date` is already of `Date` class you can skip the `as.Date` part
    df[, no_of_days := c(NA, diff(date)) , by = id][]
    #      id       date no_of_days
    # 1: 1001 2012-10-11         NA
    # 2: 1003 2013-10-25         NA
    # 3: 1003 2013-11-30         36
    # 4: 1005 2012-11-21         NA
    # 5: 1005 2013-02-20         91
    # 6: 1005 2014-03-14        387
    

    或者(正如@Arun 建议的那样)您可以使用order 而不是setkey 来保留订单

    setDT(df)[, date := as.Date(date)][order(id, date), 
                no := c(NA, diff(date)), by = id][]
    

    也可以试试dplyr

    library(dplyr)
    df %>%
      mutate(date = as.Date(date)) %>%
      arrange(id, date) %>%
      group_by(id) %>%
      mutate(no_of_days = c(NA, diff(date)))
    

    【讨论】:

    • 您可以通过以下方式保留订单:setDT(df)[, date := as.Date(date)][order(id, date), no := c(NA, diff(date)), by=id][]
    【解决方案2】:

    或者使用ave(类似于@David Arenburg 的方法)

     indx <- with(df, order(id, date))
     df1 <- transform(df[indx,], no_of_days=ave(as.numeric(date), id,
                        FUN= function(x) c(NA, diff(x))))[order(indx),]
     df1     
     #    id       date no_of_days
     #1 1001 2012-10-11         NA
     #2 1005 2013-02-20         91
     #3 1005 2012-11-21         NA
     #4 1005 2014-03-14        387
     #5 1003 2013-10-25         NA
     #6 1003 2013-11-30         36
    

    数据

    df <- structure(list(id = c(1001L, 1005L, 1005L, 1005L, 1003L, 1003L
    ), date = structure(c(15624, 15756, 15665, 16143, 16003, 16039
    ), class = "Date")), .Names = c("id", "date"), row.names = c(NA, 
    -6L), class = "data.frame")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-04
      • 2017-10-26
      • 1970-01-01
      • 1970-01-01
      • 2020-05-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多