如何将功能应用于数据子集,而该子集由另一个data.table指定?

时间:2018-10-24 09:46:19

标签: r data.table subset

我有一个data.table l1,它具有三列,Minute,Posixct用于时间和group_cor作为我的值,并且我想根据data.table s1在特定时间间隔内计算group_cor唯一值的数量。在我的原始数据集中,我有大约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在data.table s1中添加一列No,在其中我使用“ on”参数指定时间窗口。

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   

我知道每分钟的唯一值数量,并且新的“否”应该与它们相似

> 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 :(得分:0)

如果我正确地理解了您,并且弗兰克在评论中提到了什么,那么您正在寻找

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会话中有太多不同的变量。这将有助于重新启动会话并使用干净的数据和时间间隔。