2016-03-30 17 views
0

Hier die Daten:Ereignis-Trigger auf der Grundlage historischer Daten

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 

Idee ist, dass es ein bestimmtes Ereignis ist, das einen Sensor auslösen können. Daten werden in festen Intervallen protokolliert. Nach dem Ereignis muss eine bestimmte Aktion für die nächsten drei Perioden ausgeführt werden. Was ich in Daten sehen möchte, ist, eine andere Spalte zu erstellen, die 1 ist, wenn Ereignis == 1 in einem bestimmten Zeitraum und für die nächsten 3 Perioden und sonst 0. Wie folgt aus:

> 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 

Eine Möglichkeit, es zu tun, ist eine temporäre Spalte mit Ende Periode für alle Ereignis zu erstellen == 1. Wie zum Beispiel:

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

Und dann die Schleife durch alle gültiges Datum Paare und Setzen Sie die Ergebnisspalte in allen Zeitintervallen auf 1. Aber Schleife ist im Allgemeinen eine schlechte Idee, wenn Sie große Menge von Sensoren und Beobachtungen haben.

Also gibt es vielleicht einen besseren Weg, dies ohne verschachtelte Schleife für jeden Sensortyp und jedes gültige Datumspaar zu tun?

Und eine Frage, die wahrscheinlich einen separaten Beitrag verdient: können ähnliche Trigger/Regeln direkt auf SQL-Datenbank implementiert werden?

Update:

Hier ist meine Lösung für das Problem. Ich glaube wirklich, dass ich über verkompliziert dies und viel Effizienz in den Prozess zu verlieren:

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] 

Idee ist, dass ich eine temporäre Spalte für alle „Ereignis == 1“ erstellen soll Ende Zeitraum zeigen, um T + 3. Dann erstelle ich einen neuen Datenrahmen mit allen seq.Date(), um alle Daten zu speichern, die in der Ergebnisspalte auf "1" gesetzt werden sollen. Dann passe ich die Wertepaare von Zeit + Sensor an.

Irgendwelche besseren Ideen? Denken Sie daran, dass ich ~ 1mil Sensoren habe und die Ergebnisse für ~ 100 Perioden verfolgen muss. Und ich habe ~ 500 Beobachtungen. Daher ist dieses intermediate dat.frame mit allen Daten für alle Events einfach nicht durchführbar.

Antwort

0

Sie wahrscheinlich zunächst die Daten vom Sensor geteilt müssen, dann sollten

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

Sie würden Werte in tmp zwingen müssen, die nicht größer als nrow (df)

+0

Sensoren sein sollten nur eine bequeme Art, die Idee zu vermitteln. Ich habe ~ 1 Million von "Sensoren". Und durch Sensoren aufgeteilt scheint die erste Schicht der Schleife zu sein, lapply ist die zweite Schicht der Schleife. Ich denke nicht, dass dies sehr effizient sein wird (ich werde es versuchen). Ich sollte wahrscheinlich eine '.SD' auf' data.table' nach Sensor probieren und dann eine Funktion anwenden ... und verschiedene Ansätze benchmarken. Aber '.SD' ist dafür bekannt, dass es nicht sehr gut skaliert. –

Verwandte Themen