使用 data.table 查找间隔之间的差距
Finding gaps between intervals using data.table
我有以下问题:给定 data.table 中的一组 非重叠 间隔,报告间隔之间的间隙。
我在 SQL 中实现过一次,但是由于缺少前导函数或滞后函数,我在 data.table 中苦苦挣扎。为了完整起见,我有 here the SQL code. I know the functionality has been implemented in data.table version 1.9.5. as by the changelog。那么 data.table 是否可以在不进行大量合并且没有滞后或引导功能的情况下实现?
原则上,只要性能不受影响,我并不完全反对使用合并(又名连接)。我认为这很容易实现,但我不知道如何 "get" 之前的结束时间成为我的间隔 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
注意:差距是跨天平均报告的。
如果我没有遗漏任何内容,那么您在所需的输出中遗漏了一行,所以这是我尝试使用您提到的开发版本中的 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
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只是为了确保table按时间排序。
我有以下问题:给定 data.table 中的一组 非重叠 间隔,报告间隔之间的间隙。
我在 SQL 中实现过一次,但是由于缺少前导函数或滞后函数,我在 data.table 中苦苦挣扎。为了完整起见,我有 here the SQL code. I know the functionality has been implemented in data.table version 1.9.5. as by the changelog。那么 data.table 是否可以在不进行大量合并且没有滞后或引导功能的情况下实现?
原则上,只要性能不受影响,我并不完全反对使用合并(又名连接)。我认为这很容易实现,但我不知道如何 "get" 之前的结束时间成为我的间隔 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
注意:差距是跨天平均报告的。
如果我没有遗漏任何内容,那么您在所需的输出中遗漏了一行,所以这是我尝试使用您提到的开发版本中的 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
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只是为了确保table按时间排序。