对连续的每小时观察值求和以找到最大值

Summing Consecutive Hourly Observation to find Maximums

我有这样的数据...

Year   Month   Day   Hour  Total  Date       DateTime
1950   1       2     21    0.01   1/2/1950   1/2/1950 21:00
1950   1       2     23    0.01   1/2/1950   1/2/1950 23:00
1950   1       3     0     0.06   1/3/1950   1/3/1950 0:00
1950   1       3     1     0.01   1/3/1950   1/3/1950 1:00
1950   1       3     2     0.02   1/3/1950   1/3/1950 2:00
1950   1       4     11    0.24   1/4/1950   1/4/1950 11:00
1950   1       4     12    0.07   1/4/1950   1/4/1950 12:00
1950   1       4     15    0.10   1/4/1950   1/4/1950 15:00
1950   1       4     16    0.04   1/4/1950   1/4/1950 16:00
1950   1       4     17    0.01   1/4/1950   1/4/1950 17:00

现在我想找到最大的连续两个小时总计(我也对最大的连续三、四、五个小时总计感兴趣)。在上面的数据中,最大的两小时总数为 0.31(将观察值 6 和 7 相加)。最大的 3 小时总数将是最后三个观察结果。重要的是观察必须是连续的!如果观察结果按 5 小时分散但总和很高,那并不重要。我对连续观察中的最高总和(来自总计列)感兴趣(2 小时总和、3 小时总和、4 小时总和等)。我要拍摄的是每年和每月最大的连续 2 小时或 3 小时总计,输出如下所示...

Year    Month    Two Hour Greatest
1950    1         0.31
1951    4         0.77
1952    3         0.91
1953    8         0.63

首先,这里有一些示例数据(使用 lubridate 中的工具制作)

df <-
  tibble(
    date_time = seq(ymd_hm("1950-01-01 00:00")
                    , ymd_hm("1951-12-30 23:00")
                    , "1 hour")
  ) %>%
  mutate(
    Total = round(runif(n()), 2)
    , Year = year(date_time)
    , Month = month(date_time)
  ) 

请注意,这假设您对该时间段内的每个小时都有一个观察。如果没有,您可能需要使用 tidyr 中的 complete 来为缺失的观察结果添加 0(或其他适当的默认值)。

然后,使用 zoo 中的 rollsum 计算最后 k 个观察值的滚动总和。然后,summarise 为每个感兴趣的 window 获取最大值。

请注意,这里我在 计算 rollsum 之前使用了 group_by ,这样总和就不会跨越月份边界。也就是说,它不会计算 1 月的最后一个小时和 2 月的第一个小时的总数。这可确保您的最大值仅适用于给定月份内 完全 的观察结果。如果您想要不同的东西,请将 group_by 步骤移动到 之后 rollsum 并确保您对 align 将结果放在 rollsum(在最后一次观察的月份,在下面的例子中)。

代码:

df %>%
  group_by(Year, Month) %>%
  mutate(
    two_hour_tot = rollsum(Total, k = 2, fill = NA, align = "right")
    , three_hour_tot = rollsum(Total, k = 3, fill = NA, align = "right")
    , four_hour_tot = rollsum(Total, k = 4, fill = NA, align = "right")
  ) %>%
  summarise(
    two_hour_max = max(two_hour_tot, na.rm = TRUE)
    , three_hour_max = max(three_hour_tot, na.rm = TRUE)
    , four_hour_max = max(four_hour_tot, na.rm = TRUE)
  )

Returns:

# A tibble: 24 x 5
# Groups:   Year [?]
    Year Month two_hour_max three_hour_max four_hour_max
   <dbl> <dbl>        <dbl>          <dbl>         <dbl>
 1  1950     1         1.98           2.76          3.43
 2  1950     2         1.96           2.68          3.57
 3  1950     3         1.96           2.91          3.65
 4  1950     4         1.98           2.91          3.7 
 5  1950     5         1.95           2.76          3.65
 6  1950     6         1.97           2.82          3.53
 7  1950     7         1.97           2.8           3.71
 8  1950     8         1.94           2.85          3.53
 9  1950     9         2.00           2.77          3.43
10  1950    10         1.93           2.82          3.7 
# … with 14 more rows

(显然,您的 randomized/actual 值会有所不同)