【问题标题】:Join two datasets with closest timestamp interval加入两个具有最接近时间戳间隔的数据集
【发布时间】:2019-08-12 17:50:24
【问题描述】:

我编辑了我的问题 - 请阅读第二部分 编辑 2

我需要使用壁橱时间戳加入两个数据集。第一个数据集是来自移动应用程序的日记数据集:

    df1 <- data.frame(stringsAsFactors=FALSE,
        datetime = c("2019-03-19T13:26:52Z", "2019-03-19T13:26:19Z",
                     "2019-03-19T13:23:46Z", "2019-03-19T13:22:20Z",
                     "2019-03-19T13:09:56Z", "2019-03-19T13:06:04Z", "2019-03-19T13:05:21Z",
                     "2019-03-19T13:04:37Z", "2019-03-19T12:47:28Z",
                     "2019-03-19T12:46:42Z"),
       transport = c("Trainride", "Trainride", "Trainride", "Trainride",
                     "Trainride", "Trainride", "Trainride", "Trainride",
                     "Trainride", "Trainride"),
              id = c("5-3", "5-3", "5-3", "5-3", "5-3", "5-3", "5-3", "5-3", "5-3",
                     "5-3"),
            disc = c("start", "stop", "start", "stop", "start", "stop", "start",
                     "stop", "start", "stop")
    )
 # datetime dttr object   
    df1 <- df1 %>% 
      mutate(datetime = lubridate::as_datetime(datetime))

这里:

              datetime transport  id  disc
1  2019-03-19 13:26:52 Trainride 5-3 start
2  2019-03-19 13:26:19 Trainride 5-3  stop
3  2019-03-19 13:23:46 Trainride 5-3 start
4  2019-03-19 13:22:20 Trainride 5-3  stop
5  2019-03-19 13:09:56 Trainride 5-3 start
6  2019-03-19 13:06:04 Trainride 5-3  stop
7  2019-03-19 13:05:21 Trainride 5-3 start
8  2019-03-19 13:04:37 Trainride 5-3  stop
9  2019-03-19 12:47:28 Trainride 5-3 start
10 2019-03-19 12:46:42 Trainride 5-3  stop

第二个数据集是来自加速度计日志的数据集,显示运动(=INVH)或空闲(=NIVH):

df2 <- data.frame(stringsAsFactors=FALSE,
           datetime = c("2019-03-19T23:20:00Z", "2019-03-19T23:17:30Z",
                        "2019-03-19T13:08:00Z", "2019-03-19T13:07:00Z",
                        "2019-03-19T12:38:45Z", "2019-03-19T12:32:45Z",
                        "2019-03-19T11:13:15Z", "2019-03-19T11:11:45Z", "2019-03-19T10:17:45Z",
                        "2019-03-19T10:16:45Z"),
                 id = c("5-3", "5-3", "5-3", "5-3", "5-3", "5-3", "5-3", "5-3", "5-3",
                        "5-3"),
               code = c("NIVH", "INVH", "NIVH", "INVH", "NIVH", "INVH", "NIVH",
                        "INVH", "NIVH", "INVH")
       )
 # datetime dttr object 
df2 <- df2 %>% 
  mutate(datetime = lubridate::as_datetime(datetime))

这里:

              datetime  id code
1  2019-03-19 23:20:00 5-3 NIVH
2  2019-03-19 23:17:30 5-3 INVH
3  2019-03-19 13:08:00 5-3 NIVH
4  2019-03-19 13:07:00 5-3 INVH
5  2019-03-19 12:38:45 5-3 NIVH
6  2019-03-19 12:32:45 5-3 INVH
7  2019-03-19 11:13:15 5-3 NIVH
8  2019-03-19 11:11:45 5-3 INVH
9  2019-03-19 10:17:45 5-3 NIVH
10 2019-03-19 10:16:45 5-3 INVH

我需要根据时间戳字段之间的时间差连接两个数据帧。例如,在 df1 上左连接以查看应用日志数据与真实加速度计日志的一致性。简单的左连接在这里不起作用,因为在大多数情况下都有延迟时间。所以我的问题是如何加入这两个数据集 基于差异为最小绝对差异的记录。

