如何使用R检测序列数据中的间隙

4
我有一个设备,它会每隔大约5分钟向状态表中插入一行。每行被视为一个状态事件,并带有时间戳。我需要检测当两个状态事件间隔超过10分钟时的情况。
虽然可以使用循环解决方案,但这似乎不太优雅,我正在寻找另一个答案。数据库中的表可以简化为:
12:01:00, 状态, 正常 12:06:31, 状态, 正常 12:12:02, 状态, 正常 13:15:43, 状态, 正常 13,20:33, 状态, 正常
因此,我想检测第三个和第四个状态行之间存在1小时3分钟41秒的间隔。不用说,我有很多数据要处理。
2个回答

5
如果你正在使用POSIXct格式的时间戳数据,你可以进行简单的减法运算来获得时间差。由于R是向量化的,不需要循环--只需对一个向量减去另一个向量即可。然后很容易测试间隔是否大于某个阈值。
# here's a data frame with a bunch of time stamps
my_dat <- data.frame(time=Sys.time() + sort(runif(10, 100, 600)))

# Take rows 1 to n-1 and subtract rows 2 to n:
my_dat$gap <- c(NA, with(my_dat, time[-1] - time[-nrow(my_dat)]))

# now, how often was the gap more than some amount of time?
gap_threshold <- 30 # let's say, 30 seconds
my_dat$over_thresh <- my_dat$gap > gap_threshold
my_dat

# result: timestamp, difference from prior row in seconds, threshold test result
# > my_dat
#                   time       gap over_thresh
# 1  2015-05-28 16:28:05        NA          NA
# 2  2015-05-28 16:28:46 40.852095        TRUE
# 3  2015-05-28 16:29:35 49.060379        TRUE
# 4  2015-05-28 16:29:55 20.290983       FALSE
# 5  2015-05-28 16:30:02  6.580322       FALSE
# 6  2015-05-28 16:30:34 32.039323        TRUE
# 7  2015-05-28 16:30:58 24.601907       FALSE
# 8  2015-05-28 16:31:16 17.761954       FALSE
# 9  2015-05-28 16:31:51 34.794329        TRUE
# 10 2015-05-28 16:32:35 44.213900        TRUE

2

使用 chron 的 "times" 类,我们可以使用 diff 比较相邻的时间,并将其与 10 分钟进行比较:

library(chron)

Times <- times(DF[[1]])
which(c(FALSE, diff(Times) > times("00:10:00")))
## [1] 4

因此,第四个点比前一个(第三个)点晚了10分钟以上。

注意:我们使用了这个输入:

Lines <- "12:01:00, status, ok
12:06:31, status, ok
12:12:02, status, ok
13:15:43, status, ok
13:20:33, status, ok"
DF <- read.table(text = Lines, sep = ",", as.is = TRUE)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接