Emergency WASH Access for Refugees

Author
Affiliation

Whitney N Knopp

University of Colorado Boulder

Published

July 25, 2025

Introduction

Humanitarian and natural emergencies often significantly reduce access to water, sanitation and hygiene (WASH) services for refugee populations and internally displaced peoples. This negatively impacts public health and personal dignity.

My PhD research contributes to reducing the impacts of chronic and severe droughts in east Africa to increase resilience of communities, infrastructure, livelihoods and protect public health. For this analysis, I am interested in further investigating WASH access for displaced peoples in the region of east Africa. Utilizing the Sphere Handbook for humanitarian emergencies, I will evaluate each emergency for meeting the minimum standards for water and sanitation.

Methods

The data set used in this analysis comes from the United Nations High Commission on Refugees (UNHCR). It documents access to WASH services in refugee camps through numerous indicators collected over 12 years. The UNHCR WASH data are available as a package in R with documentation in github (Yash Dubey, 2024).

library(unhcrwash)
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.2     ✔ tibble    3.2.1
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.0.4     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(gt)
library(unhcrwash)

Reading the Data

# there are 2 ways to read in this data because it is also a package in R

# read data with R package
unhcrWASH_raw <- unhcrwash

# read csv from the /data path
unhcrwash_raw <- read_csv(here::here("data/raw/unhcrwash.csv"))
Rows: 6425 Columns: 27
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr  (6): start_date, end_date, location_name, country, post_emergency, repo...
dbl (21): form_id, location_id, persons_per_handpump, persons_per_tap, liter...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Data Exploration Approach

# investigate the data imported data
head(unhcrWASH_raw)
# A tibble: 6 × 27
  form_id start_date end_date   location_id location_name country post_emergency
    <dbl> <date>     <date>           <dbl> <chr>         <chr>   <chr>         
1  5.44e7 2024-01-01 2024-12-31         518 Dagahaley     Kenya   <NA>          
2  5.44e7 2024-01-01 2024-12-31         519 Hagadera      Kenya   <NA>          
3  5.44e7 2024-01-01 2024-12-31         520 Ifo           Kenya   <NA>          
4  5.44e7 2024-01-01 2024-12-31        5105 Ifo 2         Kenya   <NA>          
5  5.44e7 2024-12-02 2024-12-29         541 Buramino      Ethiop… Post-emergency
6  5.44e7 2024-09-02 2024-09-29         209 Lovua settle… Angola  Post-emergency
# ℹ 20 more variables: persons_per_handpump <dbl>, persons_per_tap <dbl>,
#   liters_per_person_per_day <dbl>, non_chlorinated_0_cfu <dbl>,
#   chlorinated_safe_water_quality <dbl>, households_with_toilet <dbl>,
#   persons_per_toilet <dbl>, persons_per_shower <dbl>,
#   persons_per_hygiene_promoter <dbl>, refugee_pop <dbl>,
#   reporting_monthly <dbl>, liters_per_person_household <dbl>,
#   potable_water_storage_10l <dbl>, protected_water_sources <dbl>, …
dim(unhcrWASH_raw)
[1] 6425   27
# there are 27 variables as columns and 6425 observations
# some of these variables are not very relevant: form_id, location_id, reporting_period_monthly_indicator, reporting_period_annual_indicator

# summarizing some of the data
unhcrwash_raw |> 
  filter(!is.na(country)) |> 
  group_by(country) |> 
  summarize(no_emergencies = n(),
            no_refugee_camps = n_distinct(location_name),
            total_refugee_pop = sum(refugee_pop, na.rm = TRUE),
            avg_L_per_person_per_day = mean(liters_per_person_per_day, na.rm = TRUE)) |> 
  knitr::kable(digits = 1)
