【问题标题】:Summarising date ranges总结日期范围
【发布时间】:2018-10-03 16:25:04
【问题描述】:

我有一个带有患者 ID 和日期的数据框,按 ID 中的日期顺序排序。每个患者通常有几条线路,尽管可能只有一条。 例如:

patid   date
1302    2009-01-27
1302    2009-02-05
1302    2009-08-28
1670    2009-03-12
2073    2009-04-03
2073    2010-11-01
2073    2010-12-19
2073    2011-03-06

据此,我想为每个患者生成一个包含开始和结束日期的数据框或 CSV 文件,所以从上面,我有

patid   start       end
1302    2009-01-27  2009-08-28
1670    2009-03-12  2009-03-12
2073    2009-04-03  2011-03-06

我在初始文件中有超过 3000 万行,所以我不想编写 for 循环。

我想知道是否有一种有效的方法可以做到这一点,或许可以从使用aggregate 为每个患者推导行数开始?

【问题讨论】:

    标签: r


    【解决方案1】:

    tidyverse:

    read.table(text="patid   date
               1302    2009-01-27
               1302    2009-02-05
               1302    2009-08-28
               1670    2009-03-12
               2073    2009-04-03
               2073    2010-11-01
               2073    2010-12-19
               2073    2011-03-06",header=T)%>%
       group_by(patid)%>%
       mutate(date=lubridate::ymd(date))%>%
       summarise(start=min(date),
                 end=max(date))
    # A tibble: 3 x 3
      patid start      end       
      <int> <date>     <date>    
    1  1302 2009-01-27 2009-08-28
    2  1670 2009-03-12 2009-03-12
    3  2073 2009-04-03 2011-03-06
    

    【讨论】:

      【解决方案2】:

      使用sqldf

      输入数据:

      df=read.table(text="patid   date
                1302    2009-01-27
                1302    2009-02-05
                1302    2009-08-28
                1670    2009-03-12
                2073    2009-04-03
                2073    2010-11-01
                2073    2010-12-19
                2073    2011-03-06",header=T)
      

      代码

       library(sqldf)
       sqldf("select patid,min(date) as start, max(date) as end from df group by patid")
      

      输出:

         patid      start        end
      1  1302 2009-01-27 2009-08-28
      2  1670 2009-03-12 2009-03-12
      3  2073 2009-04-03 2011-03-06
      

      【讨论】:

        【解决方案3】:

        使用基本 R 函数 aggregate() 和 FUN = 一个简单的自定义函数,在一个步骤中返回两个输出 min()max() 的向量:

        按照您的建议,您可以使用 aggregate() - 但如下所示,您可以一步完成,为每个 patid 组计算 min()max()

        # Read in your sample data, being careful to prevent dates from becoming factors
        pdates <- 
          read.table( text="patid   date
                            1302    2009-01-27
                            1302    2009-02-05
                            1302    2009-08-28
                            1670    2009-03-12
                            2073    2009-04-03
                            2073    2010-11-01
                            2073    2010-12-19
                            2073    2011-03-06",
                            header=TRUE, 
                            stringsAsFactors=FALSE) # keep date strings from becoming factors!
        
        aggregate( x = pdates["date"],   # dataframe with column(s) to aggregate
                   by = pdates["patid"], # passing dataframe with named column "patid" preserves the column name in the output
                   FUN = function(vdate) { 
                           c(start=min(vdate), end=max(vdate))
                         }  
                 )
        
          patid date.start   date.end
        1  1302 2009-01-27 2009-08-28
        2  1670 2009-03-12 2009-03-12
        3  2073 2009-04-03 2011-03-06
        

        编辑:或者,更简单地使用非常有用的基本 R range() 函数:

        aggregate( pdates["date"], by=pdates["patid"], range)
        
          patid     date.1     date.2
        1  1302 2009-01-27 2009-08-28
        2  1670 2009-03-12 2009-03-12
        3  2073 2009-04-03 2011-03-06
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-01-19
          • 1970-01-01
          • 2014-01-07
          • 2020-06-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多