这是数据:
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个观察结果。因此,这个包含所有事件所有日期的中间数据框架根本不可行。
答案 0 :(得分:0)
您可能需要首先按传感器拆分数据,然后这样的事情应该起作用
tmp <- lapply(which(df$event),"+", 0:3)
df$result <- 0
df$result[unique(unlist(tmp))] <- 1
您需要强制tmp中的值不大于nrow(df)