在特定时间段内使用R计算时间序列数据的计算次数的有效方法

时间:2016-08-03 20:41:03

标签: r time-series

我正在处理使用R的医院的时间序列数据,看起来像

         Time of Arrival    Time of Treatment
         8/1/14 12:14 AM    8/1/14 12:26 AM
         8/1/14 12:22 AM    8/1/14 12:35 AM
         8/1/14 12:47 AM    8/1/14 12:56 AM
         8/1/14 1:07 AM     8/1/14 1:16 AM
         8/1/14 1:19 AM     8/1/14 1:32 AM
         8/1/14 1:53 AM     8/1/14 2:02 AM
          8/1/14 1:56 AM    8/1/14 2:18 AM
          8/1/14 1:58 AM    8/1/14 2:15 AM

这主要是关于患者在ED部门的到来以及治疗时间。我有完整的一年数据,并致力于建立基于回归的模型,以预测患者的治疗时间。为此,我将整个数据集分成20分钟(12.00 A.M到12.20 A.M等),并根据此计数,有多少患者在20分钟的时间内到达。目前,我正在使用两个步骤 1.计算两个特定时期之间的患者数量 2.将计算出的数字分配回特定时间段。

为了执行第二项任务,我使用以下代码

     for (i in 1:nrow(date))
      {for (j in 1:nrow(period)){
        if (date[i,1]>=period[j,]){ 
        j=j+1
        z[i,]=t[j,]}
        }
          i=i+1
             }

不幸的是,第二步需要花费太多时间才能完成,我想知道是否有任何有效的方法可以执行我的第二项任务?我是R的新手,使用两级for循环会使计算时间过长。

在这方面的任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

计算在给定时间段内有多少患者,如果出现以下情况,我将患者定义为:

  • 他在期间结束前到达
  • 他在期开始后接受治疗

更改数据集而不是上午12点到上午0点:

require(data.table)

text = "arr;tre
8/1/14 0:14 AM;8/1/14 0:26 AM
8/1/14 0:22 AM;8/1/14 0:35 AM
8/1/14 0:47 AM;8/1/14 0:56 AM
8/1/14 1:07 AM; 8/1/14 1:16 AM
8/1/14 1:19 AM; 8/1/14 1:32 AM
8/1/14 1:53 AM; 8/1/14 2:02 AM
8/1/14 1:56 AM;8/1/14 2:18 AM
8/1/14 1:58 AM;8/1/14 2:15 AM"

阅读和解析数据:

dat <- fread(text, sep = ";")
dat[,c("arr", "tre") := .(as.POSIXct(arr, format="%m/%d/%y %H:%M %p"), as.POSIXct(tre, format="%m/%d/%y %H:%M %p"))]
dat[,`:=`(arr_d = as.IDate(arr),
          arr_t = as.ITime(arr),
          tre_d = as.IDate(tre),
          tre_t = as.ITime(tre))]
dat[,c("arr", "tre") := NULL]

你可以使用data.table的新半连接。这是data.table 1.9.7中的新功能,因此您需要开发版本。查找安装指南here

使用期间的开始和结束时间创建data.table

mp <- data.table(period_start = seq(as.POSIXct("2014-08-01 0:00"), as.POSIXct("2014-08-01 03:00"), by = "20 min"))
mp <- mp[, period_end := shift(period_start, 1, type = "lead")][-.N]
mp[,`:=`(ps_d = as.IDate(period_start),
         ps_t = as.ITime(period_start),
         pe_d = as.IDate(period_end),
         pe_t = as.ITime(period_end))]
mp[,c("period_start", "period_end") := NULL]

运行join:

res <- dat[mp,.(ps_d, ps_t, pe_d, pe_t, x.arr_d, x.arr_t, x.tre_d, x.tre_t), 
           on=.(arr_d <= pe_d, arr_t <= pe_t,
                tre_d >= ps_d, tre_t >= ps_t), nomatch=NA, allow.cartesian=TRUE]

看一下res。您可以仔细检查患者的分类。

按period_start计算患者人数

res[,sum(!is.na(x.arr_d)), by=.(ps_d, ps_t)]

这导致:

         ps_d     ps_t V1
1: 2014-07-31 00:00:00  1
2: 2014-07-31 00:20:00  2
3: 2014-07-31 00:40:00  1
4: 2014-07-31 01:00:00  2
5: 2014-07-31 01:20:00  1
6: 2014-07-31 01:40:00  3
7: 2014-08-01 02:00:00  3
8: 2014-08-01 02:20:00  0
9: 2014-08-01 02:40:00  0