country no_emergencies no_refugee_camps total_refugee_pop avg_L_per_person_per_day
Algeria 248 5 4078536 33.4
Angola 44 1 302847 23.8
Bangladesh 56 13 371124 35.9
Brazil 15 10 8164 13.3
Burkina Faso 23 2 135109 18.7
Burundi 8 4 87045 23.2
Cameroon 450 8 7296442 14.7
Chad 926 32 15437507 21.3
Colombia 16 1 7010 25.4
Democratic Republic of the Congo 265 12 3552800 43.9
Djibouti 72 2 921147 16.9
Eritrea 1 1 0 NaN
Ethiopia 979 27 30630168 16.9
Ghana 131 4 199091 38.1
India 1 1 0 NaN
Iraq 249 5 1741418 99.1
Jordan 31 2 1618740 40.1
Kenya 218 4 18034151 23.5
Malawi 69 1 3081308 10.7
Mozambique 22 1 186563 11.2
Namibia 6 1 25801 28.2
Nepal 2 1 5806 32.0
Niger 341 9 2811338 12.9
Nigeria 80 4 663519 12.8
Pakistan 1 1 8948 4.0
Republic of Congo 22 2 41894 15.7
Rwanda 432 10 7630163 33.4
Somalia 1 1 0 NaN
South Sudan 239 7 8969188 19.9
Sudan 793 33 12848789 17.3
Tanzania 210 5 12410980 27.1
Uganda 377 10 33730168 16.0
Yemen 1 1 0 NaN
Zambia 57 4 909294 23.7
Zimbabwe 37 1 393223 18.0
# summary of all data  
unhcrWASH_raw |> 
  filter(!is.na(country)) |> 
  group_by(country) |> 
  summarize(no_emergencies = n(),
            no_refugee_camps = n_distinct(location_name),
            total_refugee_pop = sum(refugee_pop, na.rm = TRUE),
            avg_L_per_person_per_day = mean(liters_per_person_per_day, na.rm = TRUE)) |> 
  knitr::kable(digits = 1)
country no_emergencies no_refugee_camps total_refugee_pop avg_L_per_person_per_day
Algeria 248 5 4078536 33.4
Angola 44 1 302847 23.8
Bangladesh 56 13 371124 35.9
Brazil 15 10 8164 13.3
Burkina Faso 23 2 135109 18.7
Burundi 8 4 87045 23.2
Cameroon 450 8 7296442 14.7
Chad 926 32 15437507 21.3
Colombia 16 1 7010 25.4
Democratic Republic of the Congo 265 12 3552800 43.9
Djibouti 72 2 921147 16.9
Eritrea 1 1 0 NaN
Ethiopia 979 27 30630168 16.9
Ghana 131 4 199091 38.1
India 1 1 0 NaN
Iraq 249 5 1741418 99.1
Jordan 31 2 1618740 40.1
Kenya 218 4 18034151 23.5
Malawi 69 1 3081308 10.7
Mozambique 22 1 186563 11.2
Namibia 6 1 25801 28.2
Nepal 2 1 5806 32.0
Niger 341 9 2811338 12.9
Nigeria 80 4 663519 12.8
Pakistan 1 1 8948 4.0
Republic of Congo 22 2 41894 15.7
Rwanda 432 10 7630163 33.4
Somalia 1 1 0 NaN
South Sudan 239 7 8969188 19.9
Sudan 793 33 12848789 17.3
Tanzania 210 5 12410980 27.1
Uganda 377 10 33730168 16.0
Yemen 1 1 0 NaN
Zambia 57 4 909294 23.7
Zimbabwe 37 1 393223 18.0
# summary of past emergencies in East Africa in the past 10 years (2015 to 2025)
eastAfrica <- c("Kenya", "Uganda", "Rwanda", "Tanzania", "Ethiopia", "Eritra", "Dijbouti", "Somalia")

