【问题标题】:R - Extract temporally independent events from dataframeR - 从数据帧中提取时间独立的事件
【发布时间】:2021-08-05 11:21:56
【问题描述】:

我想仅提取并保留被视为彼此时间独立事件的记录。

在此将时间独立事件归类为在给定时间段内发生在同一类别(列:“cat”)、同一位置(列:“loc”)的任何事件(数据框中的行)从彼此。时间段设置为 1800 秒(即 30 分钟)。例如,如果类别“X”在同一位置(即“1”)的同一类别(即“X”)的另一个事件发生后 1800 秒内记录在位置“1”,那么只有第一个记录应该被保存。而在类别“X”中,记录在位置“1”,两个或多个后续事件之间的时间差为 1801 秒,那么它将作为两个记录保存。

我希望这个描述有意义吗?

以下是一些示例数据:

df <- structure(
  list(
    cat = c("X", "X", "X", "X", "X", "X", "X", "X", "X", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Z", "Z", "Z", "Z", "Z", "Z", "Z"), 
    loc = c(1, 1, 1, 1, 1, 1, 2, 3, 3, 1, 1, 2, 3, 3, 3, 4, 2, 3, 3, 3, 3, 3, 4), 
    date_time = structure(c(1609451755, 1609452355, 1609581600, 1609582202, 1609583403, 1609585200, 1609668005, 1609538155, 1609841700, 1609495204, 1609583406, 1609668000, 1609539071, 1609756205, 1609758001, 1609581600, 1609668067, 1609451793, 1609452213, 1609452633, 1609495200, 1609626404, 1609581600), tzone = "", class = c("POSIXct", "POSIXt")), 
    date = structure(c(18627, 18628, 18629, 18629, 18629, 18629, 18630, 18628, 18632, 18628, 18629, 18630, 18629, 18631, 18631, 18629, 18630, 18627, 18628, 18628, 18628, 18630, 18629), class = "Date"), 
    time = c("23:55:55", "00:05:55", "12:00:00", "12:10:02", "12:30:03", "13:00:00", "12:00:05", "23:55:55", "12:15:00", "12:00:04", "12:30:06", "12:00:00", "00:11:11", "12:30:05", "13:00:01", "12:00:00", "12:01:07", "23:56:33", "00:03:33", "00:10:33", "12:00:00", "00:26:44", "12:00:00")), 
  row.names = c(NA, -23L), class = "data.frame")

在控制台打印出来的数据是这样的:

> df
   cat loc           date_time       date     time
1    X   1 2020-12-31 23:55:55 2020-12-31 23:55:55
2    X   1 2021-01-01 00:05:55 2021-01-01 00:05:55
3    X   1 2021-01-02 12:00:00 2021-01-02 12:00:00
4    X   1 2021-01-02 12:10:02 2021-01-02 12:10:02
5    X   1 2021-01-02 12:30:03 2021-01-02 12:30:03
6    X   1 2021-01-02 13:00:00 2021-01-02 13:00:00
7    X   2 2021-01-03 12:00:05 2021-01-03 12:00:05
8    X   3 2021-01-01 23:55:55 2021-01-01 23:55:55
9    X   3 2021-01-05 12:15:00 2021-01-05 12:15:00
10   Y   1 2021-01-01 12:00:04 2021-01-01 12:00:04
11   Y   1 2021-01-02 12:30:06 2021-01-02 12:30:06
12   Y   2 2021-01-03 12:00:00 2021-01-03 12:00:00
13   Y   3 2021-01-02 00:11:11 2021-01-02 00:11:11
14   Y   3 2021-01-04 12:30:05 2021-01-04 12:30:05
15   Y   3 2021-01-04 13:00:01 2021-01-04 13:00:01
16   Y   4 2021-01-02 12:00:00 2021-01-02 12:00:00
17   Z   2 2021-01-03 12:01:07 2021-01-03 12:01:07
18   Z   3 2020-12-31 23:56:33 2020-12-31 23:56:33
19   Z   3 2021-01-01 00:03:33 2021-01-01 00:03:33
20   Z   3 2021-01-01 00:10:33 2021-01-01 00:10:33
21   Z   3 2021-01-01 12:00:00 2021-01-01 12:00:00
22   Z   3 2021-01-03 00:26:44 2021-01-03 00:26:44
23   Z   4 2021-01-02 12:00:00 2021-01-02 12:00:00

我想要的是一些可以将其转换成这样的代码:

> df_wanted
   cat loc           date_time       date     time
1    X   1 2020-12-31 23:55:55 2020-12-31 23:55:55

3    X   1 2021-01-02 12:00:00 2021-01-02 12:00:00

5    X   1 2021-01-02 12:30:03 2021-01-02 12:30:03

7    X   2 2021-01-03 12:00:05 2021-01-03 12:00:05
8    X   3 2021-01-01 23:55:55 2021-01-01 23:55:55
9    X   3 2021-01-05 12:15:00 2021-01-05 12:15:00
10   Y   1 2021-01-01 12:00:04 2021-01-01 12:00:04
11   Y   1 2021-01-02 12:30:06 2021-01-02 12:30:06
12   Y   2 2021-01-03 12:00:00 2021-01-03 12:00:00
13   Y   3 2021-01-02 00:11:11 2021-01-02 00:11:11
14   Y   3 2021-01-04 12:30:05 2021-01-04 12:30:05

16   Y   4 2021-01-02 12:00:00 2021-01-02 12:00:00
17   Z   2 2021-01-03 12:01:07 2021-01-03 12:01:07
18   Z   3 2020-12-31 23:56:33 2020-12-31 23:56:33


21   Z   3 2021-01-01 12:00:00 2021-01-01 12:00:00
22   Z   3 2021-01-03 00:26:44 2021-01-03 00:26:44
23   Z   4 2021-01-02 12:00:00 2021-01-02 12:00:00

您可以在上方看到因在 1800 秒阈值内、同一位置、同一类别而被删除的行。

任何建议将不胜感激!

【问题讨论】:

  • 我认为这接近你想要的。 filter(df, !(cat == lag(cat) &amp; loc == lag(loc) &amp; date_time - lag(date_time, default = as.Date("2020-01-01")) &lt; 30))

标签: r datetime dplyr tidyverse


【解决方案1】:

您可以使用difftime 计算连续date_time 值之间的时间差,并仅保留每个catloc 内相差大于30 分钟的行。

library(dplyr)

df %>%
  group_by(cat, loc) %>%
  filter(as.integer(difftime(date_time, lag(date_time), units = 'secs')) > 1800 | row_number() == 1) %>%
  ungroup

【讨论】:

  • 感谢 Ronak,上面的代码非常接近,但它删除了一些额外的行。我认为lag 函数会发生这种情况,如果有多个事件落在 1800 秒阈值内,那么它会计算两个连续事件之间的差异,但会忽略之前的任何事件。如果我的解释措辞不当,我深表歉意。基本上,如果在一个事件之后有一个或多个事件(在给定的站点,对于给定的类别),那么如果这些事件发生在 1800 秒的时间内,那么只有这组事件中的第一个事件被保留。
  • 我觉得我很困惑。你能举个例子解释一下吗?您共享的数据是否会发生这种情况?
  • 感谢 Ronak,这很难解释。但是如果您查看第 5 行提供的数据,您会注意到您提供的代码也删除了这一行,但实际上是第 5 行应该保留,因为它在前一个独立事件(即第 3 行)的 1800 秒阈值内,但代码仅查看前一个事件并与该事件进行比较(即第 4 行)。我不确定,这更有意义吗?请告诉我
  • Ronak 和我在同一条路径上(我们的代码产生相同的输出)。您不需要显式调用 difftime,因为具有类 datetime 的对象为 - 调度了一个方法,该方法了解如何减去时间。仍在努力获得 OP 想要的东西......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-28
  • 1970-01-01
  • 2019-05-18
相关资源
最近更新 更多