使用data.table计算和格式化行之间的时差

时间:2013-12-12 13:07:26

标签: r diff data.table

我是data.table“scene”的新手,所以如果我的问题过于简单,我会道歉。我经常处于我必须应用某些分析的位置,或者根据唯一ID分组一些数据。通常,每个唯一ID大约有1,000行,大约有30个唯一ID。因此,我已被建议切换到data.table,而不是试图找出lapply或sapply或plyr包。

以下是我的数据类型的示例

    structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 
3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), dt = structure(c(1138366975, 
1138370472, 1138374064, 1138377669, 1138381264, 1138384873, 1138388503, 
1138399312, 1138402842, 1138406507, 1138413700, 1138417261, 1138420848, 
1138424444, 1138428071, 1138431695, 1138435287, 1138438938, 1138442428, 
1138446098), class = c("POSIXct", "POSIXt"), tzone = "GMT")), .Names = c("ID", 
"dt"), row.names = c(NA, -20L), class = "data.frame")

我将其转换为data.table

X = data.table(test)

将我的“密钥”设为个人

setkey(X,ID)

然后我们的目标是在HOURS(此时我希望很容易)计算时差。因此,以Time2-Time1获取每个连续位置BY Individual(在本例中为ID)之间的小时和分钟。

X[, diff:=c(NA,diff(dt)),by = ID]

此处的diff命令以分钟计算它,但我想以最有效的方式将此转换/舍入为小时,同时仍将值保持为POSIX或时间对象。我知道我可能会创建另一个列并将diff除以60.但我希望有一些方法可以在某处输入"hours""minutes"或某种东西。因为我不理解data.table如何处理时间。 我曾尝试使用data.frame循环使用for命令在difftime中执行此操作,但它如此繁琐并将数据链接回原始数据帧让我感到困惑,因为我不熟练for循环。

一旦我将数据分成几小时,我想只选择相隔0.5小时的数据,然后相隔4小时,然后相隔12小时。我还没有弄清楚如何在data.table

中做到

2 个答案:

答案 0 :(得分:2)

这是一种方法,尽管不是最有效的......

X[ , diff := c( NA_character_ , difftime( tail( dt , -1 ) , head( dt , -1 ) , units = "hours" ) ) , by = ID ]
#    ID                V1
# 1:  1                NA
# 2:  1 0.971388888888889
# 3:  1 0.997777777777778
# 4:  1  1.00138888888889
# 5:  2                NA

答案 1 :(得分:1)

X[, diff := c(NA,round(diff(dt)/60)),by=ID]不简单吗?似乎没有时间惩罚。

f1 <- function(X){return(X[, diff := {tmp = diff(dt); units(tmp) <- "hours"; c(NA, as.numeric(tmp))}, by=ID][])}
f2 <- function(X){return(X[, diff := c(NA,round(diff(dt)/60)),by=ID])}

library(microbenchmark)
microbenchmark(f1(X),f2(X))
# Unit: milliseconds
#   expr      min       lq   median       uq      max neval
#  f1(X) 4.676918 4.772861 5.233032 5.324829 7.387008   100
#  f2(X) 4.615325 4.854294 5.161371 5.383165 7.147151   100