# create emergency end column for year, month and date
# convert end_year into a factor
unhcrWASH_raw |> 
  separate(col = end_date, into = c("end_year", "end_month", "end_day"), sep = "-") |> 
  mutate(end_year = as.numeric(end_year)) |> 
  filter(country %in% eastAfrica, post_emergency == "Post-emergency") |> 
  filter(end_year < 2025 & end_year > 2015) |> 
  group_by(country) |> 
  summarize(no_emergencies = n(),
            no_refugee_camps = n_distinct(location_name),
            total_refugee_pop = sum(refugee_pop, na.rm = TRUE),
            avg_L_per_person_per_day = mean(liters_per_person_per_day, na.rm = TRUE)) |> 
  knitr::kable(digits = 1)
country no_emergencies no_refugee_camps total_refugee_pop avg_L_per_person_per_day
Ethiopia 872 26 30488654 16.7
Kenya 206 4 18034151 23.5
Rwanda 401 10 7610769 33.8
Tanzania 193 5 12410980 27.1
Uganda 314 10 32237438 16.3

Initial Data Tidying

Some of the issues I encountered with the raw data, which I would like to fix with tidying include:

  • Remove any entries without country information

  • Adding an end_year column for analysis (this will be a factor)

  • Removing some columns that are not relevant: form_id, location_id, reporting_period_monthly_indicator, reporting_period_annual_indicator, month/day columns that come from creating an end_year column

  • Change the country variable type from a character to a factor

  • Add a column with the duration of the emergency

  • Some entries have a refugee population of 0 (which does not seem likely, I will change these to NA)

Some of this data tidying depends on the method to bring in the data. If the data is imported as an R package, the dates already exist as a date variable, but importing as a csv, they must be changed. Additionally, the dates are separated with a - in the data imported as an R package and with a / in the csv file. Because of these differences, I will use the data frame imported from the R package for simplicity.

# tidy data based on goals listed above
unhcrWASH_tidy <- unhcrWASH_raw |> 
  filter(!is.na(country)) |> 
  mutate(duration_emergency = as.numeric(end_date - start_date)) |> 
  separate(col = end_date, into = c("end_year", "month", "date"), sep = "-") |> 
  mutate(end_year = as.integer(end_year)) |> 
  select(-c("form_id", "location_id", "reporting_monthly", "reporting_annual", "month","date")) |> 
  relocate(duration_emergency, .after = end_year) |> 
  mutate(country = as.factor(country)) |> 
  mutate(refugee_pop = na_if(refugee_pop, 0))

# save as tidy data
write_csv(unhcrWASH_tidy, here::here("data/processed/unhcrwash_tidy.csv"))

# some of my analysis will specifically focus on the region of east Africa, I will subset data 
unhcrWASH_eastAfrica_tidy <- unhcrWASH_tidy |> 
  filter(country %in% eastAfrica)

Results

To assess WASH services in east Africa, analysis was conducted for water, sanitation and synthesized for overall results. Adequacy of services were measured in accordance with standards established in the Sphere Handbook chapter on water supply, sanitation and hygiene promotion. The Sphere Handbook include guiding standards for emergency humanitarian response (Project, 2018).

Water

Safe water consists of water that is available in adequate quantities, accessible on premise and free from microbial and priority chemical contaminants (Assembly, 1977). Water supply standard 2.1 focuses on access and availability, with a key indicator being a minimum of 15 L/person/day for drinking and domestic needs (Project, 2018). Figure 1 aims to understand if water access during emergencies in east Africa has improved over the past 10 years (2015 - 2025) as well as countries where water access/availability needs are perpetually met/not achieved. The data does not highlight a trends of increasing access over years of emergencies. However, it is noted that between 2015 and 2025, refugee camps during emergencies in Uganda most often did not provide adequate quantities of drinking water. Conversely, refugee camps in Rwanda consistently were able to deliver adequate quantities of water for drinking and domestic uses.

Water Quantity

# this first portion of the analysis will focus on minimum water access for each emergency in East Africa in the last 10 years
# I am interested in investigating if access to water has improved over time and if there are countries that typically meet needs more or less
# I also want to see if in general, taps or handpumps provide a more appropriate amount of water

