Расчет событий холодной волны для нескольких станций на основе минимальной температуры в R - PullRequest
2 голосов
/ 13 апреля 2020

Холодная волна определяется, если минимальная температура на метеостанции ниже нормальной температуры на 3 ° C или более в течение 3 дней или более (Метеорологический департамент Индии, Пуна). Я попытался рассчитать его для нескольких станций, используя следующий код

#Calculation for multistation
set.seed(123)
df <- data.frame("date"= seq(from = as.Date("1970-1-1"), to = as.Date("2000-12-31"), by = "day"),
                 "Station1" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 10, 30),
                 "Station2" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 11, 29),
                 "Station3" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 9, 28))

head(df)

df$day <- format(df$date, format='%m-%d')

#Daily average (daily normal) calculation
df_summarise_all <- df %>% 
  as_tibble() %>% # for easier viewing 
  mutate(day = format(df$date, format='%m-%d')) %>% 
  group_by(day) %>%
  summarise_all(funs(mean)) %>% 
  pivot_longer(cols = -c(date, day), names_to = "variable", values_to = "value") 

#Coldwave event calculation
df %>%
  as_tibble() %>% # for easier viewing 
  pivot_longer(cols = -c(date, day), names_to = "Stations", values_to = "MinT") %>% 
  left_join(df_summarise_all %>% rename(mean_MinT = value), by = 'day') %>% 
  mutate(is_coldwave = zoo::rollapplyr(MinT < (mean_MinT - 3), 
                                       3, all,fill = NA))

. Как видно из результатов, соединение дневной нормы и минимальной температуры станции является неправильным. У меня три вопроса

  1. Как исправить объединение?
  2. Как узнать количество холодных волн в год для каждой станции? и
  3. Как получить общее количество холодных волн для каждой станции?

1 Ответ

1 голос
/ 13 апреля 2020

Вы также должны присоединиться Stations и, вероятно, сравнить с mean_MinT - 3 для coldwave.

library(dplyr)

df_out <- df %>%
             tidyr::pivot_longer(cols = -c(date, day), 
                 names_to = "Stations", values_to = "MinT") %>%
             left_join(df_summarise_all %>% rename(mean_MinT = value), 
                         by = c('day' = 'day', 'Stations' = 'variable')) %>%
             mutate(is_coldwave = zoo::rollapplyr(MinT < (mean_MinT - 3), 3, 
                     all,fill = NA))

Для расчета годовой и общей холодной волны вы можете использовать тот же метод, что и в этом ответе.

df_year <- df_out %>%
            group_by(Stations, year = format(date.x, "%Y")) %>%
           summarise(total_cold = with(rle(is_coldwave), 
                                        sum(values, na.rm = TRUE)))

и sum(df_year$total_cold) дадут общее количество.

...