Based on initial partner feedback it was decided to focus on Faryab province.
This script evaluates various environmental indicators for their utility as trigger metrics in Faryab Province in Afghanistna. The triggers are evaluated:
Forecasted:
SEAS5 – cumulative predicted rainfall for MAM predicted form Nov-March
Observational:
CHIRPS – Monthly rainfall: November - May
SWE – Monthly SWE: November – May
NDVI – Monthly NDVI: March- May
Combined Monthly CHIRPS & SWE: March- May
For each indicator we determine the worst years on record (drought-wise) across each monitoring moment/time-step. We then see how well the worst years at each of these indicator-timestep combinations line up with the worst years calculated according to ASI Dekad 3 calculation. We look at ASI Dekad 3 of May because ASI is a measure of scale of drought at a geographical level based on NDVI and crop specific coefficients. May Dekad 3 is after the growing season and just as the harvest begins for spring wheat, so is a good time to measure this cumulative indicator. It corresponded with the EMDAT dataset on historical drought in Faryab.
The heatmap & rainfall time-series produced here are included in this slide deck
Code
box::use( ../R/blob_connect)box::use( dplyr, forcats,gg = ggplot2, gghdx, janitor, lubridate, purrr, readr, scales, stats, stringr, tidyr)gghdx$gghdx()################################# PERFORMANCE METRICS ################################## We calculate performance in a specific way. It is by passing in a dataset# that has years when we would want to activate, `y`, and and years when we would# activate for a certain indicator, `x`. These are then used to calculate precision# and recall. We also use bootstrapping to test if we are better than random.## Since we have a set return period for the historical activation data, and also# the same desired activation rate as the return period, in this instance, sum(x)# and sum(y) are equal, so precision and recall are equal.# functions to calculate metricsprecision <-function(x, y) {sum(x & y) /sum(x)}recall <-function(x, y) {sum(x & y) /sum(y)}#' Compares level of metric (calcualted by `fun`) to "random" values#' by bootstrapping `y` 1,000 times. Returns the % of times the actual metric is higher than the#' random. Expect 95% of the time or more we are better than random!#'#' If the values are the same, considers it "good" (better than random).metric_calc <-function(x, y, fun, indicator) { threshold <-fun(x = x, y = y) pct_better <- purrr$map_lgl(.x =1:1000,.f = \(a) fun(x =sample(x, size =length(x), replace =FALSE), y = y) <= threshold ) |>mean() metric_name <-deparse(substitute(fun)) dplyr$tibble("{metric_name}":= threshold,"{metric_name}_beq_random":= pct_better )}calc_metrics <-function(df, x, y) { df |> dplyr$summarise(precision =metric_calc({{ x }}, {{ y }}, precision),recall =metric_calc({{ x }}, {{ y }}, recall),indicator =unique(indicator),.groups ="drop" ) |> tidyr$unnest(cols = tidyr$everything() )}