在不规则时间序列上计算滚动函数的时间间隔。

3

我正在寻求一个与优化的时间窗口滚动函数非常相关的问题的帮助。

我想计算我的函数(在下面的例子中是sum,但也可以很容易地是min或max或median...)在过去一段时间内的时间步长上,但不超过这个时间。因此,如果我感兴趣的时间持续8分钟,而我的时间步长为2,2,5,对于第三个时间步长,我只想对最后2个数字求和(这将给出总时间7),不包括第一个数字,因为它会给出总时间9。所以基本上我想要尽可能接近我的持续时间,但不要超过。

为了背景,这些值是降雨数据,mindiff 是记录间隔。因此,如果我的时间步长为5分钟,则雨水可能发生在那5分钟的任何时间。我只想找到我能够保证在过去8分钟内降落的雨水,所以任何开始时间在8分钟前的时间步长我都不能确定,我想要排除。

下面的代码非常接近我想要的内容(从上述提到的Uwe的答案进行了调整),但它包括一个点之前,除非间隔恰好等于我的持续时间。我也希望它在时间步长大于持续时间时变为NA,但这很容易在实现后完成。

附带一个期望输出的例子:

  library(tibble)
  library(data.table)


set.seed(1)
testdf <- tibble(mindiff = c(1,2,1,2,5,2,2,2,11,5,3,2,0,1),
                 DateTime = as.POSIXct("2019-01-01 00:00", z = "Etc/GMT-10")+(cumsum(mindiff)*60),
                 Value = round(runif(14,0,5),1))


dur8= 60*8


testdf[["Total8Min"]] <- setDT(testdf)[, rn := .I][.(ur = rn, ud = DateTime, ld = DateTime - dur8), 
                                              on = .(rn <= ur, DateTime <= ud, DateTime > ld),
                                              sum(as.double(Value)), by = .EACHI]$V1


testdf$desiredOut <- c(1.3,3.2,6.1,10.6,8.4,5.5,9.2,12.5,NA, 0.3,1.3,1.9,5.3,7.2)

这篇文章是由reprex包(v0.3.0)于2019-08-21创建的

我在data.table方面有些陌生,我更熟悉tidyverse,如果有人能提供tidyverse方法,我会很高兴。

进一步解释回复中所说的:在我的期望输出中,我只希望第6行输出为5.5,这是在最后2分钟(从00:11到00:13)和在此之前的5分钟内(从00:06到00:11)下降的雨量。我不想包括第4行的值,因为这场雨可能在00:04到00:06之间的任何时间下降 - 可能都在现在时间(第6行)8分钟之前的00:05之前下降。


你确定desiredOut中的所有数字都是正确的吗?例如,对于第6行输出,如果我们回溯8分钟,我们应该添加4.5 + 4.5 + 1,即10,但是你的期望输出只添加了4.5 + 1 - Ronak Shah
所以重点是,我不想在第6行的输出中包含第4行的值,因为从第4行到第6行的总时间差(2+5+2)为9分钟,超过了8分钟。如果时间差意味着我要超过8分钟,我想排除8分钟之前的一行。 - Sarah
第四行不就是比第六行晚13-6分钟(或2 + 5)吗? - Ronak Shah
我已经更新了回复@RonakShah,希望能更好地解释。 - Sarah
我已经更改了示例,因此它不在那里了。@chinsoon12 - Sarah
显示剩余2条评论
2个回答

3

这里有另一种使用cumsumDateTime实际上是个误导)的可能方法:

setDT(testdf)[, c("rn", "cs", "lagcs") := .(.I, cs <- cumsum(mindiff), cs - mindiff)]
testdf[, do := testdf[.(rn=rn, start=cs-8), on=.(rn<=rn, lagcs>=start),
    sum(Value), by=.EACHI]$V1]

输出:

    mindiff Value desiredOut rn cs lagcs   do
 1:       1   1.3        1.3  1  1     0  1.3
 2:       2   1.9        3.2  2  3     1  3.2
 3:       1   2.9        6.1  3  4     3  6.1
 4:       2   4.5       10.6  4  6     4 10.6
 5:       5   1.0        8.4  5 11     6  8.4
 6:       2   4.5        5.5  6 13    11  5.5
 7:       2   4.7        9.2  7 15    13  9.2
 8:       2   3.3       12.5  8 17    15 12.5
 9:      11   3.1         NA  9 28    17   NA
10:       5   0.3        0.3 10 33    28  0.3
11:       3   1.0        1.3 11 36    33  1.3
12:       2   0.9        1.9 12 38    36  1.9
13:       0   3.4        5.3 13 38    38  5.3
14:       1   1.9        7.2 14 39    38  7.2

数据:

library(data.table)
set.seed(1)
mindiff = c(1,2,1,2,5,2,2,2,11,5,3,2,0,1)
testdf <- data.table(mindiff = mindiff, Value = round(runif(14,0,5),1))
testdf$desiredOut <- c(1.3,3.2,6.1,10.6,8.4,5.5,9.2,12.5,NA, 0.3,1.3,1.9,5.3,7.2)

0

我认为@chinsoon12有一个更好和可扩展的方法,但由于我已经开始着手解决方案,所以我还是会发布它。

library(dplyr)

testdf %>%
   mutate(row = row_number(),
          out = purrr::map2_dbl(DateTime, row, ~{
            inds <- which(DateTime > (.x - dur8) & DateTime <= .x & .y >= row)
            if (sum(mindiff[inds]) > 8) sum(Value[inds[-1L]]) else sum(Value[inds])
     })) %>%
    select(-row)


# A tibble: 14 x 5
#   mindiff DateTime            Value desiredOut   out
#     <dbl> <dttm>              <dbl>      <dbl> <dbl>
# 1       1 2019-01-01 00:01:00   1.3        1.3   1.3
# 2       2 2019-01-01 00:03:00   1.9        3.2   3.2
# 3       1 2019-01-01 00:04:00   2.9        6.1   6.1
# 4       2 2019-01-01 00:06:00   4.5       10.6  10.6
# 5       5 2019-01-01 00:11:00   1          8.4   8.4
# 6       2 2019-01-01 00:13:00   4.5        5.5   5.5
# 7       2 2019-01-01 00:15:00   4.7        9.2   9.2
# 8       2 2019-01-01 00:17:00   3.3       12.5  12.5
# 9      11 2019-01-01 00:28:00   3.1       NA     0  
#10       5 2019-01-01 00:33:00   0.3        0.3   0.3
#11       3 2019-01-01 00:36:00   1          1.3   1.3
#12       2 2019-01-01 00:38:00   0.9        1.9   1.9
#13       0 2019-01-01 00:38:00   3.4        5.3   5.3
#14       1 2019-01-01 00:39:00   1.9        7.2   7.2

在这里,对于每个DateTime,我们取在8分钟范围内的Valuesum


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接