-
Notifications
You must be signed in to change notification settings - Fork 29
R new syntax for ECMEN #229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,200 @@ | ||
| # ------------------------------------------------------------ | ||
| # WFP Standardized Scripts | ||
| # Economic Capacity to Meet Essential Needs (ECMEN) – Assessments | ||
| # Version excluding assistance (and deducting humanitarian cash used for consumption) | ||
| # Last Updated: January 2026 | ||
| # ------------------------------------------------------------ | ||
|
|
||
| library(dplyr) | ||
|
|
||
| # ----------------------------- | ||
| # 0) Food expenditure inputs (7D recall) | ||
| # ----------------------------- | ||
| food_purch_7d <- c( | ||
| "HHExpFCer_Purch_MN_7D","HHExpFTub_Purch_MN_7D","HHExpFPuls_Purch_MN_7D", | ||
| "HHExpFVeg_Purch_MN_7D","HHExpFFrt_Purch_MN_7D","HHExpFAnimMeat_Purch_MN_7D", | ||
| "HHExpFAnimFish_Purch_MN_7D","HHExpFFats_Purch_MN_7D","HHExpFDairy_Purch_MN_7D", | ||
| "HHExpFEgg_Purch_MN_7D","HHExpFSgr_Purch_MN_7D","HHExpFCond_Purch_MN_7D", | ||
| "HHExpFBev_Purch_MN_7D","HHExpFOut_Purch_MN_7D" | ||
| ) | ||
|
|
||
| food_gift_7d <- c( | ||
| "HHExpFCer_GiftAid_MN_7D","HHExpFTub_GiftAid_MN_7D","HHExpFPuls_GiftAid_MN_7D", | ||
| "HHExpFVeg_GiftAid_MN_7D","HHExpFFrt_GiftAid_MN_7D","HHExpFAnimMeat_GiftAid_MN_7D", | ||
| "HHExpFAnimFish_GiftAid_MN_7D","HHExpFFats_GiftAid_MN_7D","HHExpFDairy_GiftAid_MN_7D", | ||
| "HHExpFEgg_GiftAid_MN_7D","HHExpFSgr_GiftAid_MN_7D","HHExpFCond_GiftAid_MN_7D", | ||
| "HHExpFBev_GiftAid_MN_7D","HHExpFOut_GiftAid_MN_7D" | ||
| ) | ||
|
|
||
| food_own_7d <- c( | ||
| "HHExpFCer_Own_MN_7D","HHExpFTub_Own_MN_7D","HHExpFPuls_Own_MN_7D", | ||
| "HHExpFVeg_Own_MN_7D","HHExpFFrt_Own_MN_7D","HHExpFAnimMeat_Own_MN_7D", | ||
| "HHExpFAnimFish_Own_MN_7D","HHExpFFats_Own_MN_7D","HHExpFDairy_Own_MN_7D", | ||
| "HHExpFEgg_Own_MN_7D","HHExpFSgr_Own_MN_7D","HHExpFCond_Own_MN_7D", | ||
| "HHExpFBev_Own_MN_7D","HHExpFOut_Own_MN_7D" | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 1) Non-food expenditure inputs (cash/credit only for ECMEN) | ||
| # 1M recall (short-term) | ||
| # ----------------------------- | ||
| nf_purch_1m <- c( | ||
| "HHExpNFHyg_Purch_MN_1M","HHExpNFTransp_Purch_MN_1M","HHExpNFFuel_Purch_MN_1M", | ||
| "HHExpNFWat_Purch_MN_1M","HHExpNFElec_Purch_MN_1M","HHExpNFEnerg_Purch_MN_1M", | ||
| "HHExpNFDwelSer_Purch_MN_1M","HHExpNFPhone_Purch_MN_1M","HHExpNFRecr_Purch_MN_1M", | ||
| "HHExpNFAlcTobac_Purch_MN_1M" | ||
| ) | ||
|
|
||
| # 6M recall (long-term) converted to monthly average by /6 | ||
| nf_purch_6m <- c( | ||
| "HHExpNFMedServ_Purch_MN_6M","HHExpNFMedGood_Purch_MN_6M","HHExpNFCloth_Purch_MN_6M", | ||
| "HHExpNFEduFee_Purch_MN_6M","HHExpNFEduGood_Purch_MN_6M","HHExpNFRent_Purch_MN_6M", | ||
| "HHExpNFHHSoft_Purch_MN_6M","HHExpNFHHMaint_Purch_MN_6M" | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 2) Assistance variables (assessments) | ||
| # ----------------------------- | ||
| asst_vars <- c("HHAsstWFPCBTRecTot","HHAsstUNNGOCBTRecTot","HHAsstCBTCShare") | ||
|
|
||
| # If your HH size variable is not HHSize, rename here: | ||
| hh_size_var <- "HHSize" # <-- change if needed (e.g., "hh_size") | ||
|
|
||
| # If your MEB variables are named differently, rename here: | ||
| meb_var <- "MEB" # per capita MEB | ||
| smeb_var <- "sMEB" # per capita SMEB (optional) | ||
|
|
||
| # ----------------------------- | ||
| # 3) Convert SYSMIS (NA) expenditures to 0 (SPSS: SYSMIS=0) | ||
| # ----------------------------- | ||
| all_exp_inputs <- c(food_purch_7d, food_gift_7d, food_own_7d, nf_purch_1m, nf_purch_6m) | ||
|
|
||
| df <- df %>% | ||
| mutate(across(all_of(all_exp_inputs), ~ as.numeric(.x))) %>% | ||
| mutate(across(all_of(all_exp_inputs), ~ dplyr::coalesce(.x, 0))) | ||
|
|
||
| # ----------------------------- | ||
| # 4) (Optional) quick overview for outliers (min/max/mean) | ||
| # ----------------------------- | ||
| exp_overview <- df %>% | ||
| summarise(across(all_of(all_exp_inputs), | ||
| list(min = ~min(.x, na.rm = TRUE), | ||
| max = ~max(.x, na.rm = TRUE), | ||
| mean = ~mean(.x, na.rm = TRUE)))) | ||
| exp_overview | ||
|
Comment on lines
+77
to
+84
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Data quality control and validation do not belong here. |
||
|
|
||
| # ----------------------------- | ||
| # 5) Compute monthly food totals by source (7D -> 1M with 30/7) | ||
| # ----------------------------- | ||
| df <- df %>% | ||
| mutate( | ||
| HHExp_Food_Purch_MN_1M = rowSums(across(all_of(food_purch_7d))) * (30/7), | ||
| HHExp_Food_GiftAid_MN_1M = rowSums(across(all_of(food_gift_7d))) * (30/7), | ||
| HHExp_Food_Own_MN_1M = rowSums(across(all_of(food_own_7d))) * (30/7) | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 6) Compute monthly non-food (cash/credit only) = 30D + (6M/6) | ||
| # ----------------------------- | ||
| df <- df %>% | ||
| mutate( | ||
| HHExpNFTotal_Purch_MN_30D = rowSums(across(all_of(nf_purch_1m))), | ||
| HHExpNFTotal_Purch_MN_6M = rowSums(across(all_of(nf_purch_6m))), | ||
| HHExpNFTotal_Purch_MN_1M = HHExpNFTotal_Purch_MN_30D + (HHExpNFTotal_Purch_MN_6M / 6) | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 7) Household economic capacity for ECMEN (ASSESSMENTS) | ||
| # IMPORTANT: exclude in-kind gifts/aid from the aggregate | ||
| # Food: Purch + Own (exclude GiftAid) | ||
| # Non-food: Purch only | ||
| # ----------------------------- | ||
| df <- df %>% | ||
| mutate( | ||
| HHExpF_ECMEN = HHExp_Food_Purch_MN_1M + HHExp_Food_Own_MN_1M, | ||
| HHExpNF_ECMEN = HHExpNFTotal_Purch_MN_1M, | ||
| HHExp_ECMEN = HHExpF_ECMEN + HHExpNF_ECMEN | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 8) Deduct humanitarian cash assistance used for consumption (ASSESSMENTS) | ||
| # ----------------------------- | ||
| df <- df %>% | ||
| mutate( | ||
| HHAsstWFPCBTRecTot = dplyr::coalesce(as.numeric(HHAsstWFPCBTRecTot), 0), | ||
| HHAsstUNNGOCBTRecTot = dplyr::coalesce(as.numeric(HHAsstUNNGOCBTRecTot), 0), | ||
| HHAsstCBTCShare = as.numeric(HHAsstCBTCShare), | ||
|
|
||
| HHAsstCBTRec = HHAsstWFPCBTRecTot + HHAsstUNNGOCBTRecTot, | ||
| HHAsstCBTRec_1M = HHAsstCBTRec / 3 | ||
| ) | ||
|
|
||
| # Median share used for consumption (if all missing -> treat as 0) | ||
| asst_share_med <- median(df$HHAsstCBTCShare, na.rm = TRUE) | ||
| if (is.na(asst_share_med)) asst_share_med <- 0 | ||
|
|
||
| df <- df %>% | ||
| mutate( | ||
| HHAsstCBTCShare_med = asst_share_med, | ||
| HHAsstCBTRec_Cons_1M = HHAsstCBTRec_1M * (HHAsstCBTCShare_med / 100), | ||
| HHAsstCBTRec_Cons_1M = dplyr::coalesce(HHAsstCBTRec_Cons_1M, 0), | ||
| HHExp_ECMEN = HHExp_ECMEN - HHAsstCBTRec_Cons_1M | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 9) Per-capita economic capacity (monthly) | ||
| # ----------------------------- | ||
| df <- df %>% | ||
| mutate( | ||
| PCExp_ECMEN = HHExp_ECMEN / .data[[hh_size_var]] | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 10) ECMEN classification vs MEB (per-capita) | ||
| # ----------------------------- | ||
| df <- df %>% | ||
| mutate( | ||
| ECMEN_exclAsst = if_else( | ||
| !is.na(PCExp_ECMEN) & !is.na(.data[[meb_var]]), | ||
| as.integer(PCExp_ECMEN > .data[[meb_var]]), | ||
| NA_integer_ | ||
| ) | ||
| ) | ||
|
|
||
| df <- df %>% | ||
| mutate( | ||
| ECMEN_exclAsst = factor( | ||
| ECMEN_exclAsst, | ||
| levels = c(0, 1), | ||
| labels = c("Below MEB", "Above MEB") | ||
| ) | ||
| ) | ||
|
|
||
|
|
||
| table(df$ECMEN_exclAsst, useNA = "ifany") | ||
|
|
||
| # Optional SMEB version (only if SMEB exists in your dataset) | ||
| if (smeb_var %in% names(df)) { | ||
| df <- df %>% | ||
| mutate( | ||
| ECMEN_exclAsst_SMEB = if_else( | ||
| !is.na(PCExp_ECMEN) & !is.na(.data[[smeb_var]]), | ||
| as.integer(PCExp_ECMEN > .data[[smeb_var]]), | ||
| NA_integer_ | ||
| ) | ||
| ) | ||
|
|
||
| df <- df %>% | ||
| mutate( | ||
| ECMEN_exclAsst_SMEB = factor( | ||
| ECMEN_exclAsst_SMEB, | ||
| levels = c(0, 1), | ||
| labels = c("Below MEB", "Above MEB") | ||
| ) | ||
| ) | ||
|
|
||
| smeb_tab <- table(df$ECMEN_exclAsst_SMEB, useNA = "ifany") | ||
| print(smeb_tab) | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,174 @@ | ||
| # ------------------------------------------------------------ | ||
| # WFP Standardized Scripts | ||
| # Economic Capacity to Meet Essential Needs (ECMEN) – Monitoring | ||
| # Version INCLUDING assistance (in-kind gifts/aid included) | ||
| # Last Updated: January 2026 | ||
| # ------------------------------------------------------------ | ||
|
|
||
| library(dplyr) | ||
|
|
||
| # ----------------------------- | ||
| # 0) Food expenditure inputs (7D recall) | ||
| # ----------------------------- | ||
| food_purch_7d <- c( | ||
| "HHExpFCer_Purch_MN_7D","HHExpFTub_Purch_MN_7D","HHExpFPuls_Purch_MN_7D", | ||
| "HHExpFVeg_Purch_MN_7D","HHExpFFrt_Purch_MN_7D","HHExpFAnimMeat_Purch_MN_7D", | ||
| "HHExpFAnimFish_Purch_MN_7D","HHExpFFats_Purch_MN_7D","HHExpFDairy_Purch_MN_7D", | ||
| "HHExpFEgg_Purch_MN_7D","HHExpFSgr_Purch_MN_7D","HHExpFCond_Purch_MN_7D", | ||
| "HHExpFBev_Purch_MN_7D","HHExpFOut_Purch_MN_7D" | ||
| ) | ||
|
|
||
| food_gift_7d <- c( | ||
| "HHExpFCer_GiftAid_MN_7D","HHExpFTub_GiftAid_MN_7D","HHExpFPuls_GiftAid_MN_7D", | ||
| "HHExpFVeg_GiftAid_MN_7D","HHExpFFrt_GiftAid_MN_7D","HHExpFAnimMeat_GiftAid_MN_7D", | ||
| "HHExpFAnimFish_GiftAid_MN_7D","HHExpFFats_GiftAid_MN_7D","HHExpFDairy_GiftAid_MN_7D", | ||
| "HHExpFEgg_GiftAid_MN_7D","HHExpFSgr_GiftAid_MN_7D","HHExpFCond_GiftAid_MN_7D", | ||
| "HHExpFBev_GiftAid_MN_7D","HHExpFOut_GiftAid_MN_7D" | ||
| ) | ||
|
|
||
| food_own_7d <- c( | ||
| "HHExpFCer_Own_MN_7D","HHExpFTub_Own_MN_7D","HHExpFPuls_Own_MN_7D", | ||
| "HHExpFVeg_Own_MN_7D","HHExpFFrt_Own_MN_7D","HHExpFAnimMeat_Own_MN_7D", | ||
| "HHExpFAnimFish_Own_MN_7D","HHExpFFats_Own_MN_7D","HHExpFDairy_Own_MN_7D", | ||
| "HHExpFEgg_Own_MN_7D","HHExpFSgr_Own_MN_7D","HHExpFCond_Own_MN_7D", | ||
| "HHExpFBev_Own_MN_7D","HHExpFOut_Own_MN_7D" | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 1) Non-food expenditure inputs (1M recall + 6M recall) | ||
| # Purchases (cash/credit) and GiftAid both used in monitoring ECMEN | ||
| # ----------------------------- | ||
| nf_purch_1m <- c( | ||
| "HHExpNFHyg_Purch_MN_1M","HHExpNFTransp_Purch_MN_1M","HHExpNFFuel_Purch_MN_1M", | ||
| "HHExpNFWat_Purch_MN_1M","HHExpNFElec_Purch_MN_1M","HHExpNFEnerg_Purch_MN_1M", | ||
| "HHExpNFDwelSer_Purch_MN_1M","HHExpNFPhone_Purch_MN_1M","HHExpNFRecr_Purch_MN_1M", | ||
| "HHExpNFAlcTobac_Purch_MN_1M" | ||
| ) | ||
|
|
||
| nf_gift_1m <- c( | ||
| "HHExpNFHyg_GiftAid_MN_1M","HHExpNFTransp_GiftAid_MN_1M","HHExpNFFuel_GiftAid_MN_1M", | ||
| "HHExpNFWat_GiftAid_MN_1M","HHExpNFElec_GiftAid_MN_1M","HHExpNFEnerg_GiftAid_MN_1M", | ||
| "HHExpNFDwelSer_GiftAid_MN_1M","HHExpNFPhone_GiftAid_MN_1M","HHExpNFRecr_GiftAid_MN_1M", | ||
| "HHExpNFAlcTobac_GiftAid_MN_1M" | ||
| ) | ||
|
|
||
| nf_purch_6m <- c( | ||
| "HHExpNFMedServ_Purch_MN_6M","HHExpNFMedGood_Purch_MN_6M","HHExpNFCloth_Purch_MN_6M", | ||
| "HHExpNFEduFee_Purch_MN_6M","HHExpNFEduGood_Purch_MN_6M","HHExpNFRent_Purch_MN_6M", | ||
| "HHExpNFHHSoft_Purch_MN_6M","HHExpNFHHMaint_Purch_MN_6M" | ||
| ) | ||
|
|
||
| nf_gift_6m <- c( | ||
| "HHExpNFMedServ_GiftAid_MN_6M","HHExpNFMedGood_GiftAid_MN_6M","HHExpNFCloth_GiftAid_MN_6M", | ||
| "HHExpNFEduFee_GiftAid_MN_6M","HHExpNFEduGood_GiftAid_MN_6M","HHExpNFRent_GiftAid_MN_6M", | ||
| "HHExpNFHHSoft_GiftAid_MN_6M","HHExpNFHHMaint_GiftAid_MN_6M" | ||
| ) | ||
|
|
||
| # Set these to your actual names if different | ||
| hh_size_var <- "HHSize" # household size | ||
| meb_var <- "MEB" # per-capita MEB | ||
| smeb_var <- "sMEB" # per-capita SMEB (optional) | ||
|
Comment on lines
+67
to
+70
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above, at this stage variables must be already standardized or fail noisily as the dataset is incomplete to execute this. |
||
|
|
||
| # ----------------------------- | ||
| # 2) Convert NA to 0 for expenditure inputs | ||
| # ----------------------------- | ||
| all_inputs <- c(food_purch_7d, food_gift_7d, food_own_7d, | ||
| nf_purch_1m, nf_gift_1m, nf_purch_6m, nf_gift_6m) | ||
|
|
||
| df <- df %>% | ||
| mutate(across(all_of(all_inputs), ~ as.numeric(.x))) %>% | ||
| mutate(across(all_of(all_inputs), ~ dplyr::coalesce(.x, 0))) | ||
|
|
||
| # ----------------------------- | ||
| # 3) Compute monthly food totals by source (7D -> 1M with 30/7) | ||
| # ----------------------------- | ||
| df <- df %>% | ||
| mutate( | ||
| HHExp_Food_Purch_MN_1M = rowSums(across(all_of(food_purch_7d))) * (30/7), | ||
| HHExp_Food_GiftAid_MN_1M = rowSums(across(all_of(food_gift_7d))) * (30/7), | ||
| HHExp_Food_Own_MN_1M = rowSums(across(all_of(food_own_7d))) * (30/7) | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 4) Compute monthly non-food totals (purchases + gift/aid) | ||
| # 30D + (6M/6) | ||
| # ----------------------------- | ||
| df <- df %>% | ||
| mutate( | ||
| HHExpNFTotal_Purch_MN_30D = rowSums(across(all_of(nf_purch_1m))), | ||
| HHExpNFTotal_Purch_MN_6M = rowSums(across(all_of(nf_purch_6m))), | ||
| HHExpNFTotal_Purch_MN_1M = HHExpNFTotal_Purch_MN_30D + (HHExpNFTotal_Purch_MN_6M / 6), | ||
|
|
||
| HHExpNFTotal_GiftAid_MN_30D = rowSums(across(all_of(nf_gift_1m))), | ||
| HHExpNFTotal_GiftAid_MN_6M = rowSums(across(all_of(nf_gift_6m))), | ||
| HHExpNFTotal_GiftAid_MN_1M = HHExpNFTotal_GiftAid_MN_30D + (HHExpNFTotal_GiftAid_MN_6M / 6) | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 5) Household economic capacity (MONITORING, including assistance) | ||
| # Food: Purch + GiftAid + Own | ||
| # Non-food: Purch + GiftAid | ||
| # ----------------------------- | ||
| df <- df %>% | ||
| mutate( | ||
| HHExpF_ECMEN = HHExp_Food_Purch_MN_1M + HHExp_Food_GiftAid_MN_1M + HHExp_Food_Own_MN_1M, | ||
| HHExpNF_ECMEN = HHExpNFTotal_Purch_MN_1M + HHExpNFTotal_GiftAid_MN_1M, | ||
| HHExp_ECMEN = HHExpF_ECMEN + HHExpNF_ECMEN | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 6) Per-capita economic capacity | ||
| # ----------------------------- | ||
| df <- df %>% | ||
| mutate( | ||
| PCExp_ECMEN = HHExp_ECMEN / .data[[hh_size_var]] | ||
| ) | ||
|
|
||
| # ----------------------------- | ||
| # 7) ECMEN classification vs MEB (per-capita) | ||
| # ----------------------------- | ||
| df <- df %>% | ||
| mutate( | ||
| ECMEN_inclAsst = if_else( | ||
| !is.na(PCExp_ECMEN) & !is.na(.data[[meb_var]]), | ||
| as.integer(PCExp_ECMEN > .data[[meb_var]]), | ||
| NA_integer_ | ||
| ) | ||
| ) | ||
|
|
||
| df <- df %>% | ||
| mutate( | ||
| ECMEN_inclAsst = factor( | ||
| ECMEN_inclAsst, | ||
| levels = c(0, 1), | ||
| labels = c("Below MEB", "Above MEB") | ||
| ) | ||
| ) | ||
|
|
||
| print(table(df$ECMEN_inclAsst, useNA = "ifany")) | ||
|
|
||
| # ----------------------------- | ||
| # 8) Optional SMEB version (if SMEB exists) | ||
| # ----------------------------- | ||
| if (smeb_var %in% names(df)) { | ||
| df <- df %>% | ||
| mutate( | ||
| ECMEN_inclAsst_SMEB = if_else( | ||
| !is.na(PCExp_ECMEN) & !is.na(.data[[smeb_var]]), | ||
| as.integer(PCExp_ECMEN > .data[[smeb_var]]), | ||
| NA_integer_ | ||
| ) | ||
| ) | ||
|
|
||
| df <- df %>% | ||
| mutate( | ||
| ECMEN_inclAsst_SMEB = factor( | ||
| ECMEN_inclAsst_SMEB,, | ||
| levels = c(0, 1), | ||
| labels = c("Below MEB", "Above MEB") | ||
| ) | ||
| ) | ||
|
|
||
|
|
||
| print(table(df$ECMEN_inclAsst_SMEB, useNA = "ifany")) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would approach this differently.
It should be done so that not having MEB and SMEB prevents a silent failure.
Rather, we should have a noisy error, gracefully handled, as the data to complete the procedure is missing.
We must assume variables are standard at this stage, as the normalization of the dataset should have been already executed at this stage.
#240