Как применить функцию к подмножеству данных, где подмножество определено другим data.table? - PullRequest
0 голосов
/ 24 октября 2018

У меня есть data.table l1 с тремя столбцами, Minute, Posixct для времени и group_cor для моего значения, и я хотел бы рассчитать количество уникальных значений group_cor за определенные промежутки времени на основе data.table s1.В моем исходном наборе данных у меня есть около 1 500 000 строк данных продолжительностью приблизительно 12 дней (структурированных как l1), поэтому я ищу быстрый метод для обработки всех этих данных.

       Posixct            group_cor   Minute
 1: 2017-08-11 13:31:36       185     2017-08-11 13:31:00
 2: 2017-08-11 13:31:36       185     2017-08-11 13:31:00
 3: 2017-08-11 13:31:36       185     2017-08-11 13:31:00
 4: 2017-08-11 13:31:37       186     2017-08-11 13:31:00
 5: 2017-08-11 13:31:37       186     2017-08-11 13:31:00
 6: 2017-08-11 13:31:37       187     2017-08-11 13:31:00
 7: 2017-08-11 13:31:37       187     2017-08-11 13:31:00
 8: 2017-08-11 13:31:37       187     2017-08-11 13:31:00
 9: 2017-08-11 13:31:37       187     2017-08-11 13:31:00

Это s1, гдеstart указывает начало временного интервала и его конец.Каждый временной интервал составляет одну минуту, и это окно перемещается на 1 секунду за раз.

                     start                 end
  1: 2017-08-11 13:31:36 2017-08-11 13:32:36
  2: 2017-08-11 13:31:37 2017-08-11 13:32:37
  3: 2017-08-11 13:31:38 2017-08-11 13:32:38
  4: 2017-08-11 13:31:39 2017-08-11 13:32:39
  5: 2017-08-11 13:31:40 2017-08-11 13:32:40   

Я пытался использовать data.table, чтобы добавить столбец No в data.table s1, где я использую "на "аргумент", чтобы указать временное окно.

oma <- function(x) length(unique(x))
s1[ l1, No:=oma(group_cor), on=c('start<Posixct','end>=Posixct')]

Однако это дает

> s1
               start                 end      No
  1: 2017-08-11 13:31:36 2017-08-11 13:32:36 188
  2: 2017-08-11 13:31:37 2017-08-11 13:32:37 188
  3: 2017-08-11 13:31:38 2017-08-11 13:32:38 188
  4: 2017-08-11 13:31:39 2017-08-11 13:32:39 188
  5: 2017-08-11 13:31:40 2017-08-11 13:32:40 188 

Столбец Нет равен 188 для всех временных окон, что не соответствует действительности (и я незнаю, откуда берется это значение ..)

> range(s1$No)
 [1] 188 188   

Я знаю количество уникальных значений для каждой минуты, и новое значение No должно быть похоже на них

> tapply(l1$group_cor, l1$Minute,oma)
2017-08-11 13:31:00 2017-08-11 13:32:00 2017-08-11 13:33:00 2017-08-11     13:34:00 
             11                  17                  18                  17 
2017-08-11 13:35:00 2017-08-11 13:36:00 2017-08-11 13:37:00 2017-08-11 13:38:00 
             21                  22                  23                  22 
2017-08-11 13:39:00 2017-08-11 13:40:00 
             20                  22     

Что я делаюнеправильно?Любая помощь будет высоко оценен!Также предложения о том, как я мог бы сделать это по-другому .. Большое спасибо.

1 Ответ

0 голосов
/ 25 октября 2018

Если я вас правильно понимаю, и именно об этом Фрэнк упомянул в комментариях, вы ищете

intvl[dat, cnt := uniqueN(group_cor), by=.EACHI, on=c('start<Posixct','end>=Posixct')][, 
   cnt := replace(cnt, is.na(cnt), 0L)]

вывод:

                 start                 end cnt
1: 2017-08-11 13:31:36 2017-08-11 13:32:36   1
2: 2017-08-11 13:31:37 2017-08-11 13:32:37   0
3: 2017-08-11 13:31:38 2017-08-11 13:32:38   0
4: 2017-08-11 13:31:39 2017-08-11 13:32:39   0
5: 2017-08-11 13:31:40 2017-08-11 13:32:40   0

данные:

library(data.table)
dat <- fread("Posixct,group_cor,Minute
2017-08-11 13:31:36,185,2017-08-11 13:31:00
2017-08-11 13:31:36,185,2017-08-11 13:31:00
2017-08-11 13:31:36,185,2017-08-11 13:31:00
2017-08-11 13:31:37,186,2017-08-11 13:31:00
2017-08-11 13:31:37,186,2017-08-11 13:31:00
2017-08-11 13:31:37,187,2017-08-11 13:31:00
2017-08-11 13:31:37,187,2017-08-11 13:31:00
2017-08-11 13:31:37,187,2017-08-11 13:31:00
2017-08-11 13:31:37,187,2017-08-11 13:31:00")
cols <- c("Posixct", "Minute")
dat[, (cols) := lapply(.SD, as.POSIXct, format="%Y-%m-%d %H:%M:%S"), .SDcols=cols]

intvl <- fread("start,end
2017-08-11 13:31:36,2017-08-11 13:32:36
2017-08-11 13:31:37,2017-08-11 13:32:37
2017-08-11 13:31:38,2017-08-11 13:32:38
2017-08-11 13:31:39,2017-08-11 13:32:39
2017-08-11 13:31:40,2017-08-11 13:32:40")
cols <- c("start", "end")
intvl[, (cols) := lapply(.SD, as.POSIXct, format="%Y-%m-%d %H:%M:%S"), .SDcols=cols]

Я думаю, что вы не могли получить это раньше, потому что у вас было слишком много разных переменных в вашей R-сессии.Это поможет перезапустить сеанс и использовать чистые данные и интервал.

...