基于历史数据的事件触发

时间:2016-03-30 10:35:49

标签: r

这是数据:

df <- data.table(time = rep(seq.Date(as.Date("2016-01-01"), as.Date("2016-01-10"), 1), 2),
                 sensor = c(rep("A", 10), rep("B", 10)),
                 event = 0)
df$event[c(3,8,11,12)] <- 1

          time sensor event
 1: 2016-01-01      A     0
 2: 2016-01-02      A     0
 3: 2016-01-03      A     1
 4: 2016-01-04      A     0
 5: 2016-01-05      A     0
 6: 2016-01-06      A     0
 7: 2016-01-07      A     0
 8: 2016-01-08      A     1
 9: 2016-01-09      A     0
10: 2016-01-10      A     0
11: 2016-01-01      B     1
12: 2016-01-02      B     1
13: 2016-01-03      B     0
14: 2016-01-04      B     0
15: 2016-01-05      B     0
16: 2016-01-06      B     0
17: 2016-01-07      B     0
18: 2016-01-08      B     0
19: 2016-01-09      B     0
20: 2016-01-10      B     0

想法是某个事件可以触发传感器。以固定间隔记录数据。事件发生后,需要在接下来的三个时段内执行某项操作。我希望在数据中看到的是创建另一列,当事件== 1时,在任何给定时间段内和接下来的3个时间段中为1,否则为0。像这样:

> df
          time sensor event result
 1: 2016-01-01      A     0      0
 2: 2016-01-02      A     0      0
 3: 2016-01-03      A     1      1
 4: 2016-01-04      A     0      1
 5: 2016-01-05      A     0      1
 6: 2016-01-06      A     0      1
 7: 2016-01-07      A     0      0
 8: 2016-01-08      A     1      1
 9: 2016-01-09      A     0      1
10: 2016-01-10      A     0      1
11: 2016-01-01      B     1      1
12: 2016-01-02      B     1      1
13: 2016-01-03      B     0      1
14: 2016-01-04      B     0      1
15: 2016-01-05      B     0      1
16: 2016-01-06      B     0      0
17: 2016-01-07      B     0      0
18: 2016-01-08      B     0      0
19: 2016-01-09      B     0      0
20: 2016-01-10      B     0      0

一种方法是创建一个临时列,其中包含所有事件的结束周期== 1.例如:

df[,temp:=ifelse(event == 1, time + 3, NA)][,temp:=as.Date(temp, origin)]

然后循环遍历所有有效日期对,并在所有时间间隔内将结果列设置为1。但是当你有大量的传感器和观察时,循环通常是一个坏主意。

因此,如果没有针对每种传感器类型和每个有效日期对的嵌套循环,可能有更好的方法吗?

这个问题可能值得一个单独的帖子:类似的触发器/规则可以直接实现到SQL数据库吗?

更新

这是我解决问题的方法。我真的认为我过度复杂化并在此过程中失去了很多效率:

df[,temp:=ifelse(event == 1, time + 3, NA)][,temp:=as.Date(temp, origin)]

dateFun <- function(x){
  c(x[1], seq.Date(as.Date(x[2]), as.Date(x[3]), 1))
}

x <- data.table(t(apply(df[!is.na(temp),.SD,by = sensor,.SDcols = c("time","temp")], 1, function(x) dateFun(x))))
x <- x[,t(.SD),by=sensor][,V1:=as.Date(as.numeric(V1), origin)]

df[,result:=ifelse(paste(sensor, time) %in% paste(x$sensor, x$V1), 1, 0)][,temp:=NULL]

想法是我为所有&#34; event == 1&#34;创建一个临时列。在T + 3显示假设的结束期。然后我创建一个包含所有seq.Date()的新数据框,以存储应设置为&#34; 1&#34;的所有日期。在结果列中。然后我匹配时间+传感器的值对。

有更好的想法吗?请记住,我有大约1百万的传感器,并且必须跟踪大约100个周期的结果。我有~500个观察结果。因此,这个包含所有事件所有日期的中间数据框架根本不可行。

1 个答案:

答案 0 :(得分:0)

您可能需要首先按传感器拆分数据,然后这样的事情应该起作用

tmp <- lapply(which(df$event),"+", 0:3)
df$result <- 0
df$result[unique(unlist(tmp))] <- 1 

您需要强制tmp中的值不大于nrow(df)