Как я могу предотвратить использование {data.table} foverlaps NA в свой вызов any (...) при выполнении больших таблиц данных? - PullRequest
0 голосов
/ 27 апреля 2018

Прежде всего, похожая проблема:

Ошибка перепутывания: ошибка в случае остановки (любая (x [[xintervals [2L]]] - x [[xintervals [1L]]] <0L)) stop </a>

История

Я пытаюсь подсчитать, сколько раз выбросы фтора (измеряемые каждые 1 минуту) перекрываются с данным событием. Считается, что эмиссия перекрывается с данным событием, когда время эмиссии составляет 10 минут до или 30 минут после времени события. Всего мы рассмотрим три события: AC, CO и MT.

Данные

Редактировать 1:

Вот два примера наборов данных, которые разрешают выполнение приведенного ниже кода. Код отлично работает для этих наборов. Как только у меня появятся данные, которые генерируют ошибку, я сделаю второе редактирование. Обратите внимание, что в приведенном ниже примере набора данных event.GN является таблицей данных вместо таблицы

emissions.GN <- data.table(date.time=seq(ymd_hms("2016-01-01 00:00:00"), by="min",length.out = 1000000))
event.GN <- data.table(dat=seq(ymd_hms("2016-01-01 00:00:00"), by="15 mins", length.out = 26383))

Редактировать 2: Я создал CSV-файл, содержащий данные event.GN, который генерирует ошибку. Файл содержит 26383 строки одной переменной dat, но только около 14000 необходимо для генерации ошибки.

Редактировать 3: До даты "2017-03-26 00:25:20" функция работает нормально. Сразу после добавления следующей записи с датой "2017-03-26 01:33:46" возникает ошибка. Я заметил, что между этими точками есть более 60 минут. Это означает, что между этими двумя событиями времени одна или несколько записей о выбросах не будут иметь соответствующих событий. Это, в свою очередь, будет генерировать NA, которые каким-то образом оказываются вовлеченными в вызов any () функции foverlaps. Я смотрю в правильном направлении?

Данные о выбросах фтора хранятся в большом массиве данных (~ 1 миллион строк), который называется «Выбросы». Обратите внимание, что только переменная date.time (POSIXct) имеет отношение к моей проблеме.

пример выбросов.GN:

         date.time     fluor hall                  period        dt
 1: 2016-01-01 00:17:04 0.3044254   GN [2016-01-01,2016-02-21] -16.07373
 2: 2016-01-01 00:17:04 0.4368381   GN [2016-01-01,2016-02-21] -16.07373
 3: 2016-01-01 00:18:04 0.5655382   GN [2016-01-01,2016-02-21] -16.07395
 4: 2016-01-01 00:19:04 0.6542259   GN [2016-01-01,2016-02-21] -16.07417
 5: 2016-01-01 00:21:04 0.6579384   GN [2016-01-01,2016-02-21] -16.07462

Данные трех событий хранятся в трех меньших таблицах данных (~ 20 тысяч записей), содержащихся в списке под названием events.GN. Обратите внимание, что только переменная dat (POSIXct) имеет отношение к моей проблеме.

пример событий AC (CO и MT аналогичны):

events.GN[["AC"]]
              dat hall numevt                                              txtevt
1: 2016-01-01 00:04:54   GN    321     PHASE 1 CHANGEMENT D'ANODE (Position anode @1I)
2: 2016-01-01 00:09:21   GN    321     PHASE 1 CHANGEMENT D'ANODE (Position anode @1I)
3: 2016-01-01 00:38:53   GN    321     PHASE 1 CHANGEMENT D'ANODE (Position anode @1I)
4: 2016-01-01 02:30:33   GN    321     PHASE 1 CHANGEMENT D'ANODE (Position anode @1I)
5: 2016-01-01 02:34:11   GN    321     PHASE 1 CHANGEMENT D'ANODE (Position anode @1I)

Функция

Я написал функцию, которая применяет фаверлапы к заданному (большому) х датированному и заданному (маленькому) y датируемому. Функция возвращает таблицу с двумя столбцами. Первый столбец yid содержит индексы выбросов. Наблюдения GN, которые хотя бы один раз совпадают с событием. Второй столбец N содержит количество перекрытий (то есть, сколько раз происходит перекрытие для этого конкретного индекса). Индекс выбросов с нулевым перекрытием в результате опущен.

# A function to compute the number of times an emission record falls between the defined starting point and end point of an event.  
find_index_and_count <- function(hall,event, lower.margin=10, upper.margin=30){
# Define start and stop variables of the large emission dataset hall to be zero, i.e. each record is a single time point, not an interval.
hall$start <- hall$date.time
hall$stop <- hall$date.time
# Define the start and stop variables of the small event datatables equal to the defined margins oof 10 and 30 minutes respectively
event$start <- event$dat-minutes(lower.margin)
event$stop <- event$dat+minutes(upper.margin)
# Set they key of both datasets to be start and stop
setkey(hall,start,stop)
setkey(event,start,stop)
# Returns the index the of the emission record that falls N times within an event time interval. The call to na.omit is necessary to remove NA's introduced by x records that don't fall within any y interval.
foverlaps(event,hall,nomatch = NA, which = TRUE)[, .N, by=yid] %>% na.omit
}

Функция успешно выполняется для событий AC и CO

Функция выдает желаемый результат, описанный выше, при вызове событий AC и CO:

find_index_and_count(emissions.GN,events.GN[["AC"]])
   yid N
 1:       1 1
 2:       2 1
 3:       3 1
 4:       4 1
 5:       5 2
