r语言 - 将午夜条目插入日志



我们正在监视 3 个进程 A、B 和 C,它们将始终处于 X、Y 或 Z 级别。协议记录进程何时更改级别。

df = read.csv(tc <- textConnection('Time1,Process1,Level1
2013-01-09 18:00:34,A,X
2013-01-09 18:00:34,B,Y
2013-01-09 18:00:34,C,X
2013-01-09 22:00:59,A,Z
2013-01-10 00:10:38,A,X
2013-01-10 18:38:35,B,Z
2013-01-11 05:03:11,A,Z
2013-01-11 11:09:10,C,Y
2013-01-11 12:01:18,A,Off
2013-01-11 12:01:18,B,Off
2013-01-11 12:01:18,C,Off
'),header=TRUE)
close.connection(tc) 
df$Time1 = as.POSIXct(df$Time1)
监控在 2013-01-09 18:

00:34 开始,在 2013-01-11 12:01:18 关闭。在 2013-01-09 18:00:34 和 2013-01-09 22:00:59 之间,进程 A 处于 X 级别,在 2013-01-09 22:00:59 和 2013-01-10 00:10:38 之间,进程 A 处于 Z 级别。

出于图表目的,我们希望将每个午夜的每个进程的最后和第一级状态插入到协议中:

2013-01-09 23:59:59,A,Z
2013-01-10 00:00:00,A,Z
2013-01-10 23:59:59,A,X
2013-01-11 00:00:00,A,X
2013-01-09 23:59:59,B,Y
2013-01-10 00:00:00,B,Y
2013-01-10 23:59:59,B,Z
2013-01-11 00:00:00,B,Z
2013-01-09 23:59:59,C,X
2013-01-10 00:00:00,C,X
2013-01-10 23:59:59,C,X
2013-01-11 00:00:00,C,X

可以假设日志中在 23:59:59 和 00:00:00 之间没有事件。最后,协议将在插入后按 Time1 排序(我们可以自己弄清楚(。任何指导都非常感谢!

(+1( 非常复杂和有趣的任务。我想我有答案。我将尝试在这里解释该方法。我希望这是有道理的。这里有两个棘手的问题。我的解决方案使用 data.table .

First: 我发现首先构造您需要的输出的前两列更容易。这是在下面显示的代码的第一部分中完成的:

require(data.table)
dates <- unique(as.character(strptime(as.character(df$Time1), "%Y-%m-%d")))
dates <- dates[1:(length(dates)-1)]
dates <- strptime(paste(dates, "23:59:59"), "%Y-%m-%d %H:%M:%S")
dates <- sort(c(dates, dates+1))
Time <- rep(dates, length(levels(df$Process1)))
Process <- rep(levels(df$Process1), each=length(dates))
dt.out <- data.table(Time=as.POSIXct(Time), Process=Process)
# data.table outputs crazy values if not converted using as.POSIXct..?!

通过查看每行代码的作用,这应该很容易理解。我希望它可以扩展到其他场景。

Second: 第二位同样棘手,但可以使用 data.table 在一行中完成。花了一段时间才弄清楚,但它很棒!

dt <- data.table(df, key="Process1") # convert input data.frame to data.table
out <- dt.out[, dt[J(Process)]$Level1[max(which(dt[J(Process)]$Time1 < Time))], 
            by = c("Process", "Time")]
> out
    Process                Time V1
 1:       A 2013-01-09 23:59:59  Z
 2:       A 2013-01-10 00:00:00  Z
 3:       A 2013-01-10 23:59:59  X
 4:       A 2013-01-11 00:00:00  X
 5:       B 2013-01-09 23:59:59  Y
 6:       B 2013-01-10 00:00:00  Y
 7:       B 2013-01-10 23:59:59  Z
 8:       B 2013-01-11 00:00:00  Z
 9:       C 2013-01-09 23:59:59  X
10:       C 2013-01-10 00:00:00  X
11:       C 2013-01-10 23:59:59  X
12:       C 2013-01-11 00:00:00  X

让我把这两行分成几部分来解释正在发生的事情。

在第一行中,我们将dt set keyProcess1。这允许按列Process1 VERY fast筛选数据。也就是说,dt["A"]相当于df[df$Process1 == "A"],但前者速度极快。

在第二行,发生了很多事情。我们已经创建了具有所需输出的前两列的dt.out。剩下的就是第三列。看看那行的最后一部分,上面写着by = c("Process", "Time") .在这里,我们按这两个变量拆分data.table dt.out。对于每一个拆分data.table,我们应用dt[J(Process)]$Level1[max(which(dt[J(Process)]$Time1 < Time))],它基本上从Process过滤的data.table中<Time的所有当前Time1值中挑选出maximum index,并使用此最大索引返回相应的Levels1值。>

希望这有帮助。

相关内容

  • 没有找到相关文章

最新更新