Условно выберите несколько элементов по диапазону дат и идентификатору в data.table - PullRequest
0 голосов
/ 03 июля 2018

У меня есть data.table, содержащий идентификаторы единиц измерения, идентификатор настройки и диапазон данных, для которого эта настройка действительна. Мне нужно извлечь настройки для определенных идентификаторов единиц для определенного дня. Следующий минимальный рабочий пример показывает, как я мог бы получить результат.

library(data.table)
settingstable=data.table(UNITID=c(1,1,1,2,2,2,3,4,5,6,6),
                     STARTDATE=as.POSIXct(c("2018-01-01","2018-02-28","2018-06-01","2018-01-01","2018-04-01","2018-06-01","2018-01-01","2018-01-01","2018-01-01","2018-01-01","2018-05-01")),
                     ENDDATE=as.POSIXct(c("2018-02-28","2018-05-31","2018-12-31","2018-03-31","2018-05-31","2018-12-31","2018-12-31","2018-12-31","2018-12-31","2018-04-30","2018-12-31")),
                     SETTINGS=c(1,2,3,4,5,6,7,8,9,10,11))
selectunits=c(2,4,6)
selectdays=as.POSIXct(c("2018-04-02","2018-05-03","2018-02-01"))

resultsettings=NULL
for (i in 1:length(selectunits)) {
  resultsettings=rbind(resultsettings,settingstable[UNITID==selectunits[i] & STARTDATE <= selectdays[i] & ENDDATE >= selectdays[i],.(UNITID,SETTINGS)])
}

Для больших таблиц данных или большого количества единиц и дней это будет очень неэффективно. Я надеялся, что группировка с by=UNITID будет работать, но, к сожалению, это невозможно, так как следующее приведет к ошибке longer object length is not a multiple of shorter object length.

resultsettings=settingstable[UNITID %in% selectunits & STARTDATE <= selectdays & ENDDATE >= selectdays,.(UNITID,SETTINGS),by=UNITID]

Как я могу улучшить свой код, чтобы он работал более эффективно?

1 Ответ

0 голосов
/ 03 июля 2018

Вы можете использовать неэквивалентное объединение:

settingstable[.(u = selectunits, d = selectdays), 
  on=.(UNITID = u, STARTDATE <= d, ENDDATE >= d), 
  .(UNITID, SETTINGS)]

   UNITID SETTINGS
1:      2        5
2:      4        8
3:      6       10

Синтаксис x[i, on=, j].

  • Список i = .(u = selectunits, d = selectdays) рассматривается как таблица, которая должна быть объединена с x = settingstable.
  • Объединение работает путем поиска каждой строки, если i в x в соответствии с on=.
  • В j мы можем преобразовать результат. (Без j мы бы просто получили объединенный стол.)

Если ваши условия on= дают несколько совпадений, все они появятся в результате. Если они не оставляют совпадений, SETTINGS и другие столбцы из x будут иметь значение NA (хотя это можно настроить с помощью аргумента nomatch=).

...