R 使用 data.table 中的条件查找波高于给定值的频率和持续时间

标签 r conditional data.table time-series signal-processing

下面粘贴了一个 MRE

地雷

date<-c('2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-01','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02','2001-01-02')
time<-c('07:00:00 GMT','08:00:00 GMT','09:00:00 GMT','10:00:00 GMT','11:00:00 GMT','12:00:00 GMT','13:00:00 GMT','14:00:00 GMT','15:00:00 GMT','16:00:00 GMT','17:00:00 GMT', '18:00:00 GMT','19:00:00 GMT','20:00:00 GMT','21:00:00 GMT','22:00:00 GMT','23:00:00 GMT','00:00:00 GMT', '01:00:00 GMT','02:00:00 GMT','03:00:00 GMT','04:00:00 GMT','05:00:00 GMT','06:00:00 GMT','07:00:00 GMT','08:00:00 GMT','09:00:00 GMT','10:00:00 GMT','11:00:00 GMT','12:00:00 GMT','13:00:00 GMT','14:00:00 GMT','15:00:00 GMT','16:00:00 GMT','17:00:00 GMT','18:00:00 GMT','19:00:00 GMT','20:00:00 GMT','21:00:00 GMT')
el<-c(0.257,0.687,1.861,3.288, 4.821,6.172,7.048,7.258,6.799,5.654,4.463,3.443,2.704,2.708,3.328,4.23,5.244,5.985,6.317,6.074,5.234,3.981,2.662,1.615,0.88,0.746,1.405,2.527,3.928,5.283,6.517,7.179,7.252,6.625,5.454,4.214,3.144,2.491,2.357)
Time<-as.POSIXct(paste(date, time),tz="GMT")
wave<-data.table(Time, el)
ggplot(wave, aes(wave$Time, wave$el)) + geom_point() + labs(x="time", y="elevation") + geom_hline(aes(yintercept=4))

我有一个波浪时间序列,我希望能够有一个函数来告诉我波浪高于给定高度的频率和平均/中值持续时间。在我的例子中,我选择了 4。

我想插入波浪在上升沿和下降沿达到 4 的时间,并找到每个波浪的两点之间的时间差。

我可以用 for 循环来做到这一点,但我认为我应该能够更快地在 data.table 中做到这一点。我有几个位置的 100 万+ 点,并且认为 for 循环不会有效。

对于上升的浪潮,我想做一些类似的事情:
wave[,timeIs4:=ifelse(elev<3 & elev[+1]>4,TRUE,FALSE )]

但不是 TRUE 放在我的插值计算中。我不知道如何访问数据表中的前面和后面的值,例如在 for 循环 i+1 或 i-1 中。

期望输出

抬腿
我想在第 4 点和第 5 点之间进行插值; 15 和 16; 29 和 30。

落腿
我想在第 11 点和第 12 点之间进行插值; 21 和 22; 36 和 37

大致结果
Rising      Falling
10:28:00    17:27:00
21:45:00    3:59:00
11:03:00    18:12:00

然后我将能够使用 difftime() 从下降中减去上升,以确定水位高于给定高度的时间。

这将为我提供水高于给定高度的频率和持续时间。

最佳答案

这是使用 devel version from GH 的可能解决方案.您将需要它用于 shift功能(如@Jan 所述)并启动新的 dcast接受表达式的方法。此外,您的 MRE 中没有分钟数,因此不确定您在预期输出中从何处获得这些分钟数。

无论如何,对于初学者来说,我们将创建一个索引(我们将其称为 Wave,因此您将知道它来自哪个波浪#),它将使用 shift 告诉我们该波浪是上升还是下降。 .然后,我们将dcast在匹配值上使用 na.omit 删除不匹配的值(如果您喜欢使用 setcolorder 函数,可以稍后对列名重新排序)

library(data.table) ## V 1.9.5+
dt[elev <= 4 & shift(elev, type = "lead") > 4, Wave := "Rising"]
dt[elev > 4 & shift(elev, type = "lead") <= 4, Wave := "Falling"]
dcast(na.omit(dt), cumsum(Wave == "Rising") ~ Wave, value.var = "time")
#    Wave             Falling              Rising
# 1:    1 2001-01-01 17:00:00 2001-01-01 10:00:00
# 2:    2 2001-01-02 03:00:00 2001-01-01 21:00:00
# 3:    3 2001-01-02 18:00:00 2001-01-02 11:00:00

关于R 使用 data.table 中的条件查找波高于给定值的频率和持续时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32543271/

相关文章:

条件宏扩展

python - 如何在多行 if 语句中注释每个条件?

r - 如何动态地从data.table中提取一些随机行

r - 我如何在R中读取MTL文件

r - quantmod ... 无法获取当天的 OHLCV 符号数据

ruby - 在 ruby​​ 中检查空格的最简单方法

r - data.table::melt - 变量列转换为具有 variable.factor = FALSE 指定的因子

r - R中组中的ifelse函数组

r - 如何直方图星期几,并有字符串标签

r - 像在facet_grid中一样在facet_wrap中设置 “space”