使用R对时间序列中的事件进行分组

JD *_*ong 9 r time-series

我一直在做一些日志记录,试图向Comcast Business说明他们在我办公室中断服务的频率.我正在将ping响应时间记录到文件,然后用R解析该文件.在日志文件中,值1000表示ping超时.我的脚本每5秒记录一次ping.因此,如果我的Comcast服务停机30秒,将导致约6个日志条目的值为1000.我想以这样的方式解析我的日志,即我可以创建一个汇总表,显示每次中断何时开始,以及它持续了多长时间.有什么好方法可以做到这一点?

这是今天的一些示例数据和一些说明我的时间序列的图表:

require(xts)
outFile <- "http://pastebin.com/raw.php?i=SJuMQ9rD"
pingLog <- read.csv(outFile, header=FALSE, 
     col.names = c("time","ms"), 
     colClasses=c("POSIXct", "numeric"))
xPingLog <- as.xts(pingLog$ms, order.by=pingLog$time)
outages <- subset(pingLog, ms==1000)
xOutages <- as.xts(outages$ms, order.by=outages$time)

par(mfrow=c(2,1))
plot(xPingLog)
plot(outages)
outages
Run Code Online (Sandbox Code Playgroud)

And*_*rie 12

你必须喜欢运行长度编码,别名rle:

offline <- ifelse(pingLog$ms==1000, TRUE, FALSE)
rleOffline <- rle(offline)

offlineTable <- data.frame(
    endtime = pingLog$time[cumsum(rleOffline$lengths)],
    duration = rleOffline$lengths * 5,
    offline = rleOffline$values
)
Run Code Online (Sandbox Code Playgroud)

结果是:

offlineTable

              endtime duration offline
1 2011-11-20 13:20:19     1030   FALSE
2 2011-11-20 13:20:35        5    TRUE
3 2011-11-20 13:24:37      240   FALSE
4 2011-11-20 13:25:57       25    TRUE
5 2011-11-20 13:53:28     1640   FALSE
Run Code Online (Sandbox Code Playgroud)

为什么这样做?

首先构建一个指示在线与离线的逻辑向量. ifelse对此很方便.

offline <- ifelse(pingLog$ms==1000, TRUE, FALSE)
Run Code Online (Sandbox Code Playgroud)

然后rle用来计算运行长度编码:

rle(offline)
Run Length Encoding
  lengths: int [1:5] 206 1 48 5 328
  values : logi [1:5] FALSE TRUE FALSE TRUE FALSE
Run Code Online (Sandbox Code Playgroud)

此表说明了TRUE或FALSE的运行次数以及每次运行的持续时间.在这种情况下,第一次运行是206个周期,值为FALSE(即在线为206*5 = 1030秒.

最后一步是使用rle信息来索引原始pingLog查找时间.额外的魔力是用来cumsum计算游程长度的累积和.这个的真实含义是每个运行终止的索引位置.