用R中的plyr计算累积计数

时间:2014-08-22 13:34:50

标签: r plyr

我有一个大约70,000行的数据框,我试图获得一个依赖于日期时间变量的计数>我一直在使用plyr进行其他分析,但这个只是不起作用。我的数据框如下:

Create.Date.Time        Service         Closing.Date.Time
1   2013-06-01 12:59:00 AV              2013-06-01 13:59:00
2   2013-06-02 07:56:00 SERVICE684793   2013-06-02 08:59:00
3   2013-06-02 09:39:00 SERVICE684793   2013-06-03 12:01:00
4   2013-06-02 14:14:00 SERVICE684796   2013-06-02 14:55:00
5   2013-06-02 17:20:00 SERVICE684797   2013-06-03 12:06:00
6   2013-06-03 07:20:00 SERVICE684793   2013-06-03 07:39:00
7   2013-06-03 08:02:00 SERVICE684839   2013-06-03 12:09:00
8   2013-06-03 08:04:00 SERVICE684841   2013-06-04 08:05:00
9   2013-06-03 08:04:00 SERVICE684841   2013-06-05 08:06:00
10  2013-06-03 08:08:00 SERVICE684841   2013-06-03 08:08:00

我的目标是获取每个Create.Date.Time关闭的每个观察的数量。我不想使用for循环,因为这将永远。 我想使用plyr,函数是计数:

计算观察次数

  

Closing.Date.Time< = Create.Date.Time

每个Create.Date.Time

的每个Service.

我的起点是ddply (df, .(Service, Create.Date.Time), ...),但我的功能有问题,因为值取决于我的Create.Date.Time,我不知道怎么写。有人可以帮帮我吗?

我想最终得到这样的数据框:

 Service        Create.Date.Time      Num.Closed
  AV            2013-06-01 12:59:00      0
  SERVICE684793 2013-06-02 07:56:00      0
  SERVICE684793 2013-06-02 09:39:00      1
  SERVICE684793 2013-06-03 07:20:00      1
  SERVICE684796 2013-06-02 14:14:00      0
  SERVICE684797 2013-06-02 17:20:00      0
  SERVICE684839 2013-06-03 08:02:00      0
  SERVICE684841 2013-06-03 08:04:00      0
  SERVICE684841 2013-06-03 08:04:00      0
  SERVICE684841 2013-06-03 08:08:00      3

2 个答案:

答案 0 :(得分:0)

我真的不确定您想要结束的data.frame如何与您从结果中提出的问题相关。不是你描述的那个人。如果没有其他选择,你可以编写一个你会使用的循环吗?

如果你想(正如你写的那样):

计算观察次数

Closing.Date.Time <= Create.Date.Time
每个Create.Date.Time的每个Service

,那么一个好的方法就是使用data.table包。在这种情况下,您的数据是:

       Create.Date.Time       Service   Closing.Date.Time
 1: 2013-06-01 12:59:00            AV 2013-06-01 13:59:00
 2: 2013-06-02 07:56:00 SERVICE684793 2013-06-02 08:59:00
 3: 2013-06-02 09:39:00 SERVICE684793 2013-06-03 12:01:00
 4: 2013-06-02 14:14:00 SERVICE684796 2013-06-02 14:55:00
 5: 2013-06-02 17:20:00 SERVICE684797 2013-06-03 12:06:00
 6: 2013-06-03 07:20:00 SERVICE684793 2013-06-03 07:39:00
 7: 2013-06-03 08:02:00 SERVICE684839 2013-06-03 12:09:00
 8: 2013-06-03 08:04:00 SERVICE684841 2013-06-04 08:05:00
 9: 2013-06-03 08:04:00 SERVICE684841 2013-06-05 08:06:00
10: 2013-06-03 08:08:00 SERVICE684841 2013-06-03 08:08:00

日期和时间为POSIXct格式。

然后:

dt[, sum(Closing.Date.Time <= Create.Date.Time ), by = c('Service', 'Create.Date.Time')]

会导致

         Service    Create.Date.Time V1
1:            AV 2013-06-01 12:59:00  0
2: SERVICE684793 2013-06-02 07:56:00  0
3: SERVICE684793 2013-06-02 09:39:00  0
4: SERVICE684796 2013-06-02 14:14:00  0
5: SERVICE684797 2013-06-02 17:20:00  0
6: SERVICE684793 2013-06-03 07:20:00  0
7: SERVICE684839 2013-06-03 08:02:00  0
8: SERVICE684841 2013-06-03 08:04:00  0
9: SERVICE684841 2013-06-03 08:08:00  1

你所描述的是什么。

干杯。

答案 1 :(得分:0)

我没有完全理解这个问题,因为有一个实例显示的预期输出与我得到的输出不同。如果这只是一个错字:

数据

 df <-   structure(list(Create.Date.Time = structure(c(1370105940, 1370174160, 
 1370180340, 1370196840, 1370208000, 1370258400, 1370260920, 1370261040, 
 1370261040, 1370261280), class = c("POSIXct", "POSIXt"), tzone = ""), 
 Service = c("AV", "SERVICE684793", "SERVICE684793", "SERVICE684796", 
"SERVICE684797", "SERVICE684793", "SERVICE684839", "SERVICE684841", 
"SERVICE684841", "SERVICE684841"), Closing.Date.Time = structure(c(1370109540, 
1370177940, 1370275260, 1370199300, 1370275560, 1370259540, 
1370275740, 1370347500, 1370433960, 1370261280), class = c("POSIXct", 
"POSIXt"), tzone = "")), .Names = c("Create.Date.Time", "Service", 
"Closing.Date.Time"), row.names = c("1", "2", "3", "4", "5", 
"6", "7", "8", "9", "10"), class = "data.frame")

POSIXct班级

中提取时间
library(lubridate)

dfNew <- within(df, {
            Createtime <- period_to_seconds(hms(strftime(Create.Date.Time, "%H:%M:%S")))
         Closingtime <- period_to_seconds(hms(strftime(Closing.Date.Time, "%H:%M:%S")))})

dfNew <- dfNew[order(dfNew$Service),] #not that necessary

使用data.table

library(data.table)
setDT(dfNew)[,Num.Closed := cumsum(unlist(lapply(1:.N, function(i) sum(Closingtime[1:i] <=Createtime[i])))),
   by=Service][,c(2,1,6), with=FALSE] 
#              Service    Create.Date.Time Num.Closed
 #1:            AV 2013-06-01 12:59:00          0
 #2: SERVICE684793 2013-06-02 07:56:00          0
 #3: SERVICE684793 2013-06-02 09:39:00          1
 #4: SERVICE684793 2013-06-03 07:20:00          1
 #5: SERVICE684796 2013-06-02 14:14:00          0
 #6: SERVICE684797 2013-06-02 17:20:00          1
 #7: SERVICE684839 2013-06-03 08:02:00          0
 #8: SERVICE684841 2013-06-03 08:04:00          0
 #9: SERVICE684841 2013-06-03 08:04:00          0
#10: SERVICE684841 2013-06-03 08:08:00          3