我是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
中做到答案 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