我正在尝试在给定阈值的时间序列中过滤两个不同的年份。第一年,我想捕获值(value)何时超过阈值的第一个实例。但是,如果该值连续几年超过该阈值,我想获取该连续值上次出现的日期。其次,在该时间序列内,我想捕获第二个超过阈值的实例。但是,该时间不能在第一个选定值的两年内,如果确实如此,则不使用该值。其外观示例如下:
dat <- data.frame(time = as.Date(c("2001-12-31","2002-12-31","2003-12-31","2004-12-31",
"2005-12-31","2006-12-31","2007-12-31","2008-12-31")),
value = c(-52.1,-52.44,23.5,-64.2,10.7,-15.4,-52.4,231.7))
我想过滤那些值 <= -50 的值,并选择给定条件的两年。预期输出为:
2002-12-31
2007-12-31
我尝试遵循类似的框架,使用切片函数来获取日期(来自另一个问题: Choosing first instance of a value by year in a time series ),但不确定如何遵循不同阈值的标准提取。感谢任何帮助!
最佳答案
我认为这是游程编码的组合(base::rle
、dplyr::consecutive_id
或 data.table::之一rleid
)和一些更简单的过滤。
您将看到使用 2*365+2
作为鉴别器:用于时间差分的 POSIXt
方法没有 “年份”
作为一个选项,所以我们需要使用天数,并且 2002-2007 年有一个闰年。
dplyr
library(dplyr)
dat %>%
group_by(grp = consecutive_id(value <= -50)) %>%
filter(any(value <= -50), row_number() == n()) %>%
ungroup() %>%
filter(row_number() == 1L | difftime(time, time[1], units="day") >= (2*365+2))
# # A tibble: 2 × 3
# time value grp
# <date> <dbl> <int>
# 1 2002-12-31 -52.4 1
# 2 2007-12-31 -52.4 5
数据表
library(data.table)
as.data.table(dat)[, .SD[any(value <= -50), .(time, value)][.N,], by = .(grp = rleid(value <= -50))
][(seq(.N) == 1 | difftime(time, time[1], units="day") >= (2*365+2)),]
# grp time value
# <int> <Date> <num>
# 1: 1 2002-12-31 -52.44
# 2: 5 2007-12-31 -52.40
基础R
(还有一点工作。)
# a home-grown base-R version of `rleid` and `consecutive_id` above
my_rleid <- function(...) {
r <- rle(do.call(paste, c(list(...), sep = "_")))$lengths
rep(seq_along(r), times = r)
}
dat |>
transform(grp = my_rleid(value <= -50)) |>
subset(ave(value <= -50, grp, FUN = function(z) any(z) & seq_along(z) == length(z))) |>
subset(seq_along(time) == 1L | difftime(time, time[1], units="day") >= (2*365+2))
# time value grp
# 2 2002-12-31 -52.44 1
# 7 2007-12-31 -52.40 5
关于r - 如何在R中给定阈值和缓冲时间来过滤时间序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77275402/