# remove outliers with IQR method
qnt <- quantile(unhcrWASH_tidy$liters_per_person_per_day, probs=c(.25, .75), na.rm = T)
iqr <- IQR(unhcrWASH_tidy$liters_per_person_per_day, na.rm = T)
lower <- qnt[1] - 1.5*iqr
upper <- qnt[2] + 1.5*iqr

#results = subset(results, results$Ecoli < upper & results$Ecoli > lower)

unhcrWASH_tidy_WQuant <- unhcrWASH_eastAfrica_tidy |> 
  subset(post_emergency == "Emergency" & 
           start_date > "2015-01-01" & 
           liters_per_person_per_day < upper & 
           liters_per_person_per_day > lower) |> 
  group_by(country) 

unhcrWASH_tidy_WQuant|> 
  ggplot() +
  geom_point(data = unhcrWASH_tidy_WQuant,
             mapping = aes(x = start_date,
                       y = liters_per_person_per_day,
                       color = country)) +
  scale_color_brewer(palette = "Accent", name = "Country") +
  theme_minimal() + 
  labs(title = "Emergency drinking water access for refugees in east Africa",
       subtitle = "In accordance with the Sphere minimum standard of 15 L/person/day",
       x = "End date of survey",
       y = "Liters per person per day") + 
  geom_hline(yintercept = 15, color = "purple")
Figure 1: Water quantity for displaced people

Water Quality

The other key component of safe water access is water quality. The Sphere Handbook, standard 2.1, requires tests where drinking water has turbidity below 5 NTU and a residual free chlorine level between 0.2 and 2 mg/L (Project, 2018). Figure 2 is a box plot of the percentage of water quality tests after an emergency that comply with Sphere standards. Table 1 presented the summary statistics for each country. On average, more than 90% of water quality tests for all east African countries complied with Sphere standards.

 # remove lower-bound outliers; upper-bound is 100
qnt <- quantile(unhcrWASH_tidy$chlorinated_safe_water_quality, probs=c(.25, .75), na.rm = T)
iqr <- IQR(unhcrWASH_tidy$chlorinated_safe_water_quality, na.rm = T)
lower <- qnt[1] - 1.5*iqr

unhcrWASH_eastAfrica_tidy |> 
    subset(post_emergency == "Post-emergency" & 
           start_date > "2015-01-01" &
           chlorinated_safe_water_quality < 100 & 
           chlorinated_safe_water_quality > lower) |> 
  ggplot(mapping = aes(x = country,
                       y = chlorinated_safe_water_quality,
                       color = country)) +
  geom_boxplot(outlier.shape = NA) +
  geom_jitter(alpha = 2/4) +
  labs(title = "Water quality at refugee camp collection points in east African countries post-emergency",
       subtitle = "Tests meeting Sphere Standards",
       x = "Country",
       y = "Percent of testing meeting standards") +
  theme_minimal() +
  theme(legend.position = "none")
Figure 2: Percentage of water quality tests in refugee camps complying with Sphere Minimum Standards for east African countries post-emergency
unhcrWASH_eastAfrica_tidy |> 
    subset(post_emergency == "Post-emergency" & 
           start_date > "2015-01-01" &
           chlorinated_safe_water_quality < 100 & 
           chlorinated_safe_water_quality > lower) |> 
  group_by(country) |> 
  summarize(min = min(chlorinated_safe_water_quality),
            max = max(chlorinated_safe_water_quality),
            median = median(chlorinated_safe_water_quality),
            mean = mean(chlorinated_safe_water_quality),
            std_dev = sd(chlorinated_safe_water_quality),
            first_q = quantile(chlorinated_safe_water_quality, probs = 0.25),
            third_q = quantile(chlorinated_safe_water_quality, probs = 0.75)) |> 
  gt() |> 
  tab_header(
    title = "Water Quality Summary Statistics",
    subtitle = "Percentage of water quality tests meeting Sphere standards") |> 
  fmt_number(
    decimals = 1
  ) |> 
  cols_label(
    country = "Country",
    min = "Mimimum Percentage of Tests",
    max = "Maximum Percentage of Tests",
    median = "Median (50th percentile)",
    mean = "Average",
    std_dev = "Standard Deviation",
    first_q = "25th Percentile",
    third_q = "75th Percentile")