---          
find_index_and_count(emissions.GN,events.GN[["CO"]])
yid N
 1:       3 1
 2:       4 1
 3:       5 1
 4:       6 1
 5:       7 1
---          

Функция возвращает ошибку при вызове события MT

Следующий вызов функции приводит к ошибке ниже:

find_index_and_count(emissions.GN,events.GN[["MT"]])

Ошибка в остановке if (any (x [[xintervals [2L]]] - x [[xintervals [1L]]] <0L)) («Все записи в столбце»,: пропущенное значение там, где требуется TRUE / FALSE </p>

5.foverlaps (событие, зал, nomatch = NA, который = TRUE)

4.eval (lhs, parent, parent)

3.eval (lhs, parent, parent)

2.folalaps (событие, зал, nomatch = NA, который = TRUE) [, .N, by = yid]%>% na.omit

1.find_index_and_count (missions.GN, events.GN [["MT"]])

  • Я предполагаю, что функция возвращает NA, когда запись в x (эмиссии.FN) не перекрывается ни с одним из событий в y (events.FN [["AC"]] и т. Д.).
  • Я не понимаю, почему происходит сбой функции на событии MT, когда она отлично работает для AC и CO. Данные точно такие же, за исключением значений и немного другого числа записей.

То, что я пробовал до сих пор

Во-первых, в аналогичной проблеме, связанной выше, кто-то указал на следующую идею:

Это часто указывает, что значение NA подается на функцию any, поэтому возвращает NA, и это не является допустимым логическим значением. - Карл Виттофт 7 мая 15 в 13: 50

Следовательно, я изменил вызов foverlaps, чтобы он возвращал 0 вместо NA, когда не найдено перекрытия между x и y, например:

foverlaps(event,hall,nomatch = 0, which = TRUE)[, .N, by=yid] %>% na.omit

Это ничего не изменило (функция работает для AC и CO, но не работает для MT).

Во-вторых, я убедился, что ни в одном из моих данных не содержится NA.

Дополнительная информация

  • При необходимости я могу предоставить код SQL, который генерирует данные о выбросах.FN и все события.FN. Обратите внимание, что, поскольку все события events.FN имеют одинаковое происхождение, не должно быть различий (кроме значений) между данными событий AC, CO и MT.
  • Если что-то еще требуется, пожалуйста, не стесняйтесь спрашивать!

1 Ответ

0 голосов
/ 27 апреля 2018

Я пытаюсь подсчитать, сколько раз выбросы фтора (измеряемые каждые 1 минуту) перекрываются с данным событием. Считается, что излучение перекрывается с данным событием, когда время выброса составляет 10 минут до или 30 минут после времени события.

Просто решаю эту задачу (поскольку я не знаю foverlaps хорошо.) ...

event.GN[, n := 
  emissions.GN[.SD[, .(d_dn = dat - 10*60, d_up = dat + 30*60)], on=.(date.time >= d_dn, date.time <= d_up), 
    .N
  , by=.EACHI]$N
]

                       dat  n
    1: 2016-01-01 00:00:00 31
    2: 2016-01-01 00:15:00 41
    3: 2016-01-01 00:30:00 41
    4: 2016-01-01 00:45:00 41
    5: 2016-01-01 01:00:00 41
   ---                       
26379: 2016-10-01 18:30:00 41
26380: 2016-10-01 18:45:00 41
26381: 2016-10-01 19:00:00 41
26382: 2016-10-01 19:15:00 41
26383: 2016-10-01 19:30:00 41

Чтобы проверить / подтвердить один из этих показателей ...

> # dat from 99th event...
> my_d <- event.GN[99, {print(.SD); dat}]
                   dat  n
1: 2016-01-02 00:30:00 41
> 
> # subsetting to overlapping emissions
> emissions.GN[date.time %between% (my_d + c(-10*60, 30*60))]
              date.time
 1: 2016-01-02 00:20:00
 2: 2016-01-02 00:21:00
 3: 2016-01-02 00:22:00
 4: 2016-01-02 00:23:00
 5: 2016-01-02 00:24:00
 6: 2016-01-02 00:25:00
 7: 2016-01-02 00:26:00
 8: 2016-01-02 00:27:00
 9: 2016-01-02 00:28:00
10: 2016-01-02 00:29:00
11: 2016-01-02 00:30:00
12: 2016-01-02 00:31:00
13: 2016-01-02 00:32:00
14: 2016-01-02 00:33:00
15: 2016-01-02 00:34:00
16: 2016-01-02 00:35:00
17: 2016-01-02 00:36:00
18: 2016-01-02 00:37:00
19: 2016-01-02 00:38:00
20: 2016-01-02 00:39:00
21: 2016-01-02 00:40:00
22: 2016-01-02 00:41:00
23: 2016-01-02 00:42:00
24: 2016-01-02 00:43:00
25: 2016-01-02 00:44:00
26: 2016-01-02 00:45:00
27: 2016-01-02 00:46:00
28: 2016-01-02 00:47:00
29: 2016-01-02 00:48:00
30: 2016-01-02 00:49:00
31: 2016-01-02 00:50:00
32: 2016-01-02 00:51:00
33: 2016-01-02 00:52:00
34: 2016-01-02 00:53:00
35: 2016-01-02 00:54:00
36: 2016-01-02 00:55:00
37: 2016-01-02 00:56:00
38: 2016-01-02 00:57:00
39: 2016-01-02 00:58:00
40: 2016-01-02 00:59:00
41: 2016-01-02 01:00:00
              date.time
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...