编辑 2 --- @soren 建议的解决方案很有帮助,但是如果我将 start datetime 和 endtime 设置为有一个 interval ,将不起作用。有什么想法吗?

df1 <- df1 %>% 
  mutate(datetime = lubridate::as_datetime(datetime)) %>% 
  arrange(datetime) %>% 
  mutate(datetime_end = lead(datetime), 
         # Create an interval object.
         Travel_Interval = lubridate::interval(start = datetime, end = datetime_end))

【问题讨论】:

  • 时滞的方向是什么? df2 中的时间戳是否总是落后于 df1 中的时间戳?
  • 不,实际上没有逻辑,df2可能比df1落后或领先几分钟

标签: r datatable dplyr timestamp


【解决方案1】:

滚动连接将完成此操作,按最近的日期时间连接数据框。以下使用data.table的解决方案

library(data.table)
dt1 <- as.data.table(df1)
setkeyv(dt1,"datetime")

dt2 <- as.data.table(df2)
setkeyv(dt2,"datetime")
dt2[,nearest_date:=datetime]

dt2[dt1,roll="nearest"]

> dt2[dt1,roll="nearest"]
               datetime  id code        nearest_date transport i.id  disc
 1: 2019-03-19 12:46:42 5-3 NIVH 2019-03-19 12:38:45 Trainride  5-3  stop
 2: 2019-03-19 12:47:28 5-3 NIVH 2019-03-19 12:38:45 Trainride  5-3 start
 3: 2019-03-19 13:04:37 5-3 INVH 2019-03-19 13:07:00 Trainride  5-3  stop
 4: 2019-03-19 13:05:21 5-3 INVH 2019-03-19 13:07:00 Trainride  5-3 start
 5: 2019-03-19 13:06:04 5-3 INVH 2019-03-19 13:07:00 Trainride  5-3  stop
 6: 2019-03-19 13:09:56 5-3 NIVH 2019-03-19 13:08:00 Trainride  5-3 start
 7: 2019-03-19 13:22:20 5-3 NIVH 2019-03-19 13:08:00 Trainride  5-3  stop
 8: 2019-03-19 13:23:46 5-3 NIVH 2019-03-19 13:08:00 Trainride  5-3 start
 9: 2019-03-19 13:26:19 5-3 NIVH 2019-03-19 13:08:00 Trainride  5-3  stop
10: 2019-03-19 13:26:52 5-3 NIVH 2019-03-19 13:08:00 Trainride  5-3 start

请注意,添加了附加列“nearest_date”dt2[,nearest_date:=datetime],以便在连接 dt2 和 dt1 时,保留日期时间的值(或可用于差异计算)。而默认情况下将数据集合并/连接在一起仅返回主键列。通常,这是可取的,因为连接的列通常是相同的。在这里,它们不是滚动连接,保留列或手动创建冗余列很有用,如这里所示。

另请注意,最接近的id 值和datetime 也可能与应用程序相关(OP 中仅给出一个 id 值)。这是通过设置连接语法中使用的键来完成的:

setkeyv(dt2,c("id","datetime"))
setkeyv(dt1,c("id","datetime"))

【讨论】:

  • 仅供参考,on= 是另一种选择,包作者在此答案末尾推荐stackoverflow.com/a/20057411
  • @Frank 有趣的文章,感谢您的参考。值得注意的是,对于较大的数据集,在键控连接和临时连接中可能会在速度/效率方面进行权衡,如果应用程序寻求绝对的效率提升,则可以使用这两种方法。
  • 谢谢两位。 @Soren 这很有帮助,是的,真实数据集有几个 id,我需要将 id 和 datetime 设置为键。
猜你喜欢
  • 2019-09-21
  • 2015-10-27
  • 1970-01-01
  • 2023-01-21
  • 2020-09-23
  • 2020-04-03
  • 1970-01-01
  • 2021-01-09
  • 2016-03-23
相关资源
最近更新 更多