【问题标题】:Creating Repeated Start and End Dates创建重复的开始和结束日期
【发布时间】:2014-09-22 17:46:09
【问题描述】:

我有一个包含许多变量的数据集。感兴趣的是:ID、情节、开始、结束、评估日期。显示了一个示例数据集

 ID Episode     Start         End  AssessmentDate
 1       1  1/1/2012  12/21/2012        1/1/2012
 1       1  1/1/2010  12/21/2012      12/12/2012
 1       1  1/1/2010  12/21/2012      12/21/2012
 1       2  1/1/2013           .        1/2/2013
 1       2  1/1/2013           .        2/2/2013
 1       2  1/1/2013           .        3/2/2013
 2       1  1/1/2012           .        4/1/2012
 2       1  1/1/2010           .       5/12/2012
 2       1  1/1/2010           .       6/21/2012
 2       2  1/1/2013           .        7/2/2013
 2       2  1/1/2013           .        8/2/2013
 2       2  1/1/2013           .        9/2/2013

我有每个人的开始日期,但没有任何结束日期。我想为 10,000 名患者确定每一集和每位患者的结束日期。我希望结束日期是每个剧集编号的最后评估日期,并且我希望在第一个和最后一个评估日期之间的每一行中都存在此日期。

我正在阅读一些关于根据 ID 和 Episode 将数据集拆分为许多较小部分的内容,但我觉得应该有一种更简单的方法来做到这一点。我是来自 SAS 的 R 新手,SAS 中的此类问题不会给我带来太多麻烦。

如果您对我的数据准备工作提出任何意见,我将不胜感激。

【问题讨论】:

  • 我同意。您可能希望将示例数据更改为更能代表您的实际数据的内容

标签: r date max grouping


【解决方案1】:

您可以使用 plyr 库中的 ddply() 按剧集查找最长评估日期:

df <- data.frame(id=1, Episode=c(1,1,1,2,2,2), AssessmentDate=as.Date(c("2012-01-01", "2012-12-12", "2012-12-21", "2013-01-02", "2013-02-02", "2013-03-02")))

library(plyr)

df <- ddply(df, .(Episode), transform, End=max(AssessmentDate))
df

这给了你:

  ID Episode AssessmentDate        End
1  1       1     2012-01-01 2012-12-21
2  1       1     2012-12-12 2012-12-21
3  1       1     2012-12-21 2012-12-21
4  1       2     2013-01-02 2013-03-02
5  1       2     2013-02-02 2013-03-02
6  1       2     2013-03-02 2013-03-02

如果你想由病人来做,你可以使用ddply().(ID)(假设识别病人)或类似的东西。

也可以使用by() 执行此操作,但会变得有点复杂,因为它将数据拆分为由分组变量的值标识的列表。

编辑:另外,如果Episode 在整个数据框中不是唯一的,即它对每个患者重复,您可以按两个变量分组,即ddply(df, .(ID, Episode), ...)

【讨论】:

    【解决方案2】:

    假设您已将值正确读取为日期并处理了“。”就像 R 中的 NA 值一样,您的示例数据框应该具有这种结构

    dd<-structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L), Episode = c(1L, 
    1L, 1L, 2L, 2L, 2L), Start = structure(c(15340, 14610, 14610, 
    15706, 15706, 15706), class = "Date"), End = structure(c(15695, 
    15695, 15695, NA, NA, NA), class = "Date"), AssessmentDate = structure(c(15340, 
    15686, 15695, 15707, 15738, 15766), class = "Date")), .Names = c("ID", 
    "Episode", "Start", "End", "AssessmentDate"), row.names = c(NA, 
    -6L), class = "data.frame")
    

    然后,您可以使用基本 ave() 函数计算每集的最大评估日期

    dd$NewEnd <- ave(dd$AssessmentDate, dd$Episode, FUN=max)
    

    给了

      ID Episode      Start        End AssessmentDate     NewEnd
    1  1       1 2012-01-01 2012-12-21     2012-01-01 2012-12-21
    2  1       1 2010-01-01 2012-12-21     2012-12-12 2012-12-21
    3  1       1 2010-01-01 2012-12-21     2012-12-21 2012-12-21
    4  1       2 2013-01-01       <NA>     2013-01-02 2013-03-02
    5  1       2 2013-01-01       <NA>     2013-02-02 2013-03-02
    6  1       2 2013-01-01       <NA>     2013-03-02 2013-03-02
    

    这里我没有覆盖现有的 End 值。我不确定在不匹配的情况下要做什么。

    【讨论】:

      【解决方案3】:

      或使用data.table(来自@MrFlicks 帖子的数据)

       library(data.table)
       setDT(dd)[, NewEnd:=max(AssessmentDate), by=Episode]
       dd
       #      ID Episode      Start        End AssessmentDate     NewEnd
       #1:  1       1 2012-01-01 2012-12-21     2012-01-01 2012-12-21
       #2:  1       1 2010-01-01 2012-12-21     2012-12-12 2012-12-21
       #3:  1       1 2010-01-01 2012-12-21     2012-12-21 2012-12-21
       #4:  1       2 2013-01-01       <NA>     2013-01-02 2013-03-02
       #5:  1       2 2013-01-01       <NA>     2013-02-02 2013-03-02
       #6:  1       2 2013-01-01       <NA>     2013-03-02 2013-03-02
      

      dplyr

      library(dplyr)
       dd %>% 
          group_by(Episode) %>% 
          mutate(NewEnd=max(AssessmentDate))
      

      【讨论】: