R 聚合行及时关闭

R 聚合行及时关闭,r,performance,datetime,data.table,aggregate,R,Performance,Datetime,Data.table,Aggregate,我在R中有一个数据集,格式如下: data = data.table( id = c(1, 2, 2, 2, 3, 3, 3, 3 ,3, 3), Start = c("2019-03-01 09:15:36", "2019-01-01 08:00:00", "2019-01-01 08:00:10","2019-01-01 08:00:30", "2019-01-01 08:00:30", "2019-01-01 08:00:40","2019-01-01 08:00:50", "2019-

我在R中有一个数据集,格式如下:

data = data.table(
id = c(1, 2, 2, 2, 3, 3, 3, 3 ,3, 3),
Start = c("2019-03-01 09:15:36", 
"2019-01-01 08:00:00", "2019-01-01 08:00:10","2019-01-01 08:00:30",
"2019-01-01 08:00:30", "2019-01-01 08:00:40","2019-01-01 08:00:50",
"2019-01-01 08:01:10", "2019-01-01 08:01:20","2019-01-01 08:01:31"
))
data$Start = as.POSIXct(data$Start ,format = "%Y-%m-%d %H:%M:%S")

每一行表示与一个人的交互,每个人由id标识(在示例数据集中,我有3个人)。根据定义,在开始日期之间少于15秒的交互应该合并(只算一次)。这个15秒的窗口应该随着每次新的交互而扩展(参见第三个人的示例结果)

根据这条规则,对于
数据
,我想创建一个标识唯一交互的newID列。结果应该是:

data$newID 
[1] 1 2 2 3 4 4 4 5 5 5

这感觉像是在
数据中应该可以使用的东西。表
,对于循环没有低效的
,但我不能让它工作…

一种方法是计算差异,并在每次值大于15时更改组

data[, new := c(NA,diff.difftime(Start))][, new_id := cumsum(c(1, abs(na.omit(new)) >= 15))]
这就给了,


受@Sotos answer的启发,您可以按照常规删除任何不需要的列,我认为正确的解决方案是:

data$test = c(T,data$ID[-1] != data$ID[-nrow(data)] |
                           diff.difftime(data$Start) > 15)

这将生成一个布尔值,其中所有的
F
都应该被删除(尽管这不会创建一个新的ID,根据问题,它解决了隐式删除问题)。

我很好奇以下内容是否适用于您的数据:

library(data.table)

dt[
  ,
  session := frollapply(Start, 2, function(x) diff(x) >= 15, fill = 1),
  by = 'id'
][
  ,
  session := cumsum(session)
]

#     id               Start session
#  1:  1 2019-03-01 09:15:36       1
#  2:  2 2019-01-01 08:00:00       2
#  3:  2 2019-01-01 08:00:10       2
#  4:  2 2019-01-01 08:00:30       3
#  5:  3 2019-01-01 08:00:00       4
#  6:  3 2019-01-01 08:00:10       4
#  7:  3 2019-01-01 08:00:20       4
#  8:  3 2019-01-01 08:00:40       5
#  9:  3 2019-01-01 08:00:50       5
# 10:  3 2019-01-01 08:01:01       5
数据:


对于这个例子,它是有效的,但是如果下一个人的开始时间接近上一个人的最后一个开始时间,它就会失败。我更改了示例以反映这种情况,例如
data[,newID:=cumsum(id!=shift(id,fill=id[1L])|c(TRUE,diff(Start)>15L)]
@chinsoon12是的,这将回答最初的问题。我现在无法测试它,但您可以尝试使用更新的数据吗(虽然我认为通过使用“```by=id``你的答案不会与Sotos的答案陷入同一个问题。如果能再次将我的答案与10.000.000的数据集进行比较,那将是一件有趣的事情。)rows@DiogoSantos似乎可以处理更新的数据。但是我不知道它在10000000行上的性能如何-可能会很慢,这是大量的数据。有什么问题吗顺便告诉我结果如何。
library(data.table)

dt[
  ,
  session := frollapply(Start, 2, function(x) diff(x) >= 15, fill = 1),
  by = 'id'
][
  ,
  session := cumsum(session)
]

#     id               Start session
#  1:  1 2019-03-01 09:15:36       1
#  2:  2 2019-01-01 08:00:00       2
#  3:  2 2019-01-01 08:00:10       2
#  4:  2 2019-01-01 08:00:30       3
#  5:  3 2019-01-01 08:00:00       4
#  6:  3 2019-01-01 08:00:10       4
#  7:  3 2019-01-01 08:00:20       4
#  8:  3 2019-01-01 08:00:40       5
#  9:  3 2019-01-01 08:00:50       5
# 10:  3 2019-01-01 08:01:01       5
dt = data.table(
  id = c(1, 2, 2, 2, 3, 3, 3, 3 , 3, 3),
  Start = as.POSIXct(
    c(
      "2019-03-01 09:15:36",
      "2019-01-01 08:00:00",
      "2019-01-01 08:00:10",
      "2019-01-01 08:00:30",
      "2019-01-01 08:00:00",
      "2019-01-01 08:00:10",
      "2019-01-01 08:00:20",
      "2019-01-01 08:00:40",
      "2019-01-01 08:00:50",
      "2019-01-01 08:01:01"
    ),
    ,
    format = "%Y-%m-%d %H:%M:%S"
  )
)