【问题标题】:Getting cummulative count with plyr in R在 R 中使用 plyr 获取累积计数
【发布时间】:2014-08-22 13:34:50
【问题描述】:

我有一个包含大约 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 对于每个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

【问题讨论】:

  • 在您展示的数据集中。 with(df, Closing.Date.Time <=Create.Date.Time)# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE。只有一行是 TRUE。我不确定您是如何在预期输出中得到3 的。
  • 我实际上想要一个累积计数,我自己输入了预期的数据框,例如,对于我的数据框第 10 行的 Create.Date.Time,对该服务有三个观察结果结束时间
  • 您能否使用dput(df) 提供您的数据框,其中df 是您的数据框?
  • @user3770767。对于SERVICE684797 行,看起来像Closing.date.time <= Create.Date.Time'. So, Num.Closed would be 1`?
  • @akrun,不,不是,因为截止日期是2013.06.03,而开幕日期是2013.06.02。所以截止日期是在开幕日期之后。我已经尝试修改您的代码以包含日期。还没有成功:-(

标签: r plyr


【解决方案1】:

我不太确定您想要最终得到的 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

这就是你所描述的。

干杯。

【讨论】:

    【解决方案2】:

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

    数据

     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
    

    【讨论】:

    • 感谢您的帮助。我觉得完全愚蠢,但是在提取时间与“period_to_seconds”之前有什么方法可以结合日期和时间?因为日期/时间的比较也应该考虑日期......
    猜你喜欢
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 2021-03-19
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多