将洪水事件ID分配给流时间序列(包括示例数据)时,通过data.table :: foverlaps函数重叠/剪切(包括示例数据)

时间:2019-01-18 04:11:41

标签: r data.table

我想将洪水事件ID分配给我的流量时间序列,并使用data.table的分组奇妙聚合(在我的情况下为事件ID)进行进一步分析。在进行任何分析之前,我已经尝试过在一个小的虚拟数据上进行尝试。这是我尝试过的。

加载data.table

library(data.table)

为测试创建一个小型数据集

d <- seq.Date(as.Date("1979-03-01"), as.Date("1979-04-30"), 1)
DT <- data.table(Date = d, Value = 1:length(d))

列表DT

DT[]

          Date Value
 1: 1979-03-01     1
 2: 1979-03-02     2
 3: 1979-03-03     3
 4: 1979-03-04     4
 5: 1979-03-05     5
 ---
 57: 1979-04-26    57
 58: 1979-04-27    58
 59: 1979-04-28    59
 60: 1979-04-29    60
 61: 1979-04-30    61

创建一个包含事件ID的查找表

s <- as.Date(c("1979-03-14", "1979-03-29", "1979-04-16"))
e <- as.Date(c("1979-03-19", "1979-04-11", "1979-04-24"))
look_up <- data.table(Event = paste0("#", 1:3), Start = s, End = e)

print look_up data.table:

look_up[]

   Event      Start        End
1:    #1 1979-03-14 1979-03-19
2:    #2 1979-03-29 1979-04-11
3:    #3 1979-04-16 1979-04-24

StratEnd列上的设置键:

setkeyv(look_up, c("Start", "End"))

添加一个新列TMP,其值与DT中的Date相同:

DT[, TMP := Date]

执行重叠联接以在每个事件ID中生成时间序列:

Z <- foverlaps(DT,
               look_up,
               by.x = c("Date", "TMP"),
               by.y = c("Start", "End"),
               type = "within",
               nomatch = 0)

删除TMP列并查看结果:

Z[, TMP := NULL]
Z[]

    Event      Start        End       Date Value
 1:    #1 1979-03-14 1979-03-19 1979-03-14    14
 2:    #1 1979-03-14 1979-03-19 1979-03-15    15
 3:    #1 1979-03-14 1979-03-19 1979-03-16    16
 4:    #1 1979-03-14 1979-03-19 1979-03-17    17
 5:    #1 1979-03-14 1979-03-19 1979-03-18    18
 6:    #1 1979-03-14 1979-03-19 1979-03-19    19
 7:    #2 1979-03-29 1979-04-11 1979-03-29    29
 8:    #2 1979-03-29 1979-04-11 1979-03-30    30
 9:    #2 1979-03-29 1979-04-11 1979-03-31    31
10:    #2 1979-03-29 1979-04-11 1979-04-01    32
11:    #2 1979-03-29 1979-04-11 1979-04-02    33
12:    #2 1979-03-29 1979-04-11 1979-04-03    34
13:    #2 1979-03-29 1979-04-11 1979-04-04    35
14:    #2 1979-03-29 1979-04-11 1979-04-05    36
15:    #2 1979-03-29 1979-04-11 1979-04-06    37
16:    #2 1979-03-29 1979-04-11 1979-04-07    38
17:    #2 1979-03-29 1979-04-11 1979-04-08    39
18:    #2 1979-03-29 1979-04-11 1979-04-09    40
19:    #2 1979-03-29 1979-04-11 1979-04-10    41
20:    #2 1979-03-29 1979-04-11 1979-04-11    42
21:    #3 1979-04-16 1979-04-24 1979-04-16    47
22:    #3 1979-04-16 1979-04-24 1979-04-17    48
23:    #3 1979-04-16 1979-04-24 1979-04-18    49
24:    #3 1979-04-16 1979-04-24 1979-04-19    50
25:    #3 1979-04-16 1979-04-24 1979-04-20    51
26:    #3 1979-04-16 1979-04-24 1979-04-21    52
27:    #3 1979-04-16 1979-04-24 1979-04-22    53
28:    #3 1979-04-16 1979-04-24 1979-04-23    54
29:    #3 1979-04-16 1979-04-24 1979-04-24    55
    Event      Start        End       Date Value

计算每个事件的平均值(基于事件ID)并打印结果:

Z[, .(Average = mean(Value)), by = Event][]

   Event Average
1:    #1    16.5
2:    #2    35.5
3:    #3    51.0

上述小型虚拟数据集的结果正是我实际流量时间序列所需要的。但是,使用实际数据遇到了一些意外的结果。让我通过尝试一小部分真实流量数据来说明我的问题。可以从我的保管箱下载该数据集(格式为data.frame的常规rds)(文件大小:15K)20-minute flow data

