如何计算每组(学生合同)的日期时间之间的时差?

时间:2013-08-06 23:13:29

标签: r datetime diff plyr date-arithmetic

我有一个特定的问题;我有以下格式的数据:

#   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,但我在文档中完全丢失,并且很难找到示例。

非常感谢您的回复!

最佳, 的Jakub

2 个答案:

答案 0 :(得分:2)

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

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)

从合约引用中获取数字并对数据进行排序

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

答案 1 :(得分:1)

这是一个稍微紧凑的版本(具有较少的“中间”列)。请注意,使用“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