【问题标题】:How to calculate time difference between datetimes, for each group (student-contract)?如何计算每个组(学生合同)的日期时间之间的时间差?
【发布时间】:2013-08-08 03:52:55
【问题描述】:

我有一个具体的问题;我有以下格式的数据:

#   USER_ID SUBMISSION_DATE CONTRACT_REF
1        1       20/6 1:00         W001
2        1       20/6 2:00         W002
3        1       20/6 3:30         W003
4        4       20/6 4:00         W004
5        5       20/6 5:00         W005
6        5       20/6 6:00         W006
7        7       20/6 7:00         W007
8        7       20/6 8:00         W008
9        7       20/6 9:00         W009
10       7      20/6 10:00        W0010

现在我需要以某种方式计算不同提交之间的时间差(唯一可识别的)。

换句话说: 我有一个提交表,在这个表中,有所有用户的所有提交。我需要找到一种方法来计算 第 n 个作业和第 (n-1) 个作业之间每个唯一 STUDENT-CONTRACT 元组的时间差。

另请注意,每个新用户必须为新分配零。所以输出如下所示:

#   USER_ID SUBMISSION_DATE CONTRACT_REF  TIME_DIFFRENCE
1        1       20/6 1:00         W001                0
2        1       20/6 2:00         W002             3600
3        1       20/6 3:30         W003             5400
4        4       20/6 4:00         W004             3600
5        5       20/6 5:00         W005                0          
6        5       20/6 6:00         W006             3600
7        7       20/6 7:00         W007                0
8        7       20/6 8:00         W008             3600
9        7       20/6 9:00         W009             3600
10       7      20/6 10:00        W0010             3600

请注意,时间可能不是以秒为单位,而是任何合适的时间。

我的想法: 1)我认为这将需要 as.POSIXct 某处,以便 R 知道如何处理时间 2)这可能涉及一些包,如plyr,但我完全迷失在文档中,示例很难找到。

非常感谢您的所有回复!

最好, 雅库布

【问题讨论】:

    标签: r datetime diff plyr date-arithmetic


    【解决方案1】:

    这是一个尝试。首先,获取数据:

    dat <- read.csv(text="USER_ID,SUBMISSION_DATE,CONTRACT_REF
    1,20/6 1:00,W001
    1,20/6 2:00,W002
    1,20/6 3:30,W003
    4,20/6 4:00,W004
    5,20/6 5:00,W005
    5,20/6 6:00,W006
    7,20/6 7:00,W007
    7,20/6 8:00,W008
    7,20/6 9:00,W009
    7,20/6 10:00,W0010",header=TRUE)
    

    从合约 ref 中获取编号并对数据进行排序

    dat$CR_NUM <- as.numeric(gsub("W","",dat$CONTRACT_REF))
    dat <- with(dat,dat[order(USER_ID,CR_NUM),])
    

    将日期转换为 POSIXct 数字表示

    dat$SD_DATE <- as.numeric(with(dat,as.POSIXct(SUBMISSION_DATE,format="%d/%m %H:%M")))
    

    使用 ave 计算以 0 开头的时间差

    dat$TIME_DIFF <- with(dat, ave(SD_DATE, USER_ID, FUN=function(x) c(0,diff(x)) ))
    

    结果:

    # not showing the calculated columns
    dat[-c(4:5)]
    
       USER_ID SUBMISSION_DATE CONTRACT_REF TIME_DIFF
    1        1       20/6 1:00         W001         0
    2        1       20/6 2:00         W002      3600
    3        1       20/6 3:30         W003      5400
    4        4       20/6 4:00         W004         0
    5        5       20/6 5:00         W005         0
    6        5       20/6 6:00         W006      3600
    7        7       20/6 7:00         W007         0
    8        7       20/6 8:00         W008      3600
    9        7       20/6 9:00         W009      3600
    10       7      20/6 10:00        W0010      3600
    

    【讨论】:

      【解决方案2】:

      这是一个稍微紧凑的版本(“中间”列更少)。请注意,使用“difftime”而不是“diff”允许您选择时间单位(秒、分钟、小时等)

      dat$DATE2 <- as.POSIXct(dat$SUBMISSION_DATE,format="%d/%m %H:%M")
      getDtimes <- function(t) {
        if(length(t)>0)   c(0,difftime(t[-1], t[-length(t)], units="hours")) else(0)
      }
      dat$DTime <- unlist(with(dat, tapply(DATE2, USER_ID, getDtimes)))
      

      关键(如上)是将时间转换为POSIXt 对象。 tapply 生成时差向量列表,然后您需要 unlist

      【讨论】:

      • 小心 unlist(tapply(...)) - 如果 data.frame 未排序,则其顺序不正确。
      • 是的 - 对数据进行排序是重要的第一步。
      猜你喜欢
      • 2020-02-14
      • 1970-01-01
      • 1970-01-01
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 2011-08-01
      • 2014-09-24
      相关资源
      最近更新 更多