Table 1: Statistics for water quality tests meeting Sphere Standards for east African countries
Water Quality Summary Statistics
Percentage of water quality tests meeting Sphere standards
Country Mimimum Percentage of Tests Maximum Percentage of Tests Median (50th percentile) Average Standard Deviation 25th Percentile 75th Percentile
Ethiopia 83.0 99.0 96.0 94.6 3.9 93.0 97.5
Kenya 83.0 99.0 97.0 95.6 4.2 94.0 99.0
Rwanda 87.0 98.0 97.0 95.2 3.7 95.0 97.0
Tanzania 86.0 99.0 95.0 94.5 4.3 90.0 98.0
Uganda 83.0 99.0 92.0 92.0 4.3 88.0 96.0

Sanitation

Sanitation is the second component of WASH. The Sphere standard for sanitation access is 2.2, which requires a maximum of 15 persons per toilet in emergencies (Project, 2018). This standard might be influenced by the number of refugees at a refugee camp. Figure 3 plots persons per toilet as a function of refugee population to identify sanitation access trends between countries and refugee population. Little correlation between population and sanitation access is displayed Figure 3, notably, in Uganda, Kenya and Tanzania, toilets are very frequently shared between less than 15 people in the majority of refugee camps.

unhcrWASH_eastAfrica_tidy |> 
  filter(!is.na(refugee_pop),
         refugee_pop < 1000000) |> # remove outliers
  ggplot(mapping = aes(x = refugee_pop,
                       y = persons_per_toilet,
                       color = country,
                       shape = post_emergency)) +
  geom_point() +
  geom_hline(yintercept = 15, 
             type = "dash",
             color = "grey") + 
  labs(title = "Impact of refugee population size on sanitation access",
       subtitile = "Evaluated against Sphere standard 3.2 for sanitation",
       x = "Refugee Population",
       y = "Number of People per Toilet",
       color = "Country",
       shape = "Emergency Type") +
  theme_minimal() +
  scale_color_brewer(palette = "Dark2")
Warning in geom_hline(yintercept = 15, type = "dash", color = "grey"): Ignoring
unknown parameters: `type`
Warning: Removed 29 rows containing missing values or values outside the scale range
(`geom_point()`).
Figure 3: Refugee camp population vs number of people per toilet

Overview

Water and sanitation services are often related, as agencies tasked with WASH provision in emergencies may support both. Figure 4 plots water and sanitation access, as L/person/day and persons/toilet, respectively, for ongoing and previous emergencies in east Africa. Ideally, emergencies fall in the bottom right section created by the 2 horizontal lines, signifying that refugees have adequate drinking water access and less than the maximum number of persons per toilet. Table 2 presents a summary of WASH access.

# compare drinking water and sanitation access
unhcrWASH_eastAfrica_tidy |> 
  ggplot() +
  geom_point(mapping = aes(x = liters_per_person_per_day,
                       y = persons_per_toilet,
                       color = country,
                       shape = post_emergency)) +
  geom_hline(yintercept = 15,
             color = "purple") +
  geom_vline(xintercept = 15,
             color = "navy") +
  scale_x_continuous(limits = c(0, 75)) + # axes chosen to get a closer look at trends between countries
  scale_y_continuous(limits = c(0, 75)) +
  labs(title = "Sanitation vs Water Access in East African Refugee Camps",
       subtitile = "Evaluated against Sphere standard 3.1 for water access and 3.2 for sanitation",
       x = "Liters per Person per Day",
       y = "Number of People per Toilet",
       color = "Country",
       shape = "Emergency Type") +
  theme_minimal() +
  scale_color_brewer(palette = "Paired")
