R 使用data.table进行日期时间比较

R 使用data.table进行日期时间比较,r,data.table,R,Data.table,我有两个data.tables,我希望扩展数据的datetime大于Ydata的StartTime,小于Ydata的EndTime 我试图写一个练习,但似乎丢失了数据 library(data.table) xdata=data.table(First=c("X1","X2","X3","X1","X3","X2"), Second=c("A1","A2","B3","A1","B3","C4"), Time=c("2018-09-01 09:

我有两个data.tables,我希望扩展数据的datetime大于Ydata的StartTime,小于Ydata的EndTime

我试图写一个练习,但似乎丢失了数据

library(data.table)
xdata=data.table(First=c("X1","X2","X3","X1","X3","X2"),
             Second=c("A1","A2","B3","A1","B3","C4"),
             Time=c("2018-09-01 09:21:03","2018-10-15 20:24:59","2018-10-15 12:06:46",
                "2018-10-16 18:21:11","2018-10-16 21:21:12","2018-10-17 00:00:01"))


ydata=data.table(ID=c("YY","ZZ","AA","HH"),
             StartTime=c("2018-08-21 08:00:00","2018-09-01 08:00:00",
                "2018-10-15 08:00:00","2018-10-18 08:00:00"),
             EndTime=c("2018-08-21 21:20:00","2018-09-01 21:20:00",
                     "2018-10-15 21:20:00","2018-10-18 21:20:00"))

library(dplyr)
outputXY <- xdata %>% filter(Time > ydata$StartTime & Time < ydata$EndTime)
但我需要的是

1 X1  A1  2018-09-01 09:21:03
2 X3  B3  2018-10-15 12:06:46
我试图修改代码,但结果是一样的

outputXY <- xdata[Time > ydata$StartTime & Time < ydata$EndTime]
outputXY ydata$StartTime和Time

我怎样才能修改它并做我想做的事?

也许像这样假设每天的时间框架相同:

编辑:仅考虑
ydata中存在的日期

library(data.table)

xdata=data.table(First=c("X1","X2","X3","X1","X3","X2"),
                 Second=c("A1","A2","B3","A1","B3","C4"),
                 Time=c("2018-09-01 09:21:03","2018-10-15 20:24:59","2018-10-15 12:06:46",
                        "2018-10-16 18:21:11","2018-10-16 21:21:12","2018-10-17 00:00:01"))

ydata=data.table(ID=c("YY","ZZ","AA","HH"),
                 StartTime=c("2018-08-21 08:00:00","2018-09-01 08:00:00",
                             "2018-10-15 08:00:00","2018-10-18 08:00:00"),
                 EndTime=c("2018-08-21 21:20:00","2018-09-01 21:20:00",
                           "2018-10-15 21:20:00","2018-10-18 21:20:00"))

xdata[, Date := as.Date(Time)]
ydata[, Date := as.Date(StartTime)]
xdata <- xdata[ydata, on = "Date", nomatch = 0]
outputXY <- xdata[Time > StartTime & Time < EndTime]
outputXY[, c("Date", "StartTime", "EndTime", "ID") := NULL]

print(outputXY)

也许像这样假设每天的时间框架相同:

编辑:仅考虑
ydata中存在的日期

library(data.table)

xdata=data.table(First=c("X1","X2","X3","X1","X3","X2"),
                 Second=c("A1","A2","B3","A1","B3","C4"),
                 Time=c("2018-09-01 09:21:03","2018-10-15 20:24:59","2018-10-15 12:06:46",
                        "2018-10-16 18:21:11","2018-10-16 21:21:12","2018-10-17 00:00:01"))

ydata=data.table(ID=c("YY","ZZ","AA","HH"),
                 StartTime=c("2018-08-21 08:00:00","2018-09-01 08:00:00",
                             "2018-10-15 08:00:00","2018-10-18 08:00:00"),
                 EndTime=c("2018-08-21 21:20:00","2018-09-01 21:20:00",
                           "2018-10-15 21:20:00","2018-10-18 21:20:00"))

xdata[, Date := as.Date(Time)]
ydata[, Date := as.Date(StartTime)]
xdata <- xdata[ydata, on = "Date", nomatch = 0]
outputXY <- xdata[Time > StartTime & Time < EndTime]
outputXY[, c("Date", "StartTime", "EndTime", "ID") := NULL]

print(outputXY)

<>你需要考虑如何加入这两个数据集。现在我最好的猜测是,您需要的所有扩展数据时间都在ydata开始时间和结束时间的任意组合之间。但是您的代码正在处理向量,因此它正在检查每个向量元素是否通过大于和小于测试

让我们展示一下数据是如何按照您的方式排列的:

xdata$Time              ydata$StartTime        ydata$EndTime
"2018-09-01 09:21:03"   "2018-08-21 08:00:00"  "2018-08-21 21:20:00"
"2018-10-15 20:24:59"   "2018-09-01 08:00:00"  "2018-09-01 21:20:00"
"2018-10-15 12:06:46"   "2018-10-15 08:00:00"  "2018-10-15 21:20:00"
"2018-10-16 18:21:11"   "2018-10-18 08:00:00"  "2018-10-18 21:20:00"
"2018-10-16 21:21:12"   "2018-08-21 08:00:00"  "2018-08-21 21:20:00"  # recycled                     
"2018-10-17 00:00:01"   "2018-09-01 08:00:00"  "2018-09-01 21:20:00"  # recycled  
请注意,当数据与矢量元素并排显示时,您可以看到满足条件的唯一一行是
“2018-10-15 12:06:46”“2018-10-15 08:00:00”“2018-10-15 21:20:00”

一种方法是使用
CJ
功能创建一个包含所有时间和开始时间组合的data.table。然后,我们可以创建一个查找,以确定该时间是否在任何可能的时间范围内

# Create a table with all combinations to Time and StartTime
timecheck <- CJ(Time = xdata$Time,StartTime = ydata$StartTime)

# Join in the EndTime
timecheck <- merge(timecheck,ydata,by = "StartTime")

# Use vector math to check if the Time is between StartTime and EndTime
# for every comination of possibilities.
timecheck[,in_range := (Time > StartTime & Time < EndTime)]

# group_by Time and create a summary of whether or not that time is in
# any range
timecheck <- timecheck[,any(in_range),.(Time)]

outputXY <- xdata %>% filter(timecheck$V1)

我建议您运行代码的每个步骤,并查看每个中间步骤中存储的内容。此外,还有其他方法可以用循环来减少内存,但不能利用向量操作。

您需要考虑如何加入这两个数据集。现在我最好的猜测是,您需要的所有扩展数据时间都在ydata开始时间和结束时间的任意组合之间。但是您的代码正在处理向量,因此它正在检查每个向量元素是否通过大于和小于测试

让我们展示一下数据是如何按照您的方式排列的:

xdata$Time              ydata$StartTime        ydata$EndTime
"2018-09-01 09:21:03"   "2018-08-21 08:00:00"  "2018-08-21 21:20:00"
"2018-10-15 20:24:59"   "2018-09-01 08:00:00"  "2018-09-01 21:20:00"
"2018-10-15 12:06:46"   "2018-10-15 08:00:00"  "2018-10-15 21:20:00"
"2018-10-16 18:21:11"   "2018-10-18 08:00:00"  "2018-10-18 21:20:00"
"2018-10-16 21:21:12"   "2018-08-21 08:00:00"  "2018-08-21 21:20:00"  # recycled                     
"2018-10-17 00:00:01"   "2018-09-01 08:00:00"  "2018-09-01 21:20:00"  # recycled  
请注意,当数据与矢量元素并排显示时,您可以看到满足条件的唯一一行是
“2018-10-15 12:06:46”“2018-10-15 08:00:00”“2018-10-15 21:20:00”

一种方法是使用
CJ
功能创建一个包含所有时间和开始时间组合的data.table。然后,我们可以创建一个查找,以确定该时间是否在任何可能的时间范围内

# Create a table with all combinations to Time and StartTime
timecheck <- CJ(Time = xdata$Time,StartTime = ydata$StartTime)

# Join in the EndTime
timecheck <- merge(timecheck,ydata,by = "StartTime")

# Use vector math to check if the Time is between StartTime and EndTime
# for every comination of possibilities.
timecheck[,in_range := (Time > StartTime & Time < EndTime)]

# group_by Time and create a summary of whether or not that time is in
# any range
timecheck <- timecheck[,any(in_range),.(Time)]

outputXY <- xdata %>% filter(timecheck$V1)

我建议您运行代码的每个步骤,并查看每个中间步骤中存储的内容。此外,还有其他一些方法可以使用循环来实现这一点,这些方法可能占用更少的内存,但不利用向量运算。

如果我理解正确,OP希望找到
xdata
Time
位于
ydata
中任何给定间隔(
StartTime
EndTime
)内的所有行

包中的
inrange()
函数就是为此而构建的。由于OP要求使用开放时间间隔(
Time>ydata$StartTime&Time
),我们需要告知
inrange()
以排除终点

library(data.table)
# coerce to POSIXct to allow for comparison operations
xdata[, Time := as.POSIXct(Time)]
tcols <- c("StartTime", "EndTime")
ydata[, (tcols) := lapply(.SD, as.POSIXct), .SDcols = tcols]

# subsetting with open intervals
xdata[inrange(Time, ydata$StartTime, ydata$EndTime, incbounds = FALSE)]
因此,3行扩展数据满足条件



如果OP要求关闭间隔(
Time>=ydata$StartTime&Time如果我理解正确,OP希望在
ydata
中查找
xdata
Time
位于任何给定间隔(
StartTime
EndTime
)内的所有行

包中的
inrange()
函数就是为此目的而构建的。由于OP要求使用开放间隔(
Time>ydata$StartTime&Time
),我们需要告诉
inrange()
)以排除端点

library(data.table)
# coerce to POSIXct to allow for comparison operations
xdata[, Time := as.POSIXct(Time)]
tcols <- c("StartTime", "EndTime")
ydata[, (tcols) := lapply(.SD, as.POSIXct), .SDcols = tcols]

# subsetting with open intervals
xdata[inrange(Time, ydata$StartTime, ydata$EndTime, incbounds = FALSE)]
因此,3行扩展数据满足条件



如果OP要求关闭间隔(
Time>=ydata$StartTime&Time扩展数据和ydata之间的链接是什么?不清楚为什么会有这种期望。请注意,一个表中有6条记录,另一个表中有4条记录。将data.table字段与向量进行比较不起作用。扩展数据和ydata之间的链接是什么?不清楚为什么会有这种期望。注意t一个表中有6条记录,另一个表中有4条记录。将data.table字段与向量进行比较不起作用。您只是创建了原始数据中没有的新的开始时间和结束时间值?正如基于假设的答案中所述。现在添加了另一个筛选器。您只是创建了新的开始时间和结束时间值不在原始数据中?如基于假设的答案中所述。现在添加了另一个筛选器。
# subsetting with closed intervals
xdata[Time %inrange% ydata[, .(StartTime, EndTime)]]