如何计算 R 中不同时间序列长度的最大值和最小值之间的差异?

How can I calculate difference between max and min over varying time series lengths in R?

我有一个时间序列的水深测量值(15 分钟间隔),我想计算每个潮汐周期的潮汐高度。潮汐高度是退潮的最大深度和最小深度之间的绝对差(反之亦然,因此是绝对差)。使事情复杂化的是,并非我所有的站点在涨潮和退潮之间都有 6 小时的变化;有的多,有的少。我想有一种方法来计算最大值和最小值之间的绝对差值,这些值随连续高点和低点之间的时间长度而变化。

只是一些随机数据:

dat <- data.frame(matrix(vector(),20,2,
                         dimnames=list(c(), c("Time", "Depth"))),
                  stringsAsFactors = F)
dat[,1] <- seq(from = 1, to = 20, by = 1)
dat[1:5,2] <- seq(from = 0.5, to = 2.5, by = 0.5)
dat[6:13,2] <- seq(from = 2.6, to = 0.4, by = -0.28)
dat[14:20,2] <- seq(from = 0.4, to = 2.8, by = 0.4)

输出应具有以下结果:

    Tide TidalHeight
1   1    2.1
2   2    2.2
3   3    2.4

潮一为低点0.5与高点2.6的绝对差,潮二为高点2.6与低点0.4的绝对差,潮三为低点与低点的绝对差0.4 和高 2.8。连续高潮和低潮之间的时间长度各不相同,在上面的例子中有 6、8 和 6 个时间步长,但在实际数据中,这可以是任意数量的时间步长。

我想知道如何自动计算潮汐之间时间长度变化的高潮和低潮之间的绝对差值。

如果您假设在涨潮和退潮期间水深都是单调的,那么@Onyamu 的评论虽然完全正确,但可以忽略。

诀窍是使用 rle 计算出每次潮汐持续的观察次数。

library(tibble)

dat <- dat %>% 
         mutate(Direction=ifelse(Depth > lag(Depth), "Rising", "Falling"))
dat$Direction[1] <- dat$Direction[2]  # Handle the first observation.

tides <- rle(dat$Direction)
dat <- dat %>% 
         add_column(Tide=unlist(lapply(1:length(tides$length), function(x) rep(x, tides$length[x]))))
dat %>% 
  group_by(Tide) %>% 
  summarise(
    HighTide=max(Depth), 
    LowTide=min(Depth), 
    .groups="drop"
  ) %>% 
  mutate(
    TideHeight=ifelse(
                 Tide == 1, 
                 HighTide - LowTide,
                 ifelse(
                   Tide == nrow(.), 
                   HighTide - lag(LowTide), 
                   lag(HighTide) - LowTide
                 )
               )
  )
dat
# A tibble: 3 x 4
   Tide HighTide LowTide TideHeight
  <int>    <dbl>   <dbl>      <dbl>
1     1     2.6      0.5        2.1
2     2     2.32     0.4        2.2
3     3     2.8      0.8        2.4

您还可以这样做:

library(tidyverse)
dat$grp <- with(rle(sign(c(diff(dat$Depth),0))), rep(seq_along(values),lengths))
abs(diff(subset(dat, ave(grp,grp,FUN = seq_along)==1)$Depth))
[1] 2.1 2.2 2.4