Есть пара вопросов к сообщению ОП, поэтому я буду go читать их шаг за шагом. Для этого рабочего процесса вам понадобятся dplyr
и lubridate
.
Сначала мы создадим некоторые поддельные данные для использования:
library(lubridate)
library(dplyr)
#create example data
dd<- data.frame(Date = seq.Date(as.Date("2021-01-01"), as.Date("2100-12-01"), by = "month"),
spei = rnorm(960,0,2))
Это будет выглядеть примерно так, как вы иметь выше
> head(dd)
Date spei year year_20 drought
1 2021-01-01 -6.85689789 2021 2021_2040 1
2 2021-02-01 -0.09292459 2021 2021_2040 1
3 2021-03-01 0.13715922 2021 2021_2040 0
4 2021-04-01 2.26805601 2021 2021_2040 0
5 2021-05-01 -0.47325008 2021 2021_2040 1
6 2021-06-01 0.37034138 2021 2021_2040 0
Затем мы можем использовать lubridate и cut для создания наших годовых и 20-летних переменных, чтобы сгруппировать их позже и создать столбец drought
, обозначающий, если spei
был отрицательным.
#create a column to group on by year and by 20-year
dd <- dd %>%
mutate(year = year(Date),
year_20 = cut(year, breaks = c(2020,2040,2060,2080, 2100), include.lowest = T,
labels = c("2021_2040", "2041_2060", "2061_2080", "2081_2100"))) %>%
#column signifying if that month was a drought
mutate(drought = ifelse(spei<0,1,0))
Получив это, мы просто используем функцию group_by
, чтобы получить частоту (или количество месяцев с засухой) по году или 20-летнему периоду
#by year
dd %>%
group_by(year) %>%
summarise(year_freq = sum(drought)) %>%
ungroup()
# A tibble: 80 x 2
year year_freq
<dbl> <dbl>
1 2021 6
2 2022 4
3 2023 7
4 2024 6
5 2025 6
6 2026 7
#by 20-year group
dd %>%
group_by(year_20) %>%
summarise(year20_freq = sum(drought)) %>%
ungroup()
# A tibble: 4 x 2
year_20 year20_freq
<fct> <dbl>
1 2021_2040 125
2 2041_2060 121
3 2061_2080 121
4 2081_2100 132
Расчет продолжительности засухи немного сложнее. Он включает
- , идентифицирующий первый месяц каждой засухи
- , вычисляющий продолжительность каждой засухи
- , объединяющий информацию из 1 и 2 вместе
Мы можем использовать lag
, чтобы определить, когда месяц изменился с «без засухи» на «засуху». В этом случае нам нужен индекс, где значение в строке i
отличается от значения в строке i-1
# find index of where values change.
change.ind <- dd$drought != lag(dd$drought)
#use index to find drought start
drought.start <- dd[change.ind & dd$drought == 1,]
Это приводит к подмножеству начального набора данных, но только со строками с первый месяц засухи. Тогда мы можем использовать rle
для расчета продолжительности засухи. rle
будет вычислять длину каждого прогона чисел, поэтому нам нужно будет установить поднабор только тех прогонов, в которых значение == 1 (засуха)
#calculate drought lengths
drought.lengths <- rle(dd$drought)
# we only want droughts (values = 1)
drought.lengths <- drought.lengths$lengths[drought.lengths$values==1]
Теперь мы можем объединить эти два фрагмента информации все вместе. Первая строка - NA
, потому что в i-1
нет значения для сравнения задержки. Его можно удалить, если вы не хотите включать эти данные.
drought.dur <- cbind(drought.start, drought_length = drought.lengths)
head(drought.dur)
Date spei year year_20 drought drought_length
NA <NA> NA NA <NA> NA 2
5 2021-05-01 -0.47325008 2021 2021_2040 1 1
9 2021-09-01 -2.04564549 2021 2021_2040 1 1
11 2021-11-01 -1.04293866 2021 2021_2040 1 2
14 2022-02-01 -0.83759671 2022 2021_2040 1 1
17 2022-05-01 -0.07784316 2022 2021_2040 1 1