Warning: Removed 256 rows containing missing values or values outside the scale range
(`geom_point()`).
Figure 4: Water and sanitation access metrics for refugees in east Africa
not_needed <- c("start_date", "end_year", "duration_emergency", "persons_per_handpump", "persons_per_tap", "non_chlorinated_0_cfu", "households_with_toilet", "persons_per_shower", "persons_per_hygiene_promoter", "liters_per_person_household", "potable_water_storage_10l", "protected_water_sources", "menstrual_hygiene_satisfaction",  "household_toilet", "defecate_in_toilet", "access_to_soap", "solid_waste_disposal_access")

unhcrWASH_eastAfrica_tidy |> 
  select(-not_needed) |> 
  group_by(country) |> 
  filter(country != "Somalia") |> # no data for Somalia
  mutate(location_name = factor(location_name)) |> 
  summarize(no_emergencies = n(),
            no_refugee_camps = n_distinct(location_name),
            avg_L_water_per_person = mean(liters_per_person_per_day, na.rm = T),
            avg_pct_safe_water_quality = mean(chlorinated_safe_water_quality, na.rm = T),
            avg_people_per_toilet = mean(persons_per_toilet, na.rm = T)) |> 
  gt() |> 
  tab_header(
    title = "Water and Sanitation Access in East Africa during Emergencies",
    subtitle = "") |> 
  fmt_number(
    columns = starts_with("avg"), 
    decimals = 1
  ) |> 
  cols_label(
    country = "Country",
    no_emergencies = "Number of Emergencies",
    no_refugee_camps = "Number of Refugee Camps",
    avg_L_water_per_person = "Average Daily Water per Person (L/person/day)",
    avg_pct_safe_water_quality = "Average Percentage of Adequate Water Quality",
    avg_people_per_toilet = "Average Number of People per Toilet")
Warning: Using an external vector in selections was deprecated in tidyselect 1.1.0.
ℹ Please use `all_of()` or `any_of()` instead.
  # Was:
  data %>% select(not_needed)

  # Now:
  data %>% select(all_of(not_needed))

See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
Table 2: Summary of average water and santiation access during emergencies for east Africa
Water and Sanitation Access in East Africa during Emergencies
Country Number of Emergencies Number of Refugee Camps Average Daily Water per Person (L/person/day) Average Percentage of Adequate Water Quality Average Number of People per Toilet
Ethiopia 979 27 16.9 95.6 22.9
Kenya 218 4 23.5 94.9 8.7
Rwanda 432 10 33.4 95.7 20.1
Tanzania 210 5 27.1 95.5 6.5
Uganda 377 10 16.0 80.2 6.6

Conclusions

Summary of Findings

  • Water access in refugee camps has not significantly improved over the last 10 years, this is more often predicted by country of refugee camp

  • No overt trends are able to be discerned from refugee population vs number of persons per toilet, this is an apparent challenge for Ethiopian refugee camps, but a strength for Ugandan, Kenyan and Tanzanian refugee camps during and after emergencies

  • On average, it is more challenging to achieve sanitation minimum standards than drinking water access

Questions and Next Steps

This is an extremely large data set, my analysis draws conclusions on current and post-emergency situations in east Africa. A next step in is to scale up to a global analysis by breaking the data into region and income level to better understand global trends in emergency WASH access.

References

Assembly, U. G. (1977). United nations publication, sales no. E.97.IV.6), chap. I, resolution 1, annex II. 3 report of the united nations water conference. In Treaty Series: Vol. I (p. 27531). United Nations General Assembly.
Project, T. S. (2018). The sphere handbook 2018. In Publisher: Practical Action; Pap/Cdr edition.
Yash Dubey. (2024). Openwashdata/unhcrwash: First release. Zenodo. https://doi.org/10.5281/ZENODO.14185117