2016-03-30 3 views
0

Вот данные:триггер событий на основе исторических данных

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 при событии == 1 в любой заданный период и в течение следующих 3 периодов и 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?

Update:

Вот мое решение этой проблемы. Я действительно думаю, что я чрезмерно усложнять это и потерять много эффективности в процессе:

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] 

Идея заключается в том, что я создаю временный столбец для всех «событий == 1», чтобы показать предполагаемый конец периода при Т + 3. Затем я создаю новый кадр данных со всеми seq.Date(), чтобы сохранить все даты, которые должны быть установлены как «1» в столбце результата. Затем я сопоставляю пары значений времени + датчик.

Любые лучшие идеи? Имейте в виду, что у меня есть ~ 1 миллиметр датчиков и приходится отслеживать результаты за ~ 100 периодов. И у меня есть ~ 500 наблюдений. Поэтому этот промежуточный data.frame со всеми датами для всех событий просто невозможен.

ответ

0

Вы, вероятно, нужно разделить данные от датчика, а затем что-то, как это должно работать

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

Вы должны были бы заставить значения в TMP быть не больше, чем nrow (ДФ)

+0

Датчики были просто удобный способ передать идею. У меня есть ~ 1 миллион «датчиков». И разделение на датчики, кажется, является первым слоем цикла, lapply - второй слой цикла. Я действительно не думаю, что это будет очень эффективно (я попробую хотя). Вероятно, я должен попробовать '.SD' на' data.table' с помощью сенсора, а затем «применить» функцию ... и сравнить различные подходы. Но '.SD' известен тем, что он не масштабируется очень хорошо. –

Смежные вопросы