如何检查r中一系列值中连续n天超过x阈值的实例数

  • 本文关键字:阈值 实例 何检查 一系列 连续 r dplyr
  • 更新时间 :
  • 英文 :


我想知道r中是否有一种方法可以返回一系列数据连续几天超过某个值的次数的值。

例如,一年中有多少次x连续30天大于10

我知道你可以发现全年有多少实例x大于某个值,但我不知道如何测试连续的实例。

其中Data是一个数据帧,包含日期、年份和值列,以及2010-2020年的每日数据:

Data %>%
group_by(Year) %>%
filter(Value >= 10) %>%
summarize(exceedances = n())

以下是2018-2021年的每日数据示例,随机值为0-25:

library(tidyverse)
library(dplyr)
library(lubridate)
value = sample(0:25, 1461, replace=T)
date = seq(as.Date("2018-01-01"), as.Date("2021-12-31"), by = "1 day")
dat = data.frame(date = date,
year = year(date),
value = value)
dat %>%
group_by(year) %>%
filter(value >= 10) %>%
summarize(exceedances = n())

输出:

# A tibble: 4 x 2
year exceedances
<dbl>       <int>
1  2018         216
2  2019         247
3  2020         229
4  2021         217

期望输出(n个>=30个连续超越是一种猜测(:

# A tibble: 4 x 2
year n_exceedances_30_consec
<dbl>       <int>
1  2018         1
2  2019         0
3  2020         2
4  2021         0

这样做的诀窍是,如果有40个连续的超越,我需要它只显示为1个实例,而不是前30天>=的10个实例10.

您可以使用slider::slide_dbl。也许这是一种复杂的方法,但你可以

library(tidyverse)
library(lubridate)
library(slider)
value = sample(0:25, 1461, replace=T)
date = seq(as.Date("2018-01-01"), as.Date("2021-12-31"), by = "1 day")
dat = data.frame(date = date,
year = year(date),
value = value)
library(dplyr)
library(slider)
consecutive_days <- 10
dat |>
mutate(greater = if_else(value >= 10, TRUE, FALSE)) |>
mutate(consecutive = slide_dbl(greater, sum, .before = consecutive_days-1)) |>
filter(consecutive >= consecutive_days) |>
filter(greater) |> 
group_by(year) |>
summarize(exceedances = n())

我显然是在这里自由打字,因为没有提供任何数据。希望这能满足您的需求!

编辑-我正在根据您发送的数据进行编辑。现在应该可以正常工作了。

这是如果你更像是一个基本的R用户:

date_index <- sapply(dat$date, (x) {
d <- dat[dat$date >= x-(consecutive_days-1) &
dat$date <= x, ]
d <- d[d$value >= 10, ]
nrow(d) >= consecutive_days
})
aggregate(x = dat[date_index, ]$value,
by = list(year = dat[date_index, ]$year),
FUN = length)

我正在稍微更改您的数据,因为我没有得到足够长的运行时间。

set.seed(6)
date = seq(as.Date("2018-01-01"), as.Date("2021-12-31"), by = "1 day")
dat = data.frame(date = date,
year = format(date, "%Y"),
value = sample(5:50, length(date), replace=TRUE)
)
year_runs <- sapply(unique(dat$year), function(y) {
runs <- rle(dat$value[dat$year==y] >= 10); sum(runs$length>=30 & runs$value)
})
year_runs
2018 2019 2020 2021 
1    2    2    2 

这里的秘密是基函数rle(游程编码(。这是每年单独运行的;如果一次跑步在新年结束,它将被截断。

为了响应您的编辑,即您希望在跑步结束的年份计算跑步次数,您可以跳过sapply,在整个数据集上使用rle,删除太短的跑步次数,然后将其反转,找到结束

runs <- rle(dat$value >= 10)
runs$values [runs$lengths < 30] <- FALSE
run_ends <- which(diff(inverse.rle(runs)) == -1) + 1
table(dat$year[run_ends])
2018 2019 2020 2021 
1    2    2    2 

最新更新