用R查找一定时间范围内突然变化(值差异)的情况

问题描述 投票:0回答:1

我有一个多年度温度时间序列,带有日期时间列(具有不规则的时间步长),如下所示:

 daytime             Temperature 
<dttm>                    <dbl>   
1981-10-01 09:00:00        22  
1981-10-02 09:00:00        21.6    
1981-10-03 09:00:00        20.3  
1981-10-04 09:00:00        20.4  
1981-10-05 09:00:00        20.6   
1981-10-05 11:00:00        21    

我想找到符合 2 个条件的所有情况,其中特定时间跨度(48 小时)内的温差(最大-最小)至少为 4°C。换句话说,找到所有快速且重要的温度变化(无论是升高还是降低)。理想情况下,结果将是一个数据框,其中 1 列包含每个检测到的病例的第一个日期,第二列包含相关的温差 (>= 4 °C) 的给定情况。

我尝试使用 Rbeast 工具来检测断点,但它似乎无法检测到这种短期变化。

非常感谢你们聪明人!!!

r time-series difference timespan custom-rolling-window
1个回答
0
投票

我将创建自己的样本数据,因为提供的数据永远不会触发 4 度差异。我将添加一个间隙,以便我们显示它是滚动 48 小时窗口,而不是滚动 2 行窗口。

(我推断您正在使用

dplyr
,因为您有
tbl_df
样本数据。)

library(dplyr)
set.seed(2023)
quux <- tibble(
  daytime = seq(as.POSIXct("2023-10-01 09:00:00"), length.out = 12, by = "day")[-(3:4)],
  Temperature = 20 + rnorm(10, sd = 3)
)
quux
# # A tibble: 10 × 2
#    daytime             Temperature
#    <dttm>                    <dbl>
#  1 2023-10-01 09:00:00        19.7
#  2 2023-10-02 09:00:00        17.1
#  3 2023-10-03 09:00:00        14.4
#  4 2023-10-06 09:00:00        19.4
#  5 2023-10-07 09:00:00        18.1
#  6 2023-10-08 09:00:00        23.3
#  7 2023-10-09 09:00:00        17.3
#  8 2023-10-10 09:00:00        23.0
#  9 2023-10-11 09:00:00        18.8
# 10 2023-10-12 09:00:00        18.6

请注意,由于我们没有

10-04
10-05
,因此从
14.4
19.4
的间隙不应触发任何内容。

从这里开始,我们需要一个滚动窗口来定义“48 小时”的事情。

out <- quux |>
  arrange(daytime) |>
  mutate(
    wid = sapply(row_number(), function(rn) rev(which(cumsum(as.numeric(diff(daytime[rn:n()]), units = "hours")) <= 48) + 1)[1]),
    wid = coalesce(wid, 1L),
    tempdiff = zoo::rollapply(Temperature, width = wid, align = "left", partial = TRUE,
                              FUN = function(z) diff(range(z)))
  )
out
# # A tibble: 10 × 4
#    daytime             Temperature   wid tempdiff
#    <dttm>                    <dbl> <dbl>    <dbl>
#  1 2023-10-01 09:00:00        19.7     3    5.37 
#  2 2023-10-02 09:00:00        17.1     2    2.68 
#  3 2023-10-03 09:00:00        14.4     1    0    
#  4 2023-10-06 09:00:00        19.4     3    5.17 
#  5 2023-10-07 09:00:00        18.1     3    6.01 
#  6 2023-10-08 09:00:00        23.3     3    6.01 
#  7 2023-10-09 09:00:00        17.3     3    5.75 
#  8 2023-10-10 09:00:00        23.0     3    4.41 
#  9 2023-10-11 09:00:00        18.8     2    0.207
# 10 2023-10-12 09:00:00        18.6     1    0    

这样,过滤掉 4 度以上的就很简单了:

out |>
  filter(tempdiff >= 4)
# # A tibble: 6 × 4
#   daytime             Temperature   wid tempdiff
#   <dttm>                    <dbl> <dbl>    <dbl>
# 1 2023-10-01 09:00:00        19.7     3     5.37
# 2 2023-10-06 09:00:00        19.4     3     5.17
# 3 2023-10-07 09:00:00        18.1     3     6.01
# 4 2023-10-08 09:00:00        23.3     3     6.01
# 5 2023-10-09 09:00:00        17.3     3     5.75
# 6 2023-10-10 09:00:00        23.0     3     4.41

上面第一步是定义

wid
th,表示“未来48小时”内包含多少行(包括当前行);您可以看到,当接近我在样本数据中施加的 2 天差距时,它会减少。在 2 天差距的前一天,我们的
tempdiff
为 0,这是因为
14.4
是唯一可用的观测值,而
diff(range(14.4))
为 0。

© www.soinside.com 2019 - 2024. All rights reserved.