【问题标题】:Finding gaps between intervals using data.table使用 data.table 查找区间之间的差距
【发布时间】:2015-06-04 21:51:42
【问题描述】:

我有以下问题:给定 data.table 中的一组不重叠区间,报告区间之间的间隙。

我已经在 SQL 中实现过一次,但是由于缺少前导函数或滞后函数,我在处理 data.table 时遇到了困难。为了完整起见,我有here SQL 代码。我知道该功能已在 data.table 版本 1.9.5 中实现。如changelog。那么这是否可以使用 data.table 而无需进行大量合并且没有滞后或领先功能?

原则上,只要性能不受影响,我并不完全反对使用合并(又名连接)。我认为这有一个简单的实现,但我不知道如何“获取”之前的结束时间作为我的差距表的开始时间。

例如:

# The numbers represent seconds from 1970-01-01 01:00:01
dat <- structure(
  list(ID = c(1L, 1L, 1L, 2L, 2L, 2L), 
       stime = structure(c(as.POSIXct("2014-01-15 08:00:00"),
                           as.POSIXct("2014-01-15 11:00:00"),
                           as.POSIXct("2014-01-16 11:30:00"),
                           as.POSIXct("2014-01-15 09:30:00"),
                           as.POSIXct("2014-01-15 12:30:00"),
                           as.POSIXct("2014-01-15 13:30:00")
                           ),
                         class = c("POSIXct", "POSIXt"), tzone = ""),
       etime = structure(c(as.POSIXct("2014-01-15 10:30:00"),
                           as.POSIXct("2014-01-15 12:00:00"),
                           as.POSIXct("2014-01-16 13:00:00"),
                           as.POSIXct("2014-01-15 11:00:00"),
                           as.POSIXct("2014-01-15 12:45:00"),
                           as.POSIXct("2014-01-15 14:30:00")
                           ), 
                         class = c("POSIXct", "POSIXt"), tzone = "")
  ),
  .Names = c("ID", "stime", "etime"),
  sorted = c("ID", "stime", "etime"),
  class = c("data.table", "data.frame"),
  row.names = c(NA,-6L)
)

dat <- data.table(dat)

这会导致:

ID               stime               etime
1  2014-01-15 10:30:00 2014-01-15 11:00:00
1  2014-01-15 12:00:00 2014-01-16 11:30:00
2  2014-01-15 11:00:00 2014-01-15 12:30:00
2  2014-01-15 12:45:00 2014-01-15 13:30:00

注意:间隔在几天内均匀报告。

【问题讨论】:

  • 你是不是漏了一行或者我漏了什么?
  • 旁注:dat &lt;- data.table(dat) 浪费内存。请改用setDT(dat)
  • 我认为这可以通过对 @eddi 在您之前的 Q 中的回答稍作改动来完成。
  • 亲爱的大卫,是的,我少了一排。感谢您的关注!

标签: r data.table


【解决方案1】:

David 的答案的一个变体,可能效率稍低,但输入起来更简单:

setkey(dat, stime)[, .(stime=etime[-.N], etime=stime[-1]), by=ID]

生产:

   ID               stime               etime
1:  1 2014-01-15 10:30:00 2014-01-15 11:00:00
2:  1 2014-01-15 12:00:00 2014-01-16 11:30:00
3:  2 2014-01-15 11:00:00 2014-01-15 12:30:00
4:  2 2014-01-15 12:45:00 2014-01-15 13:30:00

setkey 只是为了确保表格按时间排序。

【讨论】:

    【解决方案2】:

    如果我没有遗漏任何内容,则说明您在所需的输出中遗漏了一行,因此我尝试使用您提到的开发版本中的shift

    library(data.table) ## v >= 1.9.5
    indx <- dat[, .I[-.N], by = ID]$V1
    dat[, .(ID, stimes = etime, etime = shift(stime, type = "lead"))][indx]
    res
    #    ID               stime               etime
    # 1:  1 2014-01-15 10:30:00 2014-01-15 11:00:00
    # 2:  1 2014-01-15 12:00:00 2014-01-16 11:30:00
    # 3:  2 2014-01-15 11:00:00 2014-01-15 12:30:00
    # 4:  2 2014-01-15 12:45:00 2014-01-15 13:30:00
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-28
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多