一旦此flow_data.rds位于工作文件夹中,我可以通过以下方式加载它:

flow_data <- readRDS("flow_data.rds")

data.frame转换为data.table对象:

setDT(flow_data)

对于此数据集,我已经确定了三个流事件(流值大于180),并且可以以data.table格式手动创建查找表:

event_id <-
  data.table(
    Event = paste0("#", 1:3),
    Start = as.POSIXct(
      c(
        "1968-04-19 15:20:00",
        "1968-04-25 15:40:00",
        "1968-06-07 15:00:00"
      ),
      tz = "Etc/GMT-12",
      format = "%Y-%m-%d %H:%M:%S"
    ),
    End = as.POSIXct(
      c(
        "1968-04-24 07:20:00",
        "1968-04-27 05:40:00",
        "1968-06-10 21:20:00"
      ),
      tz = "Etc/GMT-12",
      format = "%Y-%m-%d %H:%M:%S"
    )
  )

显示此event_id数据表。

event_id[]

   Event               Start                 End
1:    #1 1968-04-19 15:20:00 1968-04-24 07:20:00
2:    #2 1968-04-25 15:40:00 1968-04-27 05:40:00
3:    #3 1968-06-07 15:00:00 1968-06-10 21:20:00

在flow_data中添加与“时间”列具有相同值的新列:

flow_data[, TMP := Time]

设置event_id data.table的键:

setkeyv(event_id, c("Start", "End"))

使用event_id重叠加入flow_data并仅将流时间序列(行)保持在每个事件ID周期内:

flood_timeseries = foverlaps(flow_data,
                             event_id,
                             by.x = c("Time", "TMP"),
                             by.y = c("Start", "End"),
                             type = "within",
                             nomatch = 0)

删除不需要的TMP列:

flood_timeseries[, TMP := NULL]

现在,我得到了一些意外的结果。通过检查flood_timeseries data.table,我发现:

flood_timeseries[1:435]

     Event               Start                 End                Time    Flow
  1:    #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-19 15:20:00 180.595
  2:    #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-19 15:40:00 184.468
  3:    #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-19 16:00:00 188.342
  4:    #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-19 16:20:00 192.215
  5:    #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-19 16:40:00 196.088
 ---                                                                          
431:    #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-25 14:40:00 174.323
432:    #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-25 15:00:00 176.366
433:    #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-25 15:20:00 178.410
434:    #2 1968-04-25 15:40:00 1968-04-27 05:40:00 1968-04-25 15:40:00 180.454
435:    #2 1968-04-25 15:40:00 1968-04-27 05:40:00 1968-04-25 16:00:00 182.498

我的第一个事件应该以{{1​​}}结束,而不是如上所述的1968-04-24 07:20:00

同样,#2事件的结束时间也是错误的;事件2的结束时间应为1968-04-25 15:20:00,而不是1968-04-27 05:40:00,如下所示:

1968-06-07 14:40:00

所有三个事件的开始时间似乎都可以,但是事件1和2的情况并非如此(事件3的结束时间似乎可以)。

我列出了虚拟数据和真实数据子集之间的主要区别:

  • flood_timeseries[1:3529] Event Start End Time Flow 1: #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-19 15:20:00 180.595 2: #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-19 15:40:00 184.468 3: #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-19 16:00:00 188.342 4: #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-19 16:20:00 192.215 5: #1 1968-04-19 15:20:00 1968-04-24 07:20:00 1968-04-19 16:40:00 196.088 --- 3525: #2 1968-04-25 15:40:00 1968-04-27 05:40:00 1968-06-07 14:00:00 170.283 3526: #2 1968-04-25 15:40:00 1968-04-27 05:40:00 1968-06-07 14:20:00 174.938 3527: #2 1968-04-25 15:40:00 1968-04-27 05:40:00 1968-06-07 14:40:00 178.622 3528: #3 1968-06-07 15:00:00 1968-06-10 21:20:00 1968-06-07 15:00:00 182.292 3529: #3 1968-06-07 15:00:00 1968-06-10 21:20:00 1968-06-07 15:20:00 185.963 用于我的真实数据,而不是虚拟数据集的POSIXct
  • 虚拟数据集的值列没有数据空白,但是在我的真实数据集中,存在数据空白(如Date

我想通过应用NA函数为我的流程时间序列分配事件ID时做错了什么。我有非常大的数据集,其中包含多个流场数据。如果可能,使用data.table::foverlaps()foverlaps循环快得多。有人可以帮我吗?

我正在使用for上运行的data.table 1.12.0

非常感谢。

0 个答案:

没有答案