library(tidyverse)
library(readxl)
library(janitor)
library(here)
library(scales)
library(knitr)
library(forcats)
knitr::opts_chunk$set(
message = FALSE,
warning = FALSE,
fig.width = 11,
fig.height = 7,
dpi = 300
)
theme_set(theme_minimal(base_size = 12))
This analysis supports the Mozambique case study for the proposed manuscript “Operationalizing the Effectiveness of Fisheries Other Effective Area-based Conservation Measures: A Composite Coastal Resilience Framework”.
The aim is to use the Mozambique household survey data to show how the Composite Coastal Resilience Framework (CCRF) can diagnose relative strengths and weaknesses across resilience domains. Here, we analyse two HHS-based core components:
The analysis is descriptive. The results can show patterns across places and years and can be connected to the package of initiatives implemented in each site, but they should not be interpreted as causal impacts without a stronger evaluation design.
# # Data paths
#
# This R Markdown assumes the files are stored in `data/raw/` inside the R project.
# The path chunk below uses the same direct `here("data", "raw", ...)` structure you were already using.
# Put the input files in data/raw/ inside this R project, or edit the paths below.
hhs_file <- here("data", "raw", "all_hhs_moz.csv")
# Optional context files, used mainly for checking the project context.
# The core HHS analysis below uses the HHS file and the cleaned crosswalk created in the Rmd.
annex_file <- here(
"data", "raw",
"ANNEX III_BAF_EbA_Rare_Site Specific Information_2022-06-20(1).xlsx"
)
beneficiary_file <- here(
"data", "raw",
"Beneficiaries and overlaps(1).xlsx"
)
# Load data
hhs_raw <- read_csv(hhs_file, show_col_types = FALSE) %>%
clean_names()
# The two Excel files are used mainly to define the program context and project-site crosswalk.
# The HHS analysis itself uses `all_hhs_moz.csv`.
# Inspect Excel sheets only if the optional files are present.
# This prevents the Rmd from failing when you only have the HHS CSV available.
if (file.exists(annex_file)) {
annex_sheets <- excel_sheets(annex_file)
annex_sheets
} else {
annex_sheets <- character(0)
message("Optional annex Excel file not found; continuing with HHS-only analysis.")
}
if (file.exists(beneficiary_file)) {
beneficiary_sheets <- excel_sheets(beneficiary_file)
beneficiary_sheets
} else {
beneficiary_sheets <- character(0)
message("Optional beneficiary Excel file not found; continuing with HHS-only analysis.")
}
# These objects are useful for checking the original context files.
# The actual analysis below uses a cleaned project-site crosswalk because the Excel files contain merged cells and notes.
# They are optional: if the files are not present, the Rmd still runs.
if (file.exists(annex_file)) {
livelihoods_raw <- read_excel(annex_file, sheet = "3. Livelihoods") %>%
clean_names()
} else {
livelihoods_raw <- NULL
}
if (file.exists(beneficiary_file)) {
beneficiaries_raw <- read_excel(beneficiary_file, sheet = "Target Reached Individuals") %>%
clean_names()
} else {
beneficiaries_raw <- NULL
}
# Helper functions
clean_place <- function(x) {
x %>%
as.character() %>%
iconv(from = "UTF-8", to = "ASCII//TRANSLIT") %>%
str_to_lower() %>%
str_replace_all("\\s+", " ") %>%
str_squish() %>%
str_replace_all("\\s*-\\s*", "-")
}
mean_na <- function(x) {
if (all(is.na(x))) {
return(NA_real_)
}
mean(x, na.rm = TRUE)
}
median_na <- function(x) {
if (all(is.na(x))) {
return(NA_real_)
}
median(x, na.rm = TRUE)
}
p25_na <- function(x) {
if (all(is.na(x))) {
return(NA_real_)
}
as.numeric(quantile(x, 0.25, na.rm = TRUE))
}
p75_na <- function(x) {
if (all(is.na(x))) {
return(NA_real_)
}
as.numeric(quantile(x, 0.75, na.rm = TRUE))
}
Important harmonization decisions:
Memba and Memba-sede in the HHS were
treated as Memba Sede.Insular and Ilha Insular were treated as
Ilha Insular.Mahilene and Mahelene were treated as
Mahelene.Namige-sede / Namalungo in the livelihoods sheet is
ambiguous because one row combines Namige-sede and Namalungo, while
another row lists Namalungo separately.program_context <- tribble(
~project_site, ~district, ~population_total, ~reached_individuals, ~program_maturity, ~fmp_status, ~main_livelihood_package, ~site_specific_notes,
"Sanculo", "Ilha de Mocambique", 38195, 2022, "Former/older Rare site", "FMP approved district/provincial; national review", "Microenterprises; regenerative agriculture; TVET; markets; poultry; nutrition; aquaculture", "Aquaculture active in Sanculo; two tanks completed and one group started fish farming",
"Ilha Insular", "Ilha de Mocambique", 9062, 728, "Former/older Rare site", "FMP approved district/provincial; national review", "Microenterprises; regenerative agriculture; TVET; markets; poultry; nutrition", "Full behavior adoption campaign implemented in Ilha district",
"Quissanga", "Ilha de Mocambique", 18553, 775, "Former/older Rare site", "FMP approved district/provincial; national review", "Microenterprises; regenerative agriculture; TVET; markets; poultry; nutrition", "Aquaculture group reportedly resettled and reallocated to agriculture",
"Memba Sede", "Memba", 22572, 2026, "Former/older Rare site", "FMP approved district/provincial; national review", "Microenterprises; regenerative agriculture; TVET; markets; poultry; nutrition", "Watch tower handed over; mangrove and seagrass restoration relevant; mid-term HHS delayed due to security",
"Baixo Pinda", "Memba", 7122, 998, "Former/older Rare site", "FMP approved district/provincial; national review", "Microenterprises; regenerative agriculture; TVET; markets; poultry; nutrition", "CCP room completed but handover delayed by security; mangrove/seagrass restoration relevant",
"Namige Sede", "Mogincual", 65890, 1735, "Newer expansion site", "FMP under development / approval process", "Microenterprises; regenerative agriculture; TVET; markets; poultry; nutrition; apiculture", "Mangrove restoration and hydrological restoration relevant",
"Namalungo", "Mogincual", 5000, 1793, "Newer expansion site", "FMP under development / approval process", "Microenterprises; regenerative agriculture; TVET; markets; poultry; nutrition; apiculture", "CCP room under construction; beekeeping kits replaced after protests/cyclone losses",
"Meculuvelane", "Mogincual", 5117, 856, "Newer expansion site", "FMP under development / approval process", "Microenterprises; regenerative agriculture; TVET; markets; poultry; nutrition; apiculture", "CCP room under construction; disaster-risk committees revitalized",
"Quissimajulo", "Nacala Porto", 9411, 1892, "Newer expansion site", "FMP under development / approval process", "Microenterprises; regenerative agriculture; TVET; markets; poultry; nutrition", "CCVA results validated with Quissimajulo and Mahelene; CCP room under construction",
"Mahelene", "Nacala Porto", 4118, 1832, "Newer expansion site", "FMP under development / approval process", "Microenterprises; regenerative agriculture; TVET; markets; poultry; nutrition", "CCVA results validated; land/permits secured for CCP room; some cooperative governance concerns noted"
) %>%
mutate(
project_site_clean = clean_place(project_site),
district_clean = clean_place(district)
)
program_context %>%
select(project_site, district, population_total, reached_individuals, program_maturity, fmp_status, site_specific_notes) %>%
kable(caption = "Project-site context")
| project_site | district | population_total | reached_individuals | program_maturity | fmp_status | site_specific_notes |
|---|---|---|---|---|---|---|
| Sanculo | Ilha de Mocambique | 38195 | 2022 | Former/older Rare site | FMP approved district/provincial; national review | Aquaculture active in Sanculo; two tanks completed and one group started fish farming |
| Ilha Insular | Ilha de Mocambique | 9062 | 728 | Former/older Rare site | FMP approved district/provincial; national review | Full behavior adoption campaign implemented in Ilha district |
| Quissanga | Ilha de Mocambique | 18553 | 775 | Former/older Rare site | FMP approved district/provincial; national review | Aquaculture group reportedly resettled and reallocated to agriculture |
| Memba Sede | Memba | 22572 | 2026 | Former/older Rare site | FMP approved district/provincial; national review | Watch tower handed over; mangrove and seagrass restoration relevant; mid-term HHS delayed due to security |
| Baixo Pinda | Memba | 7122 | 998 | Former/older Rare site | FMP approved district/provincial; national review | CCP room completed but handover delayed by security; mangrove/seagrass restoration relevant |
| Namige Sede | Mogincual | 65890 | 1735 | Newer expansion site | FMP under development / approval process | Mangrove restoration and hydrological restoration relevant |
| Namalungo | Mogincual | 5000 | 1793 | Newer expansion site | FMP under development / approval process | CCP room under construction; beekeeping kits replaced after protests/cyclone losses |
| Meculuvelane | Mogincual | 5117 | 856 | Newer expansion site | FMP under development / approval process | CCP room under construction; disaster-risk committees revitalized |
| Quissimajulo | Nacala Porto | 9411 | 1892 | Newer expansion site | FMP under development / approval process | CCVA results validated with Quissimajulo and Mahelene; CCP room under construction |
| Mahelene | Nacala Porto | 4118 | 1832 | Newer expansion site | FMP under development / approval process | CCVA results validated; land/permits secured for CCP room; some cooperative governance concerns noted |
hhs <- hhs_raw %>%
mutate(
year = as.integer(year),
site_name = as.character(g1_community),
community_clean = clean_place(g1_community),
municipality_clean = clean_place(g1_municipality),
province_clean = clean_place(g1_province),
project_site = case_when(
community_clean %in% c("sanculo") ~ "Sanculo",
community_clean %in% c("ilha insular", "insular") ~ "Ilha Insular",
community_clean %in% c("quissanga") ~ "Quissanga",
community_clean %in% c("memba", "memba-sede", "memba sede") ~ "Memba Sede",
community_clean %in% c("baixo pinda", "baixo pinda") ~ "Baixo Pinda",
community_clean %in% c("namige sede", "namige-sede") ~ "Namige Sede",
community_clean %in% c("namalungo") ~ "Namalungo",
community_clean %in% c("meculuvelane") ~ "Meculuvelane",
community_clean %in% c("quissimajulo") ~ "Quissimajulo",
community_clean %in% c("mahelene", "mahilene") ~ "Mahelene",
TRUE ~ NA_character_
),
is_project_site = !is.na(project_site)
) %>%
left_join(program_context, by = "project_site")
coverage_summary <- tibble(
records = nrow(hhs),
years = paste(sort(unique(hhs$year)), collapse = ", "),
n_years = n_distinct(hhs$year),
n_provinces = n_distinct(hhs$g1_province),
n_municipalities = n_distinct(hhs$g1_municipality),
n_communities = n_distinct(hhs$g1_community),
project_site_records = sum(hhs$is_project_site),
non_project_site_records = sum(!hhs$is_project_site),
pct_records_in_project_sites = project_site_records / records * 100
)
coverage_summary %>%
mutate(across(where(is.numeric), ~round(.x, 1))) %>%
kable(caption = "Overall HHS coverage")
| records | years | n_years | n_provinces | n_municipalities | n_communities | project_site_records | non_project_site_records | pct_records_in_project_sites |
|---|---|---|---|---|---|---|---|---|
| 7297 | 2019, 2021, 2023, 2024, 2025, 2026 | 6 | 4 | 9 | 27 | 3894 | 3403 | 53.4 |
records_by_year <- hhs %>%
count(year, name = "n_hhs") %>%
arrange(year)
records_by_year %>%
kable(caption = "HHS records by survey year")
| year | n_hhs |
|---|---|
| 2019 | 1460 |
| 2021 | 2493 |
| 2023 | 313 |
| 2024 | 711 |
| 2025 | 1865 |
| 2026 | 455 |
ggplot(records_by_year, aes(x = factor(year), y = n_hhs)) +
geom_col(width = 0.7) +
geom_text(aes(label = comma(n_hhs)), vjust = -0.25, size = 3.5) +
scale_y_continuous(labels = comma, expand = expansion(mult = c(0, 0.08))) +
labs(
title = "Mozambique HHS coverage by year",
x = "Survey year",
y = "Number of HHS records"
)
records_by_province_year <- hhs %>%
count(g1_province, year, name = "n_hhs") %>%
arrange(g1_province, year)
records_by_province_year %>%
kable(caption = "HHS records by province and year")
| g1_province | year | n_hhs |
|---|---|---|
| Inhambane | 2019 | 560 |
| Inhambane | 2021 | 1288 |
| Inhambane | 2025 | 600 |
| Maputo | 2019 | 165 |
| Maputo | 2021 | 152 |
| Nampula | 2019 | 534 |
| Nampula | 2021 | 1024 |
| Nampula | 2023 | 313 |
| Nampula | 2024 | 711 |
| Nampula | 2025 | 1265 |
| Nampula | 2026 | 455 |
| Sofala | 2019 | 201 |
| Sofala | 2021 | 29 |
ggplot(records_by_province_year, aes(x = factor(year), y = n_hhs, fill = g1_province)) +
geom_col(width = 0.75) +
scale_y_continuous(labels = comma) +
labs(
title = "HHS coverage by province and year",
x = "Survey year",
y = "Number of HHS records",
fill = "Province"
) +
theme(legend.position = "bottom")
records_by_municipality_year <- hhs %>%
count(g1_province, g1_municipality, year, name = "n_hhs") %>%
arrange(g1_province, g1_municipality, year)
records_by_municipality_year %>%
kable(caption = "HHS records by municipality and year")
| g1_province | g1_municipality | year | n_hhs |
|---|---|---|---|
| Inhambane | Inharrime | 2019 | 223 |
| Inhambane | Inharrime | 2021 | 228 |
| Inhambane | Inhassoro | 2019 | 197 |
| Inhambane | Inhassoro | 2021 | 923 |
| Inhambane | Inhassoro | 2025 | 600 |
| Inhambane | Massinga | 2019 | 140 |
| Inhambane | Massinga | 2021 | 137 |
| Maputo | Matutuíne | 2019 | 165 |
| Maputo | Matutuíne | 2021 | 152 |
| Nampula | Ilha de Mocambique | 2019 | 327 |
| Nampula | Ilha de Mocambique | 2021 | 322 |
| Nampula | Ilha de Mocambique | 2023 | 313 |
| Nampula | Ilha de Mocambique | 2025 | 957 |
| Nampula | Memba | 2019 | 207 |
| Nampula | Memba | 2021 | 702 |
| Nampula | Memba | 2024 | 145 |
| Nampula | Memba | 2026 | 274 |
| Nampula | Mogincual | 2024 | 306 |
| Nampula | Mogincual | 2025 | 308 |
| Nampula | Nacala Porto | 2024 | 260 |
| Nampula | Nacala Porto | 2026 | 181 |
| Sofala | Dondo | 2019 | 201 |
| Sofala | Dondo | 2021 | 29 |
ggplot(records_by_municipality_year,
aes(x = factor(year), y = fct_reorder(g1_municipality, n_hhs, .fun = sum), fill = n_hhs)) +
geom_tile(color = "white") +
geom_text(aes(label = if_else(n_hhs == 0, "", as.character(n_hhs))), size = 3) +
scale_fill_gradient(low = "grey95", high = "grey25", labels = comma) +
labs(
title = "HHS coverage by municipality and year",
x = "Survey year",
y = "Municipality",
fill = "HHS records"
)
community_coverage <- hhs %>%
count(g1_province, g1_municipality, g1_community, year, name = "n_hhs") %>%
arrange(g1_province, g1_municipality, g1_community, year)
community_totals <- hhs %>%
count(g1_province, g1_municipality, g1_community, name = "n_hhs") %>%
arrange(desc(n_hhs))
community_totals %>%
kable(caption = "Total HHS records by community / site")
| g1_province | g1_municipality | g1_community | n_hhs |
|---|---|---|---|
| Nampula | Ilha de Mocambique | Ilha Insular | 1124 |
| Inhambane | Inhassoro | Fequete | 500 |
| Inhambane | Inharrime | Zavora | 451 |
| Nampula | Ilha de Mocambique | Sanculo | 430 |
| Nampula | Memba | Memba | 420 |
| Nampula | Memba | Baixo Pinda | 382 |
| Nampula | Ilha de Mocambique | Quissanga | 365 |
| Inhambane | Inhassoro | Tsondzo | 324 |
| Nampula | Mogincual | Namige Sede | 308 |
| Inhambane | Inhassoro | Mucocuene | 305 |
| Inhambane | Massinga | Pomene | 277 |
| Nampula | Mogincual | Namalungo | 263 |
| Nampula | Nacala Porto | Mahelene | 244 |
| Inhambane | Inhassoro | Nhagondzo | 223 |
| Nampula | Memba | Serissa | 207 |
| Nampula | Nacala Porto | Quissimajulo | 197 |
| Inhambane | Inhassoro | Vuca | 195 |
| Maputo | Matutuíne | Santa Maria | 192 |
| Nampula | Memba | Simuco | 180 |
| Nampula | Memba | Memba-sede | 139 |
| Maputo | Matutuíne | Mabuluku | 125 |
| Sofala | Dondo | Sengo | 123 |
| Sofala | Dondo | Farol | 107 |
| Inhambane | Inhassoro | Petane | 99 |
| Inhambane | Inhassoro | Petane1 | 74 |
| Nampula | Mogincual | Meculuvelane | 22 |
| Nampula | Mogincual | Maculuvelane | 21 |
ggplot(community_totals,
aes(x = n_hhs, y = fct_reorder(g1_community, n_hhs))) +
geom_col(width = 0.7) +
scale_x_continuous(labels = comma) +
labs(
title = "HHS coverage by community / site",
x = "Number of HHS records",
y = "Community / site"
)
community_year_complete <- hhs %>%
count(g1_community, year, name = "n_hhs") %>%
complete(g1_community, year = sort(unique(hhs$year)), fill = list(n_hhs = 0))
ggplot(community_year_complete,
aes(x = factor(year), y = fct_reorder(g1_community, n_hhs, .fun = sum), fill = n_hhs)) +
geom_tile(color = "white") +
geom_text(aes(label = if_else(n_hhs == 0, "", as.character(n_hhs))), size = 2.7) +
scale_fill_gradient(low = "grey95", high = "grey25", labels = comma) +
labs(
title = "HHS coverage by community / site and year",
subtitle = "Blank cells indicate no HHS records in that site-year",
x = "Survey year",
y = "Community / site",
fill = "HHS records"
)
project_site_coverage <- hhs %>%
filter(is_project_site) %>%
count(project_site, district, program_maturity, year, name = "n_hhs") %>%
complete(project_site, year = sort(unique(hhs$year)), fill = list(n_hhs = 0)) %>%
group_by(project_site) %>%
fill(district, program_maturity, .direction = "downup") %>%
ungroup() %>%
arrange(district, project_site, year)
project_site_coverage %>%
kable(caption = "Project-site HHS records by year")
| project_site | year | district | program_maturity | n_hhs |
|---|---|---|---|---|
| Ilha Insular | 2019 | Ilha de Mocambique | Former/older Rare site | 327 |
| Ilha Insular | 2021 | Ilha de Mocambique | Former/older Rare site | 125 |
| Ilha Insular | 2023 | Ilha de Mocambique | Former/older Rare site | 106 |
| Ilha Insular | 2024 | Ilha de Mocambique | Former/older Rare site | 0 |
| Ilha Insular | 2025 | Ilha de Mocambique | Former/older Rare site | 566 |
| Ilha Insular | 2026 | Ilha de Mocambique | Former/older Rare site | 0 |
| Quissanga | 2019 | Ilha de Mocambique | Former/older Rare site | 0 |
| Quissanga | 2021 | Ilha de Mocambique | Former/older Rare site | 91 |
| Quissanga | 2023 | Ilha de Mocambique | Former/older Rare site | 103 |
| Quissanga | 2024 | Ilha de Mocambique | Former/older Rare site | 0 |
| Quissanga | 2025 | Ilha de Mocambique | Former/older Rare site | 171 |
| Quissanga | 2026 | Ilha de Mocambique | Former/older Rare site | 0 |
| Sanculo | 2019 | Ilha de Mocambique | Former/older Rare site | 0 |
| Sanculo | 2021 | Ilha de Mocambique | Former/older Rare site | 106 |
| Sanculo | 2023 | Ilha de Mocambique | Former/older Rare site | 104 |
| Sanculo | 2024 | Ilha de Mocambique | Former/older Rare site | 0 |
| Sanculo | 2025 | Ilha de Mocambique | Former/older Rare site | 220 |
| Sanculo | 2026 | Ilha de Mocambique | Former/older Rare site | 0 |
| Baixo Pinda | 2019 | Memba | Former/older Rare site | 1 |
| Baixo Pinda | 2021 | Memba | Former/older Rare site | 101 |
| Baixo Pinda | 2023 | Memba | Former/older Rare site | 0 |
| Baixo Pinda | 2024 | Memba | Former/older Rare site | 145 |
| Baixo Pinda | 2025 | Memba | Former/older Rare site | 0 |
| Baixo Pinda | 2026 | Memba | Former/older Rare site | 135 |
| Memba Sede | 2019 | Memba | Former/older Rare site | 206 |
| Memba Sede | 2021 | Memba | Former/older Rare site | 214 |
| Memba Sede | 2023 | Memba | Former/older Rare site | 0 |
| Memba Sede | 2024 | Memba | Former/older Rare site | 0 |
| Memba Sede | 2025 | Memba | Former/older Rare site | 0 |
| Memba Sede | 2026 | Memba | Former/older Rare site | 139 |
| Meculuvelane | 2019 | Mogincual | Newer expansion site | 0 |
| Meculuvelane | 2021 | Mogincual | Newer expansion site | 0 |
| Meculuvelane | 2023 | Mogincual | Newer expansion site | 0 |
| Meculuvelane | 2024 | Mogincual | Newer expansion site | 0 |
| Meculuvelane | 2025 | Mogincual | Newer expansion site | 22 |
| Meculuvelane | 2026 | Mogincual | Newer expansion site | 0 |
| Namalungo | 2019 | Mogincual | Newer expansion site | 0 |
| Namalungo | 2021 | Mogincual | Newer expansion site | 0 |
| Namalungo | 2023 | Mogincual | Newer expansion site | 0 |
| Namalungo | 2024 | Mogincual | Newer expansion site | 134 |
| Namalungo | 2025 | Mogincual | Newer expansion site | 129 |
| Namalungo | 2026 | Mogincual | Newer expansion site | 0 |
| Namige Sede | 2019 | Mogincual | Newer expansion site | 0 |
| Namige Sede | 2021 | Mogincual | Newer expansion site | 0 |
| Namige Sede | 2023 | Mogincual | Newer expansion site | 0 |
| Namige Sede | 2024 | Mogincual | Newer expansion site | 151 |
| Namige Sede | 2025 | Mogincual | Newer expansion site | 157 |
| Namige Sede | 2026 | Mogincual | Newer expansion site | 0 |
| Mahelene | 2019 | Nacala Porto | Newer expansion site | 0 |
| Mahelene | 2021 | Nacala Porto | Newer expansion site | 0 |
| Mahelene | 2023 | Nacala Porto | Newer expansion site | 0 |
| Mahelene | 2024 | Nacala Porto | Newer expansion site | 134 |
| Mahelene | 2025 | Nacala Porto | Newer expansion site | 0 |
| Mahelene | 2026 | Nacala Porto | Newer expansion site | 110 |
| Quissimajulo | 2019 | Nacala Porto | Newer expansion site | 0 |
| Quissimajulo | 2021 | Nacala Porto | Newer expansion site | 0 |
| Quissimajulo | 2023 | Nacala Porto | Newer expansion site | 0 |
| Quissimajulo | 2024 | Nacala Porto | Newer expansion site | 126 |
| Quissimajulo | 2025 | Nacala Porto | Newer expansion site | 0 |
| Quissimajulo | 2026 | Nacala Porto | Newer expansion site | 71 |
ggplot(project_site_coverage,
aes(x = factor(year), y = fct_reorder(project_site, n_hhs, .fun = sum), fill = n_hhs)) +
geom_tile(color = "white") +
geom_text(aes(label = if_else(n_hhs == 0, "", as.character(n_hhs))), size = 3) +
scale_fill_gradient(low = "grey95", high = "grey25", labels = comma) +
labs(
title = "Project-site HHS coverage by year",
subtitle = "This is the main sample-coverage check before comparing site-year scores",
x = "Survey year",
y = "Project site",
fill = "HHS records"
)
project_site_coverage_summary <- hhs %>%
filter(is_project_site) %>%
group_by(project_site, district, program_maturity) %>%
summarise(
n_hhs = n(),
years_covered = paste(sort(unique(year)), collapse = ", "),
n_years = n_distinct(year),
first_year = min(year),
last_year = max(year),
.groups = "drop"
) %>%
left_join(
program_context %>%
select(project_site, population_total, reached_individuals, fmp_status, site_specific_notes),
by = "project_site"
) %>%
arrange(district, project_site)
project_site_coverage_summary %>%
kable(caption = "Project-site coverage summary")
| project_site | district | program_maturity | n_hhs | years_covered | n_years | first_year | last_year | population_total | reached_individuals | fmp_status | site_specific_notes |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Ilha Insular | Ilha de Mocambique | Former/older Rare site | 1124 | 2019, 2021, 2023, 2025 | 4 | 2019 | 2025 | 9062 | 728 | FMP approved district/provincial; national review | Full behavior adoption campaign implemented in Ilha district |
| Quissanga | Ilha de Mocambique | Former/older Rare site | 365 | 2021, 2023, 2025 | 3 | 2021 | 2025 | 18553 | 775 | FMP approved district/provincial; national review | Aquaculture group reportedly resettled and reallocated to agriculture |
| Sanculo | Ilha de Mocambique | Former/older Rare site | 430 | 2021, 2023, 2025 | 3 | 2021 | 2025 | 38195 | 2022 | FMP approved district/provincial; national review | Aquaculture active in Sanculo; two tanks completed and one group started fish farming |
| Baixo Pinda | Memba | Former/older Rare site | 382 | 2019, 2021, 2024, 2026 | 4 | 2019 | 2026 | 7122 | 998 | FMP approved district/provincial; national review | CCP room completed but handover delayed by security; mangrove/seagrass restoration relevant |
| Memba Sede | Memba | Former/older Rare site | 559 | 2019, 2021, 2026 | 3 | 2019 | 2026 | 22572 | 2026 | FMP approved district/provincial; national review | Watch tower handed over; mangrove and seagrass restoration relevant; mid-term HHS delayed due to security |
| Meculuvelane | Mogincual | Newer expansion site | 22 | 2025 | 1 | 2025 | 2025 | 5117 | 856 | FMP under development / approval process | CCP room under construction; disaster-risk committees revitalized |
| Namalungo | Mogincual | Newer expansion site | 263 | 2024, 2025 | 2 | 2024 | 2025 | 5000 | 1793 | FMP under development / approval process | CCP room under construction; beekeeping kits replaced after protests/cyclone losses |
| Namige Sede | Mogincual | Newer expansion site | 308 | 2024, 2025 | 2 | 2024 | 2025 | 65890 | 1735 | FMP under development / approval process | Mangrove restoration and hydrological restoration relevant |
| Mahelene | Nacala Porto | Newer expansion site | 244 | 2024, 2026 | 2 | 2024 | 2026 | 4118 | 1832 | FMP under development / approval process | CCVA results validated; land/permits secured for CCP room; some cooperative governance concerns noted |
| Quissimajulo | Nacala Porto | Newer expansion site | 197 | 2024, 2026 | 2 | 2024 | 2026 | 9411 | 1892 | FMP under development / approval process | CCVA results validated with Quissimajulo and Mahelene; CCP room under construction |
low_sample_project_site_years <- project_site_coverage %>%
filter(n_hhs > 0, n_hhs < 30) %>%
arrange(n_hhs)
low_sample_project_site_years %>%
kable(caption = "Project-site-years with fewer than 30 HHS records")
| project_site | year | district | program_maturity | n_hhs |
|---|---|---|---|---|
| Baixo Pinda | 2019 | Memba | Former/older Rare site | 1 |
| Meculuvelane | 2025 | Mogincual | Newer expansion site | 22 |
The analysis focuses on two Impact Framework components that are relevant to the Composite Coastal Resilience Framework case study: Capacity for Collective Action and Sustainable Livelihoods.
Capacity for Collective Action reflects whether community members perceive that they are part of a fair, trusted, capable, and participatory local fisheries governance system. In the context of Fisheries OECMs, this component is important because durable conservation and fisheries-management outcomes depend not only on rules or management plans, but also on whether communities believe they can act collectively to manage resources.
The component is summarized using four indicators:
Social Equity in Fisheries Benefits: the share of fishery-dependent respondents who believe they benefit equally from the fishery as other members of the community.
Trust in Local Leadership: the share of respondents who trust local decision-makers or local authorities to make decisions that benefit the community over their own personal interests.
Collective Efficacy for Fisheries Management Score: the share of respondents who believe their community has the ability to manage the fishery effectively and maximize food and profits.
Empowerment & Participation in Management: the share of respondents who believe that local community participation in management will help maintain or improve fish catch.
Together, these indicators provide a practical measure of whether local social and governance conditions are supportive of collective fisheries management.
Sustainable Livelihoods reflects whether households have sufficient economic and food-security resilience to support long-term engagement in fisheries management and conservation. In the context of Fisheries OECMs, this component matters because households facing severe financial stress or food insecurity may have less capacity to comply with management rules, participate in governance, or invest in alternative livelihood strategies.
The component is summarized using two indicators:
Household can make ends meet: the share of respondents who report that their household can cover its needs fairly easily, easily, or very easily.
Food security: the share of respondents who report that they never worried about not having enough food for everyone in the household during the last 12 months.
For interpretation, the analysis also presents diagnostic negative indicators for financial strain and food worry. These are useful for communicating the livelihood vulnerability behind the Sustainable Livelihoods score.
agree_values <- c("Agree", "Strongly agree")
hhs_if <- hhs %>%
mutate(
# Capacity for Collective Action
social_equity = case_when(
g8_fishery_benefit_equal == "Yes" ~ 1,
g8_fishery_benefit_equal == "No" ~ 0,
g8_fishery_benefit_equal == "I don’t depend on or benefit from the fishery" ~ NA_real_,
TRUE ~ NA_real_
),
social_equity_sensitivity_nonbenefit_0 = case_when(
g8_fishery_benefit_equal == "Yes" ~ 1,
g8_fishery_benefit_equal %in% c("No", "I don’t depend on or benefit from the fishery") ~ 0,
TRUE ~ NA_real_
),
leadership_trust_local = case_when(
g8_trust_local_decision %in% agree_values ~ 1,
!is.na(g8_trust_local_decision) ~ 0,
TRUE ~ NA_real_
),
collective_efficacy = case_when(
g8_my_community_ability %in% agree_values ~ 1,
!is.na(g8_my_community_ability) ~ 0,
TRUE ~ NA_real_
),
empowerment_participation = case_when(
g12_agreement_community_participation %in% agree_values ~ 1,
!is.na(g12_agreement_community_participation) ~ 0,
TRUE ~ NA_real_
),
# Sustainable Livelihoods
ends_meet_positive = case_when(
g13_hh_ends_meet %in% c("Fairly easy", "Easy", "Very easy") ~ 1,
!is.na(g13_hh_ends_meet) ~ 0,
TRUE ~ NA_real_
),
food_security_positive = case_when(
g11_food_worry == "Never" ~ 1,
g11_food_worry %in% c("Sometimes", "Often") ~ 0,
TRUE ~ NA_real_
),
# Diagnostic negative indicators
financial_strain = case_when(
g13_hh_ends_meet %in% c("With difficulty", "With great difficulty") ~ 1,
g13_hh_ends_meet %in% c("Fairly easy", "Easy", "Very easy") ~ 0,
TRUE ~ NA_real_
),
food_worry_any = case_when(
g11_food_worry %in% c("Sometimes", "Often") ~ 1,
g11_food_worry == "Never" ~ 0,
TRUE ~ NA_real_
),
food_worry_often = case_when(
g11_food_worry == "Often" ~ 1,
g11_food_worry %in% c("Sometimes", "Never") ~ 0,
TRUE ~ NA_real_
)
)
# Indicator metadata
core_indicator_vars <- c(
"social_equity",
"leadership_trust_local",
"collective_efficacy",
"empowerment_participation",
"ends_meet_positive",
"food_security_positive"
)
diagnostic_indicator_vars <- c(
"financial_strain",
"food_worry_any",
"food_worry_often"
)
indicator_vars <- c(core_indicator_vars, diagnostic_indicator_vars)
indicator_meta <- tribble(
~indicator, ~domain, ~label, ~direction,
"social_equity", "Capacity for Collective Action", "Social Equity in Fisheries Benefits", "positive_core",
"leadership_trust_local", "Capacity for Collective Action", "Trust in Local Leadership", "positive_core",
"collective_efficacy", "Capacity for Collective Action", "Collective Efficacy for Fisheries Management Score", "positive_core",
"empowerment_participation", "Capacity for Collective Action", "Empowerment & Participation in Management", "positive_core",
"ends_meet_positive", "Sustainable Livelihoods", "Household covers needs", "positive_core",
"food_security_positive", "Sustainable Livelihoods", "Never worried about enough food", "positive_core",
"financial_strain", "Sustainable Livelihoods", "Household covers needs with difficulty", "diagnostic_negative",
"food_worry_any", "Sustainable Livelihoods", "Sometimes/often worried about food", "diagnostic_negative",
"food_worry_often", "Sustainable Livelihoods", "Often worried about food", "diagnostic_negative"
)
Domain scores are calculated as the simple average of the positive indicator percentages within each domain. This means each indicator receives equal weight within its domain.
Error bars in the score plots show approximate 95% confidence intervals. For single indicators, the intervals are calculated from the respondent-level variation in the binary indicator. For composite domain scores, the intervals are approximated from the component-indicator standard errors under the same equal-weighting logic. Treat these as descriptive uncertainty intervals rather than formal causal inference intervals.
pct_percent <- function(x) {
mean_na(x) * 100
}
se_percent <- function(x) {
n_valid <- sum(!is.na(x))
if (n_valid <= 1) {
return(NA_real_)
}
sd(x, na.rm = TRUE) / sqrt(n_valid) * 100
}
ci_low_percent <- function(x) {
pct <- pct_percent(x)
se <- se_percent(x)
if (is.na(pct) || is.na(se)) {
return(NA_real_)
}
pmax(0, pct - 1.96 * se)
}
ci_high_percent <- function(x) {
pct <- pct_percent(x)
se <- se_percent(x)
if (is.na(pct) || is.na(se)) {
return(NA_real_)
}
pmin(100, pct + 1.96 * se)
}
summarise_indicators <- function(data, group_vars) {
data %>%
group_by(across(all_of(group_vars))) %>%
summarise(
n_hhs = n(),
median_income = median_na(g13_hh_average_income),
income_p25 = p25_na(g13_hh_average_income),
income_p75 = p75_na(g13_hh_average_income),
across(
all_of(indicator_vars),
list(
n_valid = ~sum(!is.na(.x)),
pct = ~pct_percent(.x),
se = ~se_percent(.x),
ci_low = ~ci_low_percent(.x),
ci_high = ~ci_high_percent(.x)
),
.names = "{.col}__{.fn}"
),
.groups = "drop"
) %>%
pivot_longer(
cols = matches("__"),
names_to = c("indicator", ".value"),
names_sep = "__"
) %>%
left_join(indicator_meta, by = "indicator")
}
make_domain_scores <- function(indicator_summary, group_vars) {
indicator_summary %>%
filter(direction == "positive_core") %>%
group_by(across(all_of(group_vars)), domain) %>%
summarise(
n_hhs = first(n_hhs),
domain_score = mean_na(pct),
domain_se = {
n_indicators <- sum(!is.na(pct))
se_vals <- se[!is.na(se)]
if (n_indicators == 0 || length(se_vals) == 0) {
NA_real_
} else {
sqrt(sum(se_vals^2)) / n_indicators
}
},
ci_low = pmax(0, domain_score - 1.96 * domain_se),
ci_high = pmin(100, domain_score + 1.96 * domain_se),
n_indicators_available = sum(!is.na(pct)),
min_n_valid = min(n_valid, na.rm = TRUE),
.groups = "drop"
) %>%
mutate(
min_n_valid = if_else(is.infinite(min_n_valid), NA_real_, as.numeric(min_n_valid))
)
}
impact_vars_raw <- c(
"g8_fishery_benefit_equal",
"g8_trust_local_decision",
"g8_my_community_ability",
"g12_agreement_community_participation",
"g11_food_worry",
"g13_hh_ends_meet",
"g13_hh_average_income"
)
missingness <- hhs_if %>%
summarise(across(
all_of(impact_vars_raw),
list(
n_missing = ~sum(is.na(.x)),
pct_missing = ~mean(is.na(.x)) * 100
),
.names = "{.col}__{.fn}"
)) %>%
pivot_longer(
everything(),
names_to = c("variable", ".value"),
names_sep = "__"
) %>%
arrange(desc(pct_missing))
missingness %>%
mutate(pct_missing = round(pct_missing, 1)) %>%
kable(caption = "Missingness in selected Impact Framework variables")
| variable | n_missing | pct_missing |
|---|---|---|
| g12_agreement_community_participation | 3004 | 41.2 |
| g13_hh_average_income | 420 | 5.8 |
| g13_hh_ends_meet | 124 | 1.7 |
| g8_my_community_ability | 100 | 1.4 |
| g11_food_worry | 91 | 1.2 |
| g8_fishery_benefit_equal | 90 | 1.2 |
| g8_trust_local_decision | 35 | 0.5 |
ggplot(missingness,
aes(x = pct_missing, y = fct_reorder(variable, pct_missing))) +
geom_col(width = 0.7) +
scale_x_continuous(labels = label_percent(scale = 1), limits = c(0, 100)) +
labs(
title = "Missingness in selected Impact Framework variables",
x = "Missing responses",
y = NULL
)
This section uses the complete Mozambique HHS dataset, not only project sites.
overall_indicators <- hhs_if %>%
mutate(analysis_group = "All Mozambique HHS") %>%
summarise_indicators(group_vars = "analysis_group")
overall_indicators %>%
select(domain, label, direction, n_hhs, n_valid, pct, se, ci_low, ci_high) %>%
mutate(across(c(pct, se, ci_low, ci_high), ~round(.x, 1))) %>%
arrange(domain, direction, desc(pct)) %>%
kable(caption = "Overall indicator scores in the complete Mozambique HHS")
| domain | label | direction | n_hhs | n_valid | pct | se | ci_low | ci_high |
|---|---|---|---|---|---|---|---|---|
| Capacity for Collective Action | Empowerment & Participation in Management | positive_core | 7297 | 4293 | 88.4 | 0.5 | 87.4 | 89.3 |
| Capacity for Collective Action | Social Equity in Fisheries Benefits | positive_core | 7297 | 6811 | 83.4 | 0.5 | 82.6 | 84.3 |
| Capacity for Collective Action | Trust in Local Leadership | positive_core | 7297 | 7262 | 80.6 | 0.5 | 79.6 | 81.5 |
| Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | positive_core | 7297 | 7197 | 71.3 | 0.5 | 70.2 | 72.3 |
| Sustainable Livelihoods | Sometimes/often worried about food | diagnostic_negative | 7297 | 7206 | 88.3 | 0.4 | 87.5 | 89.0 |
| Sustainable Livelihoods | Household covers needs with difficulty | diagnostic_negative | 7297 | 7173 | 73.5 | 0.5 | 72.4 | 74.5 |
| Sustainable Livelihoods | Often worried about food | diagnostic_negative | 7297 | 7206 | 22.0 | 0.5 | 21.0 | 22.9 |
| Sustainable Livelihoods | Household covers needs | positive_core | 7297 | 7173 | 26.5 | 0.5 | 25.5 | 27.6 |
| Sustainable Livelihoods | Never worried about enough food | positive_core | 7297 | 7206 | 11.7 | 0.4 | 11.0 | 12.5 |
overall_indicators %>%
filter(direction == "positive_core") %>%
ggplot(aes(x = fct_reorder(label, pct), y = pct)) +
geom_col(width = 0.7) +
geom_errorbar(aes(ymin = ci_low, ymax = ci_high), width = 0.18) +
coord_flip() +
facet_wrap(~ domain, scales = "free_y") +
scale_y_continuous(limits = c(0, 100), labels = label_percent(scale = 1)) +
labs(
title = "Overall positive indicator scores in the complete Mozambique HHS",
subtitle = "Percent of valid responses coded as positive; error bars show approximate 95% CIs",
x = NULL,
y = "% positive"
)
overall_domains <- overall_indicators %>%
make_domain_scores(group_vars = "analysis_group")
overall_domains %>%
mutate(across(c(domain_score, domain_se, ci_low, ci_high), ~round(.x, 1))) %>%
kable(caption = "Overall CCRF domain scores in the complete Mozambique HHS")
| analysis_group | domain | n_hhs | domain_score | domain_se | ci_low | ci_high | n_indicators_available | min_n_valid |
|---|---|---|---|---|---|---|---|---|
| All Mozambique HHS | Capacity for Collective Action | 7297 | 80.9 | 0.2 | 80.4 | 81.4 | 4 | 4293 |
| All Mozambique HHS | Sustainable Livelihoods | 7297 | 19.1 | 0.3 | 18.5 | 19.8 | 2 | 7173 |
ggplot(overall_domains, aes(x = fct_reorder(domain, domain_score), y = domain_score)) +
geom_col(width = 0.65) +
geom_errorbar(aes(ymin = ci_low, ymax = ci_high), width = 0.16) +
geom_text(aes(label = round(domain_score, 1)), vjust = -0.7, size = 4) +
scale_y_continuous(limits = c(0, 100)) +
labs(
title = "Overall CCRF diagnostic scores in the complete Mozambique HHS",
subtitle = "Error bars show approximate 95% CIs",
x = NULL,
y = "Mean domain score, 0–100"
)
year_indicators <- hhs_if %>%
summarise_indicators(group_vars = "year")
year_domains <- year_indicators %>%
make_domain_scores(group_vars = "year")
year_domains %>%
mutate(across(c(domain_score, domain_se, ci_low, ci_high), ~round(.x, 1))) %>%
arrange(year, domain) %>%
kable(caption = "Domain scores by year, complete Mozambique HHS")
| year | domain | n_hhs | domain_score | domain_se | ci_low | ci_high | n_indicators_available | min_n_valid |
|---|---|---|---|---|---|---|---|---|
| 2019 | Capacity for Collective Action | 1460 | 81.6 | 0.6 | 80.5 | 82.7 | 4 | 757 |
| 2019 | Sustainable Livelihoods | 1460 | 26.2 | 0.8 | 24.6 | 27.8 | 2 | 1400 |
| 2021 | Capacity for Collective Action | 2493 | 85.6 | 0.4 | 84.8 | 86.3 | 4 | 1181 |
| 2021 | Sustainable Livelihoods | 2493 | 19.4 | 0.6 | 18.3 | 20.5 | 2 | 2425 |
| 2023 | Capacity for Collective Action | 313 | 95.8 | 0.6 | 94.7 | 96.9 | 4 | 261 |
| 2023 | Sustainable Livelihoods | 313 | 9.6 | 1.1 | 7.4 | 11.8 | 2 | 313 |
| 2024 | Capacity for Collective Action | 711 | 86.6 | 0.6 | 85.4 | 87.8 | 4 | 548 |
| 2024 | Sustainable Livelihoods | 711 | 21.7 | 1.1 | 19.6 | 23.9 | 2 | 711 |
| 2025 | Capacity for Collective Action | 1865 | 73.8 | 0.5 | 72.8 | 74.9 | 4 | 1250 |
| 2025 | Sustainable Livelihoods | 1865 | 13.4 | 0.5 | 12.4 | 14.5 | 2 | 1865 |
| 2026 | Capacity for Collective Action | 455 | 62.0 | 1.1 | 59.8 | 64.2 | 4 | 296 |
| 2026 | Sustainable Livelihoods | 455 | 21.9 | 1.3 | 19.4 | 24.4 | 2 | 455 |
ggplot(year_domains,
aes(x = year, y = domain_score, group = domain, linetype = domain)) +
geom_errorbar(aes(ymin = ci_low, ymax = ci_high), width = 0.12, alpha = 0.7) +
geom_line(linewidth = 0.8) +
geom_point(size = 2.4) +
scale_y_continuous(limits = c(0, 100), breaks = seq(0, 100, 25)) +
scale_x_continuous(breaks = sort(unique(year_domains$year))) +
labs(
title = "CCRF domain scores by year: complete Mozambique HHS",
subtitle = "Use cautiously: site composition varies across years; error bars show approximate 95% CIs",
x = "Survey year",
y = "Mean domain score, 0–100",
linetype = "Domain"
) +
theme(legend.position = "bottom")
year_indicators %>%
filter(direction == "positive_core") %>%
mutate(across(c(pct, se, ci_low, ci_high), ~round(.x, 1))) %>%
select(year, domain, label, n_hhs, n_valid, pct, se, ci_low, ci_high) %>%
arrange(year, domain, label) %>%
kable(caption = "Positive indicator scores by year, complete Mozambique HHS")
| year | domain | label | n_hhs | n_valid | pct | se | ci_low | ci_high |
|---|---|---|---|---|---|---|---|---|
| 2019 | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 1460 | 1389 | 77.9 | 1.1 | 75.7 | 80.1 |
| 2019 | Capacity for Collective Action | Empowerment & Participation in Management | 1460 | 757 | 89.0 | 1.1 | 86.8 | 91.3 |
| 2019 | Capacity for Collective Action | Social Equity in Fisheries Benefits | 1460 | 1203 | 78.2 | 1.2 | 75.9 | 80.6 |
| 2019 | Capacity for Collective Action | Trust in Local Leadership | 1460 | 1440 | 81.3 | 1.0 | 79.3 | 83.3 |
| 2019 | Sustainable Livelihoods | Household covers needs | 1460 | 1404 | 33.8 | 1.3 | 31.4 | 36.3 |
| 2019 | Sustainable Livelihoods | Never worried about enough food | 1460 | 1400 | 18.6 | 1.0 | 16.6 | 20.7 |
| 2021 | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 2493 | 2464 | 81.2 | 0.8 | 79.7 | 82.8 |
| 2021 | Capacity for Collective Action | Empowerment & Participation in Management | 2493 | 1181 | 88.7 | 0.9 | 86.8 | 90.5 |
| 2021 | Capacity for Collective Action | Social Equity in Fisheries Benefits | 2493 | 2366 | 87.9 | 0.7 | 86.6 | 89.2 |
| 2021 | Capacity for Collective Action | Trust in Local Leadership | 2493 | 2478 | 84.5 | 0.7 | 83.1 | 86.0 |
| 2021 | Sustainable Livelihoods | Household covers needs | 2493 | 2425 | 25.6 | 0.9 | 23.9 | 27.4 |
| 2021 | Sustainable Livelihoods | Never worried about enough food | 2493 | 2462 | 13.1 | 0.7 | 11.7 | 14.4 |
| 2023 | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 313 | 313 | 90.1 | 1.7 | 86.8 | 93.4 |
| 2023 | Capacity for Collective Action | Empowerment & Participation in Management | 313 | 261 | 98.5 | 0.8 | 97.0 | 100.0 |
| 2023 | Capacity for Collective Action | Social Equity in Fisheries Benefits | 313 | 312 | 98.7 | 0.6 | 97.5 | 100.0 |
| 2023 | Capacity for Collective Action | Trust in Local Leadership | 313 | 313 | 95.8 | 1.1 | 93.6 | 98.1 |
| 2023 | Sustainable Livelihoods | Household covers needs | 313 | 313 | 19.2 | 2.2 | 14.8 | 23.5 |
| 2023 | Sustainable Livelihoods | Never worried about enough food | 313 | 313 | 0.0 | 0.0 | 0.0 | 0.0 |
| 2024 | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 711 | 711 | 72.2 | 1.7 | 68.9 | 75.4 |
| 2024 | Capacity for Collective Action | Empowerment & Participation in Management | 711 | 548 | 97.3 | 0.7 | 95.9 | 98.6 |
| 2024 | Capacity for Collective Action | Social Equity in Fisheries Benefits | 711 | 711 | 88.3 | 1.2 | 86.0 | 90.7 |
| 2024 | Capacity for Collective Action | Trust in Local Leadership | 711 | 711 | 88.6 | 1.2 | 86.3 | 90.9 |
| 2024 | Sustainable Livelihoods | Household covers needs | 711 | 711 | 20.1 | 1.5 | 17.2 | 23.1 |
| 2024 | Sustainable Livelihoods | Never worried about enough food | 711 | 711 | 23.3 | 1.6 | 20.2 | 26.5 |
| 2025 | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 1865 | 1865 | 54.7 | 1.2 | 52.4 | 57.0 |
| 2025 | Capacity for Collective Action | Empowerment & Participation in Management | 1865 | 1250 | 81.1 | 1.1 | 78.9 | 83.3 |
| 2025 | Capacity for Collective Action | Social Equity in Fisheries Benefits | 1865 | 1790 | 82.7 | 0.9 | 81.0 | 84.5 |
| 2025 | Capacity for Collective Action | Trust in Local Leadership | 1865 | 1865 | 76.8 | 1.0 | 74.9 | 78.7 |
| 2025 | Sustainable Livelihoods | Household covers needs | 1865 | 1865 | 23.4 | 1.0 | 21.5 | 25.3 |
| 2025 | Sustainable Livelihoods | Never worried about enough food | 1865 | 1865 | 3.5 | 0.4 | 2.7 | 4.3 |
| 2026 | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 455 | 455 | 51.2 | 2.3 | 46.6 | 55.8 |
| 2026 | Capacity for Collective Action | Empowerment & Participation in Management | 455 | 296 | 90.9 | 1.7 | 87.6 | 94.2 |
| 2026 | Capacity for Collective Action | Social Equity in Fisheries Benefits | 455 | 429 | 57.1 | 2.4 | 52.4 | 61.8 |
| 2026 | Capacity for Collective Action | Trust in Local Leadership | 455 | 455 | 48.8 | 2.3 | 44.2 | 53.4 |
| 2026 | Sustainable Livelihoods | Household covers needs | 455 | 455 | 36.7 | 2.3 | 32.3 | 41.1 |
| 2026 | Sustainable Livelihoods | Never worried about enough food | 455 | 455 | 7.0 | 1.2 | 4.7 | 9.4 |
ggplot(
year_indicators %>% filter(direction == "positive_core"),
aes(
x = year,
y = pct,
group = label,
color = label
)
) +
geom_errorbar(
aes(ymin = ci_low, ymax = ci_high),
width = 0.10,
alpha = 0.45,
linewidth = 0.5
) +
geom_line(linewidth = 0.8) +
geom_point(size = 2) +
facet_wrap(~ domain, ncol = 1) +
scale_y_continuous(
limits = c(0, 100),
labels = scales::label_percent(scale = 1)
) +
scale_x_continuous(
breaks = sort(unique(year_indicators$year))
) +
scale_color_brewer(palette = "Dark2") +
labs(
title = "Positive indicator scores by year: complete Mozambique HHS",
subtitle = "Each line is one Impact Framework indicator; error bars show approximate 95% CIs",
x = "Survey year",
y = "% positive",
color = "Indicator"
) +
theme_minimal(base_size = 12) +
theme(
legend.position = "bottom",
legend.title = element_text(size = 11),
legend.text = element_text(size = 10),
strip.text = element_text(face = "bold")
)
site_indicators <- hhs_if %>%
summarise_indicators(group_vars = c("site_name", "g1_municipality", "g1_province"))
site_domains <- site_indicators %>%
make_domain_scores(group_vars = c("site_name", "g1_municipality", "g1_province"))
site_domains %>%
mutate(across(c(domain_score, domain_se, ci_low, ci_high), ~round(.x, 1))) %>%
arrange(domain, domain_score) %>%
kable(caption = "Domain scores by site, complete Mozambique HHS")
| site_name | g1_municipality | g1_province | domain | n_hhs | domain_score | domain_se | ci_low | ci_high | n_indicators_available | min_n_valid |
|---|---|---|---|---|---|---|---|---|---|---|
| Quissanga | Ilha de Mocambique | Nampula | Capacity for Collective Action | 365 | 66.9 | 1.2 | 64.6 | 69.2 | 4 | 324 |
| Baixo Pinda | Memba | Nampula | Capacity for Collective Action | 382 | 68.6 | 1.2 | 66.3 | 70.9 | 4 | 350 |
| Memba-sede | Memba | Nampula | Capacity for Collective Action | 139 | 70.0 | 1.8 | 66.5 | 73.4 | 4 | 88 |
| Petane | Inhassoro | Inhambane | Capacity for Collective Action | 99 | 70.0 | 2.3 | 65.5 | 74.5 | 4 | 33 |
| Namalungo | Mogincual | Nampula | Capacity for Collective Action | 263 | 71.6 | 1.1 | 69.3 | 73.8 | 4 | 239 |
| Petane1 | Inhassoro | Inhambane | Capacity for Collective Action | 74 | 71.7 | 3.1 | 65.7 | 77.7 | 4 | 21 |
| Vuca | Inhassoro | Inhambane | Capacity for Collective Action | 195 | 76.4 | 1.6 | 73.3 | 79.5 | 4 | 88 |
| Quissimajulo | Nacala Porto | Nampula | Capacity for Collective Action | 197 | 76.6 | 1.5 | 73.6 | 79.6 | 4 | 117 |
| Fequete | Inhassoro | Inhambane | Capacity for Collective Action | 500 | 78.0 | 1.0 | 76.1 | 80.0 | 4 | 198 |
| Mahelene | Nacala Porto | Nampula | Capacity for Collective Action | 244 | 79.4 | 1.3 | 76.8 | 82.0 | 4 | 163 |
| Simuco | Memba | Nampula | Capacity for Collective Action | 180 | 79.5 | 1.5 | 76.6 | 82.4 | 4 | 11 |
| Memba | Memba | Nampula | Capacity for Collective Action | 420 | 79.7 | 1.2 | 77.4 | 82.0 | 4 | 170 |
| Maculuvelane | Mogincual | Nampula | Capacity for Collective Action | 21 | 81.0 | 2.8 | 75.5 | 86.4 | 4 | 21 |
| Ilha Insular | Ilha de Mocambique | Nampula | Capacity for Collective Action | 1124 | 81.3 | 0.6 | 80.1 | 82.4 | 4 | 572 |
| Pomene | Massinga | Inhambane | Capacity for Collective Action | 277 | 83.0 | 1.2 | 80.7 | 85.4 | 4 | 155 |
| Nhagondzo | Inhassoro | Inhambane | Capacity for Collective Action | 223 | 84.2 | 1.2 | 81.8 | 86.6 | 4 | 152 |
| Mucocuene | Inhassoro | Inhambane | Capacity for Collective Action | 305 | 85.1 | 1.1 | 83.1 | 87.2 | 4 | 118 |
| Santa Maria | Matutuíne | Maputo | Capacity for Collective Action | 192 | 87.3 | 1.2 | 84.9 | 89.6 | 4 | 167 |
| Serissa | Memba | Nampula | Capacity for Collective Action | 207 | 87.7 | 1.3 | 85.1 | 90.3 | 4 | 68 |
| Tsondzo | Inhassoro | Inhambane | Capacity for Collective Action | 324 | 88.1 | 1.0 | 86.3 | 90.0 | 4 | 174 |
| Namige Sede | Mogincual | Nampula | Capacity for Collective Action | 308 | 88.3 | 1.0 | 86.4 | 90.2 | 4 | 195 |
| Mabuluku | Matutuíne | Maputo | Capacity for Collective Action | 125 | 88.5 | 1.4 | 85.7 | 91.3 | 4 | 115 |
| Sanculo | Ilha de Mocambique | Nampula | Capacity for Collective Action | 430 | 89.2 | 0.7 | 87.8 | 90.7 | 4 | 395 |
| Zavora | Inharrime | Inhambane | Capacity for Collective Action | 451 | 90.1 | 0.7 | 88.7 | 91.4 | 4 | 205 |
| Meculuvelane | Mogincual | Nampula | Capacity for Collective Action | 22 | 90.9 | 2.9 | 85.2 | 96.6 | 4 | 22 |
| Farol | Dondo | Sofala | Capacity for Collective Action | 107 | 91.7 | 1.3 | 89.1 | 94.2 | 4 | 79 |
| Sengo | Dondo | Sofala | Capacity for Collective Action | 123 | 95.1 | 1.1 | 92.9 | 97.3 | 4 | 53 |
| Maculuvelane | Mogincual | Nampula | Sustainable Livelihoods | 21 | 0.0 | 0.0 | 0.0 | 0.0 | 2 | 21 |
| Baixo Pinda | Memba | Nampula | Sustainable Livelihoods | 382 | 2.5 | 0.6 | 1.4 | 3.6 | 2 | 380 |
| Farol | Dondo | Sofala | Sustainable Livelihoods | 107 | 3.3 | 1.2 | 0.9 | 5.7 | 2 | 105 |
| Sanculo | Ilha de Mocambique | Nampula | Sustainable Livelihoods | 430 | 4.8 | 0.7 | 3.4 | 6.3 | 2 | 424 |
| Serissa | Memba | Nampula | Sustainable Livelihoods | 207 | 7.0 | 1.3 | 4.6 | 9.5 | 2 | 199 |
| Petane1 | Inhassoro | Inhambane | Sustainable Livelihoods | 74 | 8.8 | 2.3 | 4.3 | 13.3 | 2 | 72 |
| Sengo | Dondo | Sofala | Sustainable Livelihoods | 123 | 8.9 | 1.9 | 5.2 | 12.5 | 2 | 107 |
| Mucocuene | Inhassoro | Inhambane | Sustainable Livelihoods | 305 | 9.5 | 1.2 | 7.2 | 11.9 | 2 | 304 |
| Tsondzo | Inhassoro | Inhambane | Sustainable Livelihoods | 324 | 10.5 | 1.2 | 8.1 | 12.8 | 2 | 320 |
| Quissanga | Ilha de Mocambique | Nampula | Sustainable Livelihoods | 365 | 11.0 | 1.1 | 8.8 | 13.2 | 2 | 363 |
| Petane | Inhassoro | Inhambane | Sustainable Livelihoods | 99 | 11.1 | 2.2 | 6.8 | 15.4 | 2 | 99 |
| Nhagondzo | Inhassoro | Inhambane | Sustainable Livelihoods | 223 | 12.5 | 1.6 | 9.5 | 15.6 | 2 | 219 |
| Namalungo | Mogincual | Nampula | Sustainable Livelihoods | 263 | 13.3 | 1.4 | 10.6 | 16.0 | 2 | 263 |
| Ilha Insular | Ilha de Mocambique | Nampula | Sustainable Livelihoods | 1124 | 15.3 | 0.7 | 13.9 | 16.7 | 2 | 1121 |
| Fequete | Inhassoro | Inhambane | Sustainable Livelihoods | 500 | 16.7 | 1.1 | 14.5 | 19.0 | 2 | 492 |
| Memba-sede | Memba | Nampula | Sustainable Livelihoods | 139 | 19.8 | 2.2 | 15.5 | 24.1 | 2 | 139 |
| Meculuvelane | Mogincual | Nampula | Sustainable Livelihoods | 22 | 20.5 | 5.4 | 9.9 | 31.0 | 2 | 22 |
| Vuca | Inhassoro | Inhambane | Sustainable Livelihoods | 195 | 22.9 | 2.1 | 18.8 | 27.0 | 2 | 194 |
| Simuco | Memba | Nampula | Sustainable Livelihoods | 180 | 24.4 | 2.3 | 19.9 | 28.8 | 2 | 176 |
| Mahelene | Nacala Porto | Nampula | Sustainable Livelihoods | 244 | 25.4 | 1.9 | 21.7 | 29.1 | 2 | 244 |
| Quissimajulo | Nacala Porto | Nampula | Sustainable Livelihoods | 197 | 26.4 | 2.2 | 22.1 | 30.7 | 2 | 197 |
| Pomene | Massinga | Inhambane | Sustainable Livelihoods | 277 | 29.5 | 1.9 | 25.8 | 33.3 | 2 | 270 |
| Zavora | Inharrime | Inhambane | Sustainable Livelihoods | 451 | 32.3 | 1.6 | 29.2 | 35.3 | 2 | 410 |
| Memba | Memba | Nampula | Sustainable Livelihoods | 420 | 37.6 | 1.7 | 34.3 | 40.9 | 2 | 408 |
| Mabuluku | Matutuíne | Maputo | Sustainable Livelihoods | 125 | 42.7 | 3.2 | 36.5 | 49.0 | 2 | 119 |
| Namige Sede | Mogincual | Nampula | Sustainable Livelihoods | 308 | 42.9 | 2.0 | 39.0 | 46.7 | 2 | 308 |
| Santa Maria | Matutuíne | Maputo | Sustainable Livelihoods | 192 | 51.3 | 2.6 | 46.2 | 56.5 | 2 | 183 |
ggplot(site_domains,
aes(x = fct_reorder(site_name, domain_score), y = domain_score)) +
geom_col(width = 0.7) +
geom_errorbar(aes(ymin = ci_low, ymax = ci_high), width = 0.18) +
coord_flip() +
facet_wrap(~ domain, scales = "free_y") +
scale_y_continuous(limits = c(0, 100), breaks = seq(0, 100, 25)) +
labs(
title = "CCRF domain scores by site: complete Mozambique HHS",
subtitle = "Error bars show approximate 95% CIs",
x = "Site / community",
y = "Mean domain score, 0–100"
)
site_domain_wide <- site_domains %>%
select(site_name, g1_municipality, g1_province, n_hhs, domain, domain_score) %>%
pivot_wider(names_from = domain, values_from = domain_score) %>%
mutate(
domain_gap_collective_action_minus_livelihoods =
`Capacity for Collective Action` - `Sustainable Livelihoods`
) %>%
arrange(desc(domain_gap_collective_action_minus_livelihoods))
site_domain_wide %>%
mutate(across(where(is.numeric), ~round(.x, 1))) %>%
kable(caption = "Site-level gap between collective action and sustainable livelihoods")
| site_name | g1_municipality | g1_province | n_hhs | Capacity for Collective Action | Sustainable Livelihoods | domain_gap_collective_action_minus_livelihoods |
|---|---|---|---|---|---|---|
| Farol | Dondo | Sofala | 107 | 91.7 | 3.3 | 88.4 |
| Sengo | Dondo | Sofala | 123 | 95.1 | 8.9 | 86.2 |
| Sanculo | Ilha de Mocambique | Nampula | 430 | 89.2 | 4.8 | 84.4 |
| Maculuvelane | Mogincual | Nampula | 21 | 81.0 | 0.0 | 81.0 |
| Serissa | Memba | Nampula | 207 | 87.7 | 7.0 | 80.6 |
| Tsondzo | Inhassoro | Inhambane | 324 | 88.1 | 10.5 | 77.7 |
| Mucocuene | Inhassoro | Inhambane | 305 | 85.1 | 9.5 | 75.6 |
| Nhagondzo | Inhassoro | Inhambane | 223 | 84.2 | 12.5 | 71.7 |
| Meculuvelane | Mogincual | Nampula | 22 | 90.9 | 20.5 | 70.5 |
| Baixo Pinda | Memba | Nampula | 382 | 68.6 | 2.5 | 66.1 |
| Ilha Insular | Ilha de Mocambique | Nampula | 1124 | 81.3 | 15.3 | 66.0 |
| Petane1 | Inhassoro | Inhambane | 74 | 71.7 | 8.8 | 62.9 |
| Fequete | Inhassoro | Inhambane | 500 | 78.0 | 16.7 | 61.3 |
| Petane | Inhassoro | Inhambane | 99 | 70.0 | 11.1 | 58.9 |
| Namalungo | Mogincual | Nampula | 263 | 71.6 | 13.3 | 58.3 |
| Zavora | Inharrime | Inhambane | 451 | 90.1 | 32.3 | 57.8 |
| Quissanga | Ilha de Mocambique | Nampula | 365 | 66.9 | 11.0 | 55.9 |
| Simuco | Memba | Nampula | 180 | 79.5 | 24.4 | 55.1 |
| Mahelene | Nacala Porto | Nampula | 244 | 79.4 | 25.4 | 54.0 |
| Pomene | Massinga | Inhambane | 277 | 83.0 | 29.5 | 53.5 |
| Vuca | Inhassoro | Inhambane | 195 | 76.4 | 22.9 | 53.5 |
| Quissimajulo | Nacala Porto | Nampula | 197 | 76.6 | 26.4 | 50.2 |
| Memba-sede | Memba | Nampula | 139 | 70.0 | 19.8 | 50.2 |
| Mabuluku | Matutuíne | Maputo | 125 | 88.5 | 42.7 | 45.8 |
| Namige Sede | Mogincual | Nampula | 308 | 88.3 | 42.9 | 45.5 |
| Memba | Memba | Nampula | 420 | 79.7 | 37.6 | 42.1 |
| Santa Maria | Matutuíne | Maputo | 192 | 87.3 | 51.3 | 35.9 |
ggplot(site_domain_wide,
aes(x = domain_gap_collective_action_minus_livelihoods,
y = fct_reorder(site_name, domain_gap_collective_action_minus_livelihoods))) +
geom_col(width = 0.7) +
labs(
title = "Diagnostic gap by site",
subtitle = "Positive values mean Capacity for Collective Action scores higher than Sustainable Livelihoods",
x = "Capacity for Collective Action minus Sustainable Livelihoods",
y = "Site / community"
)
This is the broadest site-year view. It includes all Mozambique HHS sites, not only BAF / Rare project sites. Use this mainly as a coverage and pattern-exploration plot.
site_year_indicators <- hhs_if %>%
summarise_indicators(group_vars = c("site_name", "g1_municipality", "g1_province", "year"))
site_year_domains <- site_year_indicators %>%
make_domain_scores(group_vars = c("site_name", "g1_municipality", "g1_province", "year"))
site_year_domains %>%
mutate(across(c(domain_score, domain_se, ci_low, ci_high), ~round(.x, 1))) %>%
arrange(site_name, year, domain) %>%
kable(caption = "Domain scores by site and year, complete Mozambique HHS")
| site_name | g1_municipality | g1_province | year | domain | n_hhs | domain_score | domain_se | ci_low | ci_high | n_indicators_available | min_n_valid |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Baixo Pinda | Memba | Nampula | 2019 | Capacity for Collective Action | 1 | 50.0 | NA | NA | NA | 4 | 1 |
| Baixo Pinda | Memba | Nampula | 2019 | Sustainable Livelihoods | 1 | 0.0 | NA | NA | NA | 2 | 1 |
| Baixo Pinda | Memba | Nampula | 2021 | Capacity for Collective Action | 101 | 52.1 | 1.6 | 49.0 | 55.2 | 4 | 96 |
| Baixo Pinda | Memba | Nampula | 2021 | Sustainable Livelihoods | 101 | 0.0 | 0.0 | 0.0 | 0.0 | 2 | 99 |
| Baixo Pinda | Memba | Nampula | 2024 | Capacity for Collective Action | 145 | 96.9 | 0.7 | 95.5 | 98.3 | 4 | 143 |
| Baixo Pinda | Memba | Nampula | 2024 | Sustainable Livelihoods | 145 | 1.0 | 0.6 | 0.0 | 2.2 | 2 | 145 |
| Baixo Pinda | Memba | Nampula | 2026 | Capacity for Collective Action | 135 | 51.4 | 1.7 | 48.0 | 54.8 | 4 | 110 |
| Baixo Pinda | Memba | Nampula | 2026 | Sustainable Livelihoods | 135 | 5.9 | 1.4 | 3.2 | 8.7 | 2 | 135 |
| Farol | Dondo | Sofala | 2019 | Capacity for Collective Action | 107 | 91.7 | 1.3 | 89.1 | 94.2 | 4 | 79 |
| Farol | Dondo | Sofala | 2019 | Sustainable Livelihoods | 107 | 3.3 | 1.2 | 0.9 | 5.7 | 2 | 105 |
| Fequete | Inhassoro | Inhambane | 2019 | Capacity for Collective Action | 196 | 80.9 | 1.5 | 78.0 | 83.8 | 4 | 90 |
| Fequete | Inhassoro | Inhambane | 2019 | Sustainable Livelihoods | 196 | 19.7 | 2.0 | 15.9 | 23.6 | 2 | 189 |
| Fequete | Inhassoro | Inhambane | 2021 | Capacity for Collective Action | 200 | 78.7 | 1.7 | 75.5 | 82.0 | 4 | 62 |
| Fequete | Inhassoro | Inhambane | 2021 | Sustainable Livelihoods | 200 | 15.1 | 1.7 | 11.7 | 18.4 | 2 | 198 |
| Fequete | Inhassoro | Inhambane | 2025 | Capacity for Collective Action | 104 | 71.7 | 2.3 | 67.2 | 76.1 | 4 | 46 |
| Fequete | Inhassoro | Inhambane | 2025 | Sustainable Livelihoods | 104 | 14.4 | 2.4 | 9.7 | 19.2 | 2 | 104 |
| Ilha Insular | Ilha de Mocambique | Nampula | 2019 | Capacity for Collective Action | 327 | 75.5 | 1.3 | 72.9 | 78.1 | 4 | 139 |
| Ilha Insular | Ilha de Mocambique | Nampula | 2019 | Sustainable Livelihoods | 327 | 25.7 | 1.6 | 22.5 | 28.8 | 2 | 325 |
| Ilha Insular | Ilha de Mocambique | Nampula | 2021 | Capacity for Collective Action | 125 | 95.3 | 1.1 | 93.1 | 97.4 | 4 | 65 |
| Ilha Insular | Ilha de Mocambique | Nampula | 2021 | Sustainable Livelihoods | 125 | 8.9 | 1.8 | 5.4 | 12.4 | 2 | 124 |
| Ilha Insular | Ilha de Mocambique | Nampula | 2023 | Capacity for Collective Action | 106 | 98.8 | 0.5 | 97.8 | 99.9 | 4 | 55 |
| Ilha Insular | Ilha de Mocambique | Nampula | 2023 | Sustainable Livelihoods | 106 | 3.3 | 1.2 | 0.9 | 5.7 | 2 | 106 |
| Ilha Insular | Ilha de Mocambique | Nampula | 2025 | Capacity for Collective Action | 566 | 77.8 | 0.8 | 76.2 | 79.5 | 4 | 313 |
| Ilha Insular | Ilha de Mocambique | Nampula | 2025 | Sustainable Livelihoods | 566 | 13.0 | 0.9 | 11.2 | 14.8 | 2 | 566 |
| Mabuluku | Matutuíne | Maputo | 2019 | Capacity for Collective Action | 61 | 87.5 | 2.1 | 83.5 | 91.6 | 4 | 59 |
| Mabuluku | Matutuíne | Maputo | 2019 | Sustainable Livelihoods | 61 | 48.6 | 4.1 | 40.5 | 56.6 | 2 | 56 |
| Mabuluku | Matutuíne | Maputo | 2021 | Capacity for Collective Action | 64 | 89.4 | 1.9 | 85.7 | 93.1 | 4 | 56 |
| Mabuluku | Matutuíne | Maputo | 2021 | Sustainable Livelihoods | 64 | 36.5 | 4.1 | 28.5 | 44.5 | 2 | 63 |
| Maculuvelane | Mogincual | Nampula | 2024 | Capacity for Collective Action | 21 | 81.0 | 2.8 | 75.5 | 86.4 | 4 | 21 |
| Maculuvelane | Mogincual | Nampula | 2024 | Sustainable Livelihoods | 21 | 0.0 | 0.0 | 0.0 | 0.0 | 2 | 21 |
| Mahelene | Nacala Porto | Nampula | 2024 | Capacity for Collective Action | 134 | 91.9 | 1.1 | 89.7 | 94.1 | 4 | 96 |
| Mahelene | Nacala Porto | Nampula | 2024 | Sustainable Livelihoods | 134 | 19.0 | 2.4 | 14.3 | 23.7 | 2 | 134 |
| Mahelene | Nacala Porto | Nampula | 2026 | Capacity for Collective Action | 110 | 63.2 | 2.5 | 58.4 | 68.1 | 4 | 67 |
| Mahelene | Nacala Porto | Nampula | 2026 | Sustainable Livelihoods | 110 | 33.2 | 2.7 | 27.9 | 38.5 | 2 | 110 |
| Meculuvelane | Mogincual | Nampula | 2025 | Capacity for Collective Action | 22 | 90.9 | 2.9 | 85.2 | 96.6 | 4 | 22 |
| Meculuvelane | Mogincual | Nampula | 2025 | Sustainable Livelihoods | 22 | 20.5 | 5.4 | 9.9 | 31.0 | 2 | 22 |
| Memba | Memba | Nampula | 2019 | Capacity for Collective Action | 206 | 61.9 | 2.0 | 57.8 | 65.9 | 4 | 77 |
| Memba | Memba | Nampula | 2019 | Sustainable Livelihoods | 206 | 19.2 | 1.8 | 15.6 | 22.8 | 2 | 200 |
| Memba | Memba | Nampula | 2021 | Capacity for Collective Action | 214 | 95.1 | 0.8 | 93.5 | 96.7 | 4 | 93 |
| Memba | Memba | Nampula | 2021 | Sustainable Livelihoods | 214 | 55.1 | 2.4 | 50.4 | 59.9 | 2 | 207 |
| Memba-sede | Memba | Nampula | 2026 | Capacity for Collective Action | 139 | 70.0 | 1.8 | 66.5 | 73.4 | 4 | 88 |
| Memba-sede | Memba | Nampula | 2026 | Sustainable Livelihoods | 139 | 19.8 | 2.2 | 15.5 | 24.1 | 2 | 139 |
| Mucocuene | Inhassoro | Inhambane | 2019 | Capacity for Collective Action | 1 | 100.0 | NA | NA | NA | 3 | 0 |
| Mucocuene | Inhassoro | Inhambane | 2019 | Sustainable Livelihoods | 1 | 0.0 | NA | NA | NA | 2 | 1 |
| Mucocuene | Inhassoro | Inhambane | 2021 | Capacity for Collective Action | 205 | 89.4 | 1.0 | 87.4 | 91.4 | 4 | 77 |
| Mucocuene | Inhassoro | Inhambane | 2021 | Sustainable Livelihoods | 205 | 4.9 | 1.1 | 2.8 | 7.0 | 2 | 204 |
| Mucocuene | Inhassoro | Inhambane | 2025 | Capacity for Collective Action | 99 | 76.3 | 2.3 | 71.8 | 80.7 | 4 | 41 |
| Mucocuene | Inhassoro | Inhambane | 2025 | Sustainable Livelihoods | 99 | 19.2 | 2.7 | 13.9 | 24.5 | 2 | 99 |
| Namalungo | Mogincual | Nampula | 2024 | Capacity for Collective Action | 134 | 64.7 | 1.2 | 62.4 | 67.1 | 4 | 134 |
| Namalungo | Mogincual | Nampula | 2024 | Sustainable Livelihoods | 134 | 6.3 | 1.4 | 3.5 | 9.2 | 2 | 134 |
| Namalungo | Mogincual | Nampula | 2025 | Capacity for Collective Action | 129 | 78.3 | 1.8 | 74.9 | 81.8 | 4 | 105 |
| Namalungo | Mogincual | Nampula | 2025 | Sustainable Livelihoods | 129 | 20.5 | 2.2 | 16.3 | 24.8 | 2 | 129 |
| Namige Sede | Mogincual | Nampula | 2024 | Capacity for Collective Action | 151 | 93.5 | 1.2 | 91.1 | 95.8 | 4 | 68 |
| Namige Sede | Mogincual | Nampula | 2024 | Sustainable Livelihoods | 151 | 62.6 | 2.7 | 57.3 | 67.9 | 2 | 151 |
| Namige Sede | Mogincual | Nampula | 2025 | Capacity for Collective Action | 157 | 83.2 | 1.5 | 80.3 | 86.1 | 4 | 127 |
| Namige Sede | Mogincual | Nampula | 2025 | Sustainable Livelihoods | 157 | 23.9 | 2.0 | 19.9 | 27.9 | 2 | 157 |
| Nhagondzo | Inhassoro | Inhambane | 2021 | Capacity for Collective Action | 127 | 89.6 | 1.4 | 86.9 | 92.3 | 4 | 76 |
| Nhagondzo | Inhassoro | Inhambane | 2021 | Sustainable Livelihoods | 127 | 8.5 | 1.8 | 5.1 | 12.0 | 2 | 123 |
| Nhagondzo | Inhassoro | Inhambane | 2025 | Capacity for Collective Action | 96 | 77.5 | 2.1 | 73.4 | 81.6 | 4 | 76 |
| Nhagondzo | Inhassoro | Inhambane | 2025 | Sustainable Livelihoods | 96 | 17.7 | 2.7 | 12.4 | 23.1 | 2 | 96 |
| Petane | Inhassoro | Inhambane | 2025 | Capacity for Collective Action | 99 | 70.0 | 2.3 | 65.5 | 74.5 | 4 | 33 |
| Petane | Inhassoro | Inhambane | 2025 | Sustainable Livelihoods | 99 | 11.1 | 2.2 | 6.8 | 15.4 | 2 | 99 |
| Petane1 | Inhassoro | Inhambane | 2021 | Capacity for Collective Action | 74 | 71.7 | 3.1 | 65.7 | 77.7 | 4 | 21 |
| Petane1 | Inhassoro | Inhambane | 2021 | Sustainable Livelihoods | 74 | 8.8 | 2.3 | 4.3 | 13.3 | 2 | 72 |
| Pomene | Massinga | Inhambane | 2019 | Capacity for Collective Action | 140 | 81.8 | 1.7 | 78.5 | 85.1 | 4 | 90 |
| Pomene | Massinga | Inhambane | 2019 | Sustainable Livelihoods | 140 | 33.1 | 2.9 | 27.5 | 38.8 | 2 | 133 |
| Pomene | Massinga | Inhambane | 2021 | Capacity for Collective Action | 137 | 84.1 | 1.7 | 80.7 | 87.5 | 4 | 65 |
| Pomene | Massinga | Inhambane | 2021 | Sustainable Livelihoods | 137 | 25.9 | 2.4 | 21.2 | 30.6 | 2 | 137 |
| Quissanga | Ilha de Mocambique | Nampula | 2021 | Capacity for Collective Action | 91 | 89.3 | 1.7 | 85.9 | 92.7 | 4 | 57 |
| Quissanga | Ilha de Mocambique | Nampula | 2021 | Sustainable Livelihoods | 91 | 14.6 | 2.6 | 9.5 | 19.7 | 2 | 89 |
| Quissanga | Ilha de Mocambique | Nampula | 2023 | Capacity for Collective Action | 103 | 98.3 | 0.6 | 97.1 | 99.5 | 4 | 102 |
| Quissanga | Ilha de Mocambique | Nampula | 2023 | Sustainable Livelihoods | 103 | 24.8 | 2.5 | 19.9 | 29.6 | 2 | 103 |
| Quissanga | Ilha de Mocambique | Nampula | 2025 | Capacity for Collective Action | 171 | 37.6 | 1.4 | 34.8 | 40.4 | 4 | 165 |
| Quissanga | Ilha de Mocambique | Nampula | 2025 | Sustainable Livelihoods | 171 | 0.9 | 0.5 | 0.0 | 1.9 | 2 | 171 |
| Quissimajulo | Nacala Porto | Nampula | 2024 | Capacity for Collective Action | 126 | 83.9 | 1.6 | 80.9 | 87.0 | 4 | 86 |
| Quissimajulo | Nacala Porto | Nampula | 2024 | Sustainable Livelihoods | 126 | 19.4 | 2.5 | 14.5 | 24.3 | 2 | 126 |
| Quissimajulo | Nacala Porto | Nampula | 2026 | Capacity for Collective Action | 71 | 61.0 | 3.3 | 54.5 | 67.5 | 4 | 31 |
| Quissimajulo | Nacala Porto | Nampula | 2026 | Sustainable Livelihoods | 71 | 38.7 | 3.9 | 31.1 | 46.3 | 2 | 71 |
| Sanculo | Ilha de Mocambique | Nampula | 2021 | Capacity for Collective Action | 106 | 94.0 | 1.2 | 91.6 | 96.3 | 4 | 90 |
| Sanculo | Ilha de Mocambique | Nampula | 2021 | Sustainable Livelihoods | 106 | 10.4 | 2.1 | 6.2 | 14.6 | 2 | 100 |
| Sanculo | Ilha de Mocambique | Nampula | 2023 | Capacity for Collective Action | 104 | 90.4 | 1.3 | 87.8 | 93.0 | 4 | 104 |
| Sanculo | Ilha de Mocambique | Nampula | 2023 | Sustainable Livelihoods | 104 | 1.0 | 0.7 | 0.0 | 2.3 | 2 | 104 |
| Sanculo | Ilha de Mocambique | Nampula | 2025 | Capacity for Collective Action | 220 | 86.3 | 1.1 | 84.2 | 88.5 | 4 | 201 |
| Sanculo | Ilha de Mocambique | Nampula | 2025 | Sustainable Livelihoods | 220 | 4.1 | 0.9 | 2.3 | 5.9 | 2 | 220 |
| Santa Maria | Matutuíne | Maputo | 2019 | Capacity for Collective Action | 104 | 93.6 | 1.2 | 91.2 | 96.0 | 4 | 95 |
| Santa Maria | Matutuíne | Maputo | 2019 | Sustainable Livelihoods | 104 | 65.2 | 3.4 | 58.7 | 71.8 | 2 | 96 |
| Santa Maria | Matutuíne | Maputo | 2021 | Capacity for Collective Action | 88 | 80.1 | 2.1 | 76.0 | 84.2 | 4 | 72 |
| Santa Maria | Matutuíne | Maputo | 2021 | Sustainable Livelihoods | 88 | 36.0 | 3.6 | 28.9 | 43.1 | 2 | 87 |
| Sengo | Dondo | Sofala | 2019 | Capacity for Collective Action | 94 | 93.6 | 1.5 | 90.6 | 96.5 | 4 | 38 |
| Sengo | Dondo | Sofala | 2019 | Sustainable Livelihoods | 94 | 6.5 | 1.8 | 3.1 | 10.0 | 2 | 92 |
| Sengo | Dondo | Sofala | 2021 | Capacity for Collective Action | 29 | 100.0 | 0.0 | 100.0 | 100.0 | 4 | 15 |
| Sengo | Dondo | Sofala | 2021 | Sustainable Livelihoods | 29 | 23.3 | 6.7 | 10.3 | 36.4 | 2 | 15 |
| Serissa | Memba | Nampula | 2021 | Capacity for Collective Action | 207 | 87.7 | 1.3 | 85.1 | 90.3 | 4 | 68 |
| Serissa | Memba | Nampula | 2021 | Sustainable Livelihoods | 207 | 7.0 | 1.3 | 4.6 | 9.5 | 2 | 199 |
| Simuco | Memba | Nampula | 2021 | Capacity for Collective Action | 180 | 79.5 | 1.5 | 76.6 | 82.4 | 4 | 11 |
| Simuco | Memba | Nampula | 2021 | Sustainable Livelihoods | 180 | 24.4 | 2.3 | 19.9 | 28.8 | 2 | 176 |
| Tsondzo | Inhassoro | Inhambane | 2021 | Capacity for Collective Action | 221 | 92.0 | 0.9 | 90.3 | 93.8 | 4 | 109 |
| Tsondzo | Inhassoro | Inhambane | 2021 | Sustainable Livelihoods | 221 | 7.8 | 1.3 | 5.4 | 10.3 | 2 | 217 |
| Tsondzo | Inhassoro | Inhambane | 2025 | Capacity for Collective Action | 103 | 80.8 | 2.1 | 76.7 | 84.8 | 4 | 65 |
| Tsondzo | Inhassoro | Inhambane | 2025 | Sustainable Livelihoods | 103 | 16.0 | 2.5 | 11.1 | 21.0 | 2 | 103 |
| Vuca | Inhassoro | Inhambane | 2021 | Capacity for Collective Action | 96 | 86.1 | 1.6 | 82.9 | 89.3 | 4 | 32 |
| Vuca | Inhassoro | Inhambane | 2021 | Sustainable Livelihoods | 96 | 26.2 | 3.1 | 20.1 | 32.4 | 2 | 95 |
| Vuca | Inhassoro | Inhambane | 2025 | Capacity for Collective Action | 99 | 68.0 | 2.4 | 63.4 | 72.7 | 4 | 56 |
| Vuca | Inhassoro | Inhambane | 2025 | Sustainable Livelihoods | 99 | 19.7 | 2.8 | 14.2 | 25.2 | 2 | 99 |
| Zavora | Inharrime | Inhambane | 2019 | Capacity for Collective Action | 223 | 89.2 | 1.1 | 87.0 | 91.3 | 4 | 89 |
| Zavora | Inharrime | Inhambane | 2019 | Sustainable Livelihoods | 223 | 31.6 | 2.3 | 27.1 | 36.2 | 2 | 185 |
| Zavora | Inharrime | Inhambane | 2021 | Capacity for Collective Action | 228 | 90.8 | 0.9 | 89.0 | 92.6 | 4 | 116 |
| Zavora | Inharrime | Inhambane | 2021 | Sustainable Livelihoods | 228 | 32.8 | 2.2 | 28.5 | 37.1 | 2 | 219 |
ggplot(site_year_domains,
aes(x = factor(year), y = fct_reorder(site_name, domain_score, .fun = mean_na), fill = domain_score)) +
geom_tile(color = "white") +
facet_wrap(~ domain, ncol = 2) +
scale_fill_gradient(low = "grey95", high = "grey20", limits = c(0, 100), na.value = "white") +
labs(
title = "CCRF domain scores by site and year: complete Mozambique HHS",
subtitle = "Blank/missing combinations reflect no data or insufficient valid indicator responses. See table for confidence intervals.",
x = "Survey year",
y = "Site / community",
fill = "Score
0–100"
)
ggplot(site_year_domains,
aes(x = year, y = domain_score, group = domain, linetype = domain)) +
geom_errorbar(aes(ymin = ci_low, ymax = ci_high), width = 0.10, alpha = 0.45) +
geom_line(linewidth = 0.6) +
geom_point(size = 1.8) +
facet_wrap(~ site_name, ncol = 4) +
scale_y_continuous(limits = c(0, 100), breaks = c(0, 50, 100)) +
scale_x_continuous(breaks = sort(unique(site_year_domains$year))) +
labs(
title = "CCRF domain scores by site and year: complete Mozambique HHS",
subtitle = "Use cautiously: some site-year estimates are based on small samples; error bars show approximate 95% CIs",
x = "Survey year",
y = "Mean domain score, 0–100",
linetype = "Domain"
) +
theme(
legend.position = "bottom",
axis.text.x = element_text(angle = 45, hjust = 1),
strip.text = element_text(face = "bold")
)
This section focuses only on the BAF / Rare project sites. This is the main case-study subset.
hhs_project <- hhs_if %>%
filter(is_project_site)
project_site_indicators <- hhs_project %>%
summarise_indicators(group_vars = c("project_site", "district", "program_maturity"))
project_site_domains <- project_site_indicators %>%
make_domain_scores(group_vars = c("project_site", "district", "program_maturity"))
project_site_domains %>%
mutate(across(c(domain_score, domain_se, ci_low, ci_high), ~round(.x, 1))) %>%
arrange(district, project_site, domain) %>%
kable(caption = "Domain scores by Wilipihera / Rare project site")
| project_site | district | program_maturity | domain | n_hhs | domain_score | domain_se | ci_low | ci_high | n_indicators_available | min_n_valid |
|---|---|---|---|---|---|---|---|---|---|---|
| Ilha Insular | Ilha de Mocambique | Former/older Rare site | Capacity for Collective Action | 1124 | 81.3 | 0.6 | 80.1 | 82.4 | 4 | 572 |
| Ilha Insular | Ilha de Mocambique | Former/older Rare site | Sustainable Livelihoods | 1124 | 15.3 | 0.7 | 13.9 | 16.7 | 2 | 1121 |
| Quissanga | Ilha de Mocambique | Former/older Rare site | Capacity for Collective Action | 365 | 66.9 | 1.2 | 64.6 | 69.2 | 4 | 324 |
| Quissanga | Ilha de Mocambique | Former/older Rare site | Sustainable Livelihoods | 365 | 11.0 | 1.1 | 8.8 | 13.2 | 2 | 363 |
| Sanculo | Ilha de Mocambique | Former/older Rare site | Capacity for Collective Action | 430 | 89.2 | 0.7 | 87.8 | 90.7 | 4 | 395 |
| Sanculo | Ilha de Mocambique | Former/older Rare site | Sustainable Livelihoods | 430 | 4.8 | 0.7 | 3.4 | 6.3 | 2 | 424 |
| Baixo Pinda | Memba | Former/older Rare site | Capacity for Collective Action | 382 | 68.6 | 1.2 | 66.3 | 70.9 | 4 | 350 |
| Baixo Pinda | Memba | Former/older Rare site | Sustainable Livelihoods | 382 | 2.5 | 0.6 | 1.4 | 3.6 | 2 | 380 |
| Memba Sede | Memba | Former/older Rare site | Capacity for Collective Action | 559 | 77.8 | 1.0 | 75.8 | 79.7 | 4 | 258 |
| Memba Sede | Memba | Former/older Rare site | Sustainable Livelihoods | 559 | 33.1 | 1.4 | 30.4 | 35.8 | 2 | 547 |
| Meculuvelane | Mogincual | Newer expansion site | Capacity for Collective Action | 22 | 90.9 | 2.9 | 85.2 | 96.6 | 4 | 22 |
| Meculuvelane | Mogincual | Newer expansion site | Sustainable Livelihoods | 22 | 20.5 | 5.4 | 9.9 | 31.0 | 2 | 22 |
| Namalungo | Mogincual | Newer expansion site | Capacity for Collective Action | 263 | 71.6 | 1.1 | 69.3 | 73.8 | 4 | 239 |
| Namalungo | Mogincual | Newer expansion site | Sustainable Livelihoods | 263 | 13.3 | 1.4 | 10.6 | 16.0 | 2 | 263 |
| Namige Sede | Mogincual | Newer expansion site | Capacity for Collective Action | 308 | 88.3 | 1.0 | 86.4 | 90.2 | 4 | 195 |
| Namige Sede | Mogincual | Newer expansion site | Sustainable Livelihoods | 308 | 42.9 | 2.0 | 39.0 | 46.7 | 2 | 308 |
| Mahelene | Nacala Porto | Newer expansion site | Capacity for Collective Action | 244 | 79.4 | 1.3 | 76.8 | 82.0 | 4 | 163 |
| Mahelene | Nacala Porto | Newer expansion site | Sustainable Livelihoods | 244 | 25.4 | 1.9 | 21.7 | 29.1 | 2 | 244 |
| Quissimajulo | Nacala Porto | Newer expansion site | Capacity for Collective Action | 197 | 76.6 | 1.5 | 73.6 | 79.6 | 4 | 117 |
| Quissimajulo | Nacala Porto | Newer expansion site | Sustainable Livelihoods | 197 | 26.4 | 2.2 | 22.1 | 30.7 | 2 | 197 |
ggplot(project_site_domains,
aes(x = fct_reorder(project_site, domain_score), y = domain_score, fill = domain)) +
geom_col(position = position_dodge(width = 0.75), width = 0.7) +
geom_errorbar(
aes(ymin = ci_low, ymax = ci_high),
position = position_dodge(width = 0.75),
width = 0.18
) +
coord_flip() +
facet_wrap(~ district, scales = "free_y") +
scale_y_continuous(limits = c(0, 100), breaks = seq(0, 100, 25)) +
labs(
title = "Project-site CCRF domain scores",
subtitle = "Error bars show approximate 95% CIs",
x = "Project site",
y = "Mean domain score, 0–100",
fill = "Domain"
) +
theme(legend.position = "bottom")
project_site_indicators %>%
filter(direction == "positive_core") %>%
mutate(across(c(pct, se, ci_low, ci_high), ~round(.x, 1))) %>%
select(project_site, district, domain, label, n_hhs, n_valid, pct, se, ci_low, ci_high) %>%
arrange(district, project_site, domain, label) %>%
kable(caption = "Positive indicator scores by project site")
| project_site | district | domain | label | n_hhs | n_valid | pct | se | ci_low | ci_high |
|---|---|---|---|---|---|---|---|---|---|
| Ilha Insular | Ilha de Mocambique | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 1124 | 1124 | 67.2 | 1.4 | 64.4 | 69.9 |
| Ilha Insular | Ilha de Mocambique | Capacity for Collective Action | Empowerment & Participation in Management | 1124 | 572 | 93.2 | 1.1 | 91.1 | 95.2 |
| Ilha Insular | Ilha de Mocambique | Capacity for Collective Action | Social Equity in Fisheries Benefits | 1124 | 1071 | 83.3 | 1.1 | 81.1 | 85.5 |
| Ilha Insular | Ilha de Mocambique | Capacity for Collective Action | Trust in Local Leadership | 1124 | 1124 | 81.4 | 1.2 | 79.1 | 83.7 |
| Ilha Insular | Ilha de Mocambique | Sustainable Livelihoods | Household covers needs | 1124 | 1121 | 26.9 | 1.3 | 24.3 | 29.5 |
| Ilha Insular | Ilha de Mocambique | Sustainable Livelihoods | Never worried about enough food | 1124 | 1123 | 3.7 | 0.6 | 2.6 | 4.7 |
| Quissanga | Ilha de Mocambique | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 365 | 364 | 57.1 | 2.6 | 52.1 | 62.2 |
| Quissanga | Ilha de Mocambique | Capacity for Collective Action | Empowerment & Participation in Management | 365 | 324 | 54.9 | 2.8 | 49.5 | 60.4 |
| Quissanga | Ilha de Mocambique | Capacity for Collective Action | Social Equity in Fisheries Benefits | 365 | 362 | 95.0 | 1.1 | 92.8 | 97.3 |
| Quissanga | Ilha de Mocambique | Capacity for Collective Action | Trust in Local Leadership | 365 | 364 | 60.4 | 2.6 | 55.4 | 65.5 |
| Quissanga | Ilha de Mocambique | Sustainable Livelihoods | Household covers needs | 365 | 363 | 19.3 | 2.1 | 15.2 | 23.3 |
| Quissanga | Ilha de Mocambique | Sustainable Livelihoods | Never worried about enough food | 365 | 364 | 2.7 | 0.9 | 1.1 | 4.4 |
| Sanculo | Ilha de Mocambique | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 430 | 429 | 85.5 | 1.7 | 82.2 | 88.9 |
| Sanculo | Ilha de Mocambique | Capacity for Collective Action | Empowerment & Participation in Management | 430 | 395 | 94.4 | 1.2 | 92.2 | 96.7 |
| Sanculo | Ilha de Mocambique | Capacity for Collective Action | Social Equity in Fisheries Benefits | 430 | 428 | 81.1 | 1.9 | 77.4 | 84.8 |
| Sanculo | Ilha de Mocambique | Capacity for Collective Action | Trust in Local Leadership | 430 | 429 | 95.8 | 1.0 | 93.9 | 97.7 |
| Sanculo | Ilha de Mocambique | Sustainable Livelihoods | Household covers needs | 430 | 424 | 7.8 | 1.3 | 5.2 | 10.3 |
| Sanculo | Ilha de Mocambique | Sustainable Livelihoods | Never worried about enough food | 430 | 428 | 1.9 | 0.7 | 0.6 | 3.2 |
| Baixo Pinda | Memba | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 382 | 381 | 73.0 | 2.3 | 68.5 | 77.4 |
| Baixo Pinda | Memba | Capacity for Collective Action | Empowerment & Participation in Management | 382 | 350 | 74.9 | 2.3 | 70.3 | 79.4 |
| Baixo Pinda | Memba | Capacity for Collective Action | Social Equity in Fisheries Benefits | 382 | 379 | 80.7 | 2.0 | 76.8 | 84.7 |
| Baixo Pinda | Memba | Capacity for Collective Action | Trust in Local Leadership | 382 | 382 | 45.8 | 2.6 | 40.8 | 50.8 |
| Baixo Pinda | Memba | Sustainable Livelihoods | Household covers needs | 382 | 380 | 4.5 | 1.1 | 2.4 | 6.6 |
| Baixo Pinda | Memba | Sustainable Livelihoods | Never worried about enough food | 382 | 381 | 0.5 | 0.4 | 0.0 | 1.3 |
| Memba Sede | Memba | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 559 | 551 | 78.0 | 1.8 | 74.6 | 81.5 |
| Memba Sede | Memba | Capacity for Collective Action | Empowerment & Participation in Management | 559 | 258 | 84.1 | 2.3 | 79.6 | 88.6 |
| Memba Sede | Memba | Capacity for Collective Action | Social Equity in Fisheries Benefits | 559 | 529 | 74.9 | 1.9 | 71.2 | 78.6 |
| Memba Sede | Memba | Capacity for Collective Action | Trust in Local Leadership | 559 | 554 | 74.0 | 1.9 | 70.4 | 77.7 |
| Memba Sede | Memba | Sustainable Livelihoods | Household covers needs | 559 | 547 | 42.0 | 2.1 | 37.9 | 46.2 |
| Memba Sede | Memba | Sustainable Livelihoods | Never worried about enough food | 559 | 551 | 24.1 | 1.8 | 20.6 | 27.7 |
| Meculuvelane | Mogincual | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 22 | 22 | 72.7 | 9.7 | 53.7 | 91.8 |
| Meculuvelane | Mogincual | Capacity for Collective Action | Empowerment & Participation in Management | 22 | 22 | 95.5 | 4.5 | 86.5 | 100.0 |
| Meculuvelane | Mogincual | Capacity for Collective Action | Social Equity in Fisheries Benefits | 22 | 22 | 100.0 | 0.0 | 100.0 | 100.0 |
| Meculuvelane | Mogincual | Capacity for Collective Action | Trust in Local Leadership | 22 | 22 | 95.5 | 4.5 | 86.5 | 100.0 |
| Meculuvelane | Mogincual | Sustainable Livelihoods | Household covers needs | 22 | 22 | 40.9 | 10.7 | 19.9 | 61.9 |
| Meculuvelane | Mogincual | Sustainable Livelihoods | Never worried about enough food | 22 | 22 | 0.0 | 0.0 | 0.0 | 0.0 |
| Namalungo | Mogincual | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 263 | 263 | 31.6 | 2.9 | 25.9 | 37.2 |
| Namalungo | Mogincual | Capacity for Collective Action | Empowerment & Participation in Management | 263 | 239 | 95.0 | 1.4 | 92.2 | 97.8 |
| Namalungo | Mogincual | Capacity for Collective Action | Social Equity in Fisheries Benefits | 263 | 263 | 95.4 | 1.3 | 92.9 | 98.0 |
| Namalungo | Mogincual | Capacity for Collective Action | Trust in Local Leadership | 263 | 263 | 64.3 | 3.0 | 58.5 | 70.1 |
| Namalungo | Mogincual | Sustainable Livelihoods | Household covers needs | 263 | 263 | 26.6 | 2.7 | 21.3 | 32.0 |
| Namalungo | Mogincual | Sustainable Livelihoods | Never worried about enough food | 263 | 263 | 0.0 | 0.0 | 0.0 | 0.0 |
| Namige Sede | Mogincual | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 308 | 308 | 80.8 | 2.2 | 76.4 | 85.2 |
| Namige Sede | Mogincual | Capacity for Collective Action | Empowerment & Participation in Management | 308 | 195 | 91.3 | 2.0 | 87.3 | 95.3 |
| Namige Sede | Mogincual | Capacity for Collective Action | Social Equity in Fisheries Benefits | 308 | 307 | 90.9 | 1.6 | 87.7 | 94.1 |
| Namige Sede | Mogincual | Capacity for Collective Action | Trust in Local Leadership | 308 | 308 | 90.3 | 1.7 | 86.9 | 93.6 |
| Namige Sede | Mogincual | Sustainable Livelihoods | Household covers needs | 308 | 308 | 48.4 | 2.9 | 42.8 | 54.0 |
| Namige Sede | Mogincual | Sustainable Livelihoods | Never worried about enough food | 308 | 308 | 37.3 | 2.8 | 31.9 | 42.7 |
| Mahelene | Nacala Porto | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 244 | 244 | 74.6 | 2.8 | 69.1 | 80.1 |
| Mahelene | Nacala Porto | Capacity for Collective Action | Empowerment & Participation in Management | 244 | 163 | 89.0 | 2.5 | 84.1 | 93.8 |
| Mahelene | Nacala Porto | Capacity for Collective Action | Social Equity in Fisheries Benefits | 244 | 230 | 68.7 | 3.1 | 62.7 | 74.7 |
| Mahelene | Nacala Porto | Capacity for Collective Action | Trust in Local Leadership | 244 | 244 | 85.2 | 2.3 | 80.8 | 89.7 |
| Mahelene | Nacala Porto | Sustainable Livelihoods | Household covers needs | 244 | 244 | 36.9 | 3.1 | 30.8 | 43.0 |
| Mahelene | Nacala Porto | Sustainable Livelihoods | Never worried about enough food | 244 | 244 | 13.9 | 2.2 | 9.6 | 18.3 |
| Quissimajulo | Nacala Porto | Capacity for Collective Action | Collective Efficacy for Fisheries Management Score | 197 | 197 | 64.5 | 3.4 | 57.8 | 71.2 |
| Quissimajulo | Nacala Porto | Capacity for Collective Action | Empowerment & Participation in Management | 197 | 117 | 89.7 | 2.8 | 84.2 | 95.3 |
| Quissimajulo | Nacala Porto | Capacity for Collective Action | Social Equity in Fisheries Benefits | 197 | 186 | 63.4 | 3.5 | 56.5 | 70.4 |
| Quissimajulo | Nacala Porto | Capacity for Collective Action | Trust in Local Leadership | 197 | 197 | 88.8 | 2.2 | 84.4 | 93.2 |
| Quissimajulo | Nacala Porto | Sustainable Livelihoods | Household covers needs | 197 | 197 | 31.0 | 3.3 | 24.5 | 37.4 |
| Quissimajulo | Nacala Porto | Sustainable Livelihoods | Never worried about enough food | 197 | 197 | 21.8 | 3.0 | 16.0 | 27.6 |
project_site_indicators_clean <- project_site_indicators %>%
filter(direction == "positive_core") %>%
mutate(
label = stringr::str_wrap(label, width = 28),
project_site = stringr::str_wrap(project_site, width = 16)
)
project_site_indicators_clean <- project_site_indicators %>%
filter(direction == "positive_core") %>%
mutate(
label = stringr::str_wrap(label, width = 28),
project_site = stringr::str_wrap(project_site, width = 16)
)
# Define site order
site_levels <- project_site_indicators_clean %>%
distinct(project_site) %>%
arrange(project_site) %>%
mutate(site_id = row_number())
project_site_indicators_clean <- project_site_indicators_clean %>%
left_join(site_levels, by = "project_site")
# Alternating background bands
site_bands <- site_levels %>%
mutate(
xmin = site_id - 0.5,
xmax = site_id + 0.5,
shade = site_id %% 2 == 0
) %>%
filter(shade)
ggplot(
project_site_indicators_clean,
aes(
x = site_id,
y = pct,
color = label,
group = label
)
) +
geom_rect(
data = site_bands,
aes(
xmin = xmin,
xmax = xmax,
ymin = -Inf,
ymax = Inf
),
inherit.aes = FALSE,
fill = "grey95",
color = NA
) +
geom_errorbar(
aes(ymin = ci_low, ymax = ci_high),
position = position_dodge(width = 0.55),
width = 0.25,
linewidth = 0.5,
alpha = 0.6
) +
geom_point(
position = position_dodge(width = 0.55),
size = 2.4
) +
coord_flip() +
facet_wrap(
~ domain,
ncol = 1
) +
scale_x_continuous(
breaks = site_levels$site_id,
labels = site_levels$project_site,
expand = expansion(add = 0.3)
) +
scale_y_continuous(
limits = c(0, 100),
breaks = seq(0, 100, 25),
labels = scales::label_percent(scale = 1)
) +
scale_color_brewer(palette = "Dark2") +
labs(
title = "Positive indicator scores by project site",
subtitle = "Points show mean indicator scores; error bars show approximate 95% CIs",
x = NULL,
y = "% positive",
color = "Indicator"
) +
theme_minimal(base_size = 12) +
theme(
legend.position = "bottom",
legend.title = element_text(size = 10),
legend.text = element_text(size = 9),
strip.text = element_text(face = "bold"),
panel.grid.minor = element_blank(),
panel.grid.major.y = element_blank()
)
project_site_year_indicators <- hhs_project %>%
summarise_indicators(group_vars = c("project_site", "district", "program_maturity", "year"))
project_site_year_domains <- project_site_year_indicators %>%
make_domain_scores(group_vars = c("project_site", "district", "program_maturity", "year"))
project_site_year_domains %>%
mutate(across(c(domain_score, domain_se, ci_low, ci_high), ~round(.x, 1))) %>%
arrange(district, project_site, year, domain) %>%
kable(caption = "Project-site domain scores by year")
| project_site | district | program_maturity | year | domain | n_hhs | domain_score | domain_se | ci_low | ci_high | n_indicators_available | min_n_valid |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Ilha Insular | Ilha de Mocambique | Former/older Rare site | 2019 | Capacity for Collective Action | 327 | 75.5 | 1.3 | 72.9 | 78.1 | 4 | 139 |
| Ilha Insular | Ilha de Mocambique | Former/older Rare site | 2019 | Sustainable Livelihoods | 327 | 25.7 | 1.6 | 22.5 | 28.8 | 2 | 325 |
| Ilha Insular | Ilha de Mocambique | Former/older Rare site | 2021 | Capacity for Collective Action | 125 | 95.3 | 1.1 | 93.1 | 97.4 | 4 | 65 |
| Ilha Insular | Ilha de Mocambique | Former/older Rare site | 2021 | Sustainable Livelihoods | 125 | 8.9 | 1.8 | 5.4 | 12.4 | 2 | 124 |
| Ilha Insular | Ilha de Mocambique | Former/older Rare site | 2023 | Capacity for Collective Action | 106 | 98.8 | 0.5 | 97.8 | 99.9 | 4 | 55 |
| Ilha Insular | Ilha de Mocambique | Former/older Rare site | 2023 | Sustainable Livelihoods | 106 | 3.3 | 1.2 | 0.9 | 5.7 | 2 | 106 |
| Ilha Insular | Ilha de Mocambique | Former/older Rare site | 2025 | Capacity for Collective Action | 566 | 77.8 | 0.8 | 76.2 | 79.5 | 4 | 313 |
| Ilha Insular | Ilha de Mocambique | Former/older Rare site | 2025 | Sustainable Livelihoods | 566 | 13.0 | 0.9 | 11.2 | 14.8 | 2 | 566 |
| Quissanga | Ilha de Mocambique | Former/older Rare site | 2021 | Capacity for Collective Action | 91 | 89.3 | 1.7 | 85.9 | 92.7 | 4 | 57 |
| Quissanga | Ilha de Mocambique | Former/older Rare site | 2021 | Sustainable Livelihoods | 91 | 14.6 | 2.6 | 9.5 | 19.7 | 2 | 89 |
| Quissanga | Ilha de Mocambique | Former/older Rare site | 2023 | Capacity for Collective Action | 103 | 98.3 | 0.6 | 97.1 | 99.5 | 4 | 102 |
| Quissanga | Ilha de Mocambique | Former/older Rare site | 2023 | Sustainable Livelihoods | 103 | 24.8 | 2.5 | 19.9 | 29.6 | 2 | 103 |
| Quissanga | Ilha de Mocambique | Former/older Rare site | 2025 | Capacity for Collective Action | 171 | 37.6 | 1.4 | 34.8 | 40.4 | 4 | 165 |
| Quissanga | Ilha de Mocambique | Former/older Rare site | 2025 | Sustainable Livelihoods | 171 | 0.9 | 0.5 | 0.0 | 1.9 | 2 | 171 |
| Sanculo | Ilha de Mocambique | Former/older Rare site | 2021 | Capacity for Collective Action | 106 | 94.0 | 1.2 | 91.6 | 96.3 | 4 | 90 |
| Sanculo | Ilha de Mocambique | Former/older Rare site | 2021 | Sustainable Livelihoods | 106 | 10.4 | 2.1 | 6.2 | 14.6 | 2 | 100 |
| Sanculo | Ilha de Mocambique | Former/older Rare site | 2023 | Capacity for Collective Action | 104 | 90.4 | 1.3 | 87.8 | 93.0 | 4 | 104 |
| Sanculo | Ilha de Mocambique | Former/older Rare site | 2023 | Sustainable Livelihoods | 104 | 1.0 | 0.7 | 0.0 | 2.3 | 2 | 104 |
| Sanculo | Ilha de Mocambique | Former/older Rare site | 2025 | Capacity for Collective Action | 220 | 86.3 | 1.1 | 84.2 | 88.5 | 4 | 201 |
| Sanculo | Ilha de Mocambique | Former/older Rare site | 2025 | Sustainable Livelihoods | 220 | 4.1 | 0.9 | 2.3 | 5.9 | 2 | 220 |
| Baixo Pinda | Memba | Former/older Rare site | 2019 | Capacity for Collective Action | 1 | 50.0 | NA | NA | NA | 4 | 1 |
| Baixo Pinda | Memba | Former/older Rare site | 2019 | Sustainable Livelihoods | 1 | 0.0 | NA | NA | NA | 2 | 1 |
| Baixo Pinda | Memba | Former/older Rare site | 2021 | Capacity for Collective Action | 101 | 52.1 | 1.6 | 49.0 | 55.2 | 4 | 96 |
| Baixo Pinda | Memba | Former/older Rare site | 2021 | Sustainable Livelihoods | 101 | 0.0 | 0.0 | 0.0 | 0.0 | 2 | 99 |
| Baixo Pinda | Memba | Former/older Rare site | 2024 | Capacity for Collective Action | 145 | 96.9 | 0.7 | 95.5 | 98.3 | 4 | 143 |
| Baixo Pinda | Memba | Former/older Rare site | 2024 | Sustainable Livelihoods | 145 | 1.0 | 0.6 | 0.0 | 2.2 | 2 | 145 |
| Baixo Pinda | Memba | Former/older Rare site | 2026 | Capacity for Collective Action | 135 | 51.4 | 1.7 | 48.0 | 54.8 | 4 | 110 |
| Baixo Pinda | Memba | Former/older Rare site | 2026 | Sustainable Livelihoods | 135 | 5.9 | 1.4 | 3.2 | 8.7 | 2 | 135 |
| Memba Sede | Memba | Former/older Rare site | 2019 | Capacity for Collective Action | 206 | 61.9 | 2.0 | 57.8 | 65.9 | 4 | 77 |
| Memba Sede | Memba | Former/older Rare site | 2019 | Sustainable Livelihoods | 206 | 19.2 | 1.8 | 15.6 | 22.8 | 2 | 200 |
| Memba Sede | Memba | Former/older Rare site | 2021 | Capacity for Collective Action | 214 | 95.1 | 0.8 | 93.5 | 96.7 | 4 | 93 |
| Memba Sede | Memba | Former/older Rare site | 2021 | Sustainable Livelihoods | 214 | 55.1 | 2.4 | 50.4 | 59.9 | 2 | 207 |
| Memba Sede | Memba | Former/older Rare site | 2026 | Capacity for Collective Action | 139 | 70.0 | 1.8 | 66.5 | 73.4 | 4 | 88 |
| Memba Sede | Memba | Former/older Rare site | 2026 | Sustainable Livelihoods | 139 | 19.8 | 2.2 | 15.5 | 24.1 | 2 | 139 |
| Meculuvelane | Mogincual | Newer expansion site | 2025 | Capacity for Collective Action | 22 | 90.9 | 2.9 | 85.2 | 96.6 | 4 | 22 |
| Meculuvelane | Mogincual | Newer expansion site | 2025 | Sustainable Livelihoods | 22 | 20.5 | 5.4 | 9.9 | 31.0 | 2 | 22 |
| Namalungo | Mogincual | Newer expansion site | 2024 | Capacity for Collective Action | 134 | 64.7 | 1.2 | 62.4 | 67.1 | 4 | 134 |
| Namalungo | Mogincual | Newer expansion site | 2024 | Sustainable Livelihoods | 134 | 6.3 | 1.4 | 3.5 | 9.2 | 2 | 134 |
| Namalungo | Mogincual | Newer expansion site | 2025 | Capacity for Collective Action | 129 | 78.3 | 1.8 | 74.9 | 81.8 | 4 | 105 |
| Namalungo | Mogincual | Newer expansion site | 2025 | Sustainable Livelihoods | 129 | 20.5 | 2.2 | 16.3 | 24.8 | 2 | 129 |
| Namige Sede | Mogincual | Newer expansion site | 2024 | Capacity for Collective Action | 151 | 93.5 | 1.2 | 91.1 | 95.8 | 4 | 68 |
| Namige Sede | Mogincual | Newer expansion site | 2024 | Sustainable Livelihoods | 151 | 62.6 | 2.7 | 57.3 | 67.9 | 2 | 151 |
| Namige Sede | Mogincual | Newer expansion site | 2025 | Capacity for Collective Action | 157 | 83.2 | 1.5 | 80.3 | 86.1 | 4 | 127 |
| Namige Sede | Mogincual | Newer expansion site | 2025 | Sustainable Livelihoods | 157 | 23.9 | 2.0 | 19.9 | 27.9 | 2 | 157 |
| Mahelene | Nacala Porto | Newer expansion site | 2024 | Capacity for Collective Action | 134 | 91.9 | 1.1 | 89.7 | 94.1 | 4 | 96 |
| Mahelene | Nacala Porto | Newer expansion site | 2024 | Sustainable Livelihoods | 134 | 19.0 | 2.4 | 14.3 | 23.7 | 2 | 134 |
| Mahelene | Nacala Porto | Newer expansion site | 2026 | Capacity for Collective Action | 110 | 63.2 | 2.5 | 58.4 | 68.1 | 4 | 67 |
| Mahelene | Nacala Porto | Newer expansion site | 2026 | Sustainable Livelihoods | 110 | 33.2 | 2.7 | 27.9 | 38.5 | 2 | 110 |
| Quissimajulo | Nacala Porto | Newer expansion site | 2024 | Capacity for Collective Action | 126 | 83.9 | 1.6 | 80.9 | 87.0 | 4 | 86 |
| Quissimajulo | Nacala Porto | Newer expansion site | 2024 | Sustainable Livelihoods | 126 | 19.4 | 2.5 | 14.5 | 24.3 | 2 | 126 |
| Quissimajulo | Nacala Porto | Newer expansion site | 2026 | Capacity for Collective Action | 71 | 61.0 | 3.3 | 54.5 | 67.5 | 4 | 31 |
| Quissimajulo | Nacala Porto | Newer expansion site | 2026 | Sustainable Livelihoods | 71 | 38.7 | 3.9 | 31.1 | 46.3 | 2 | 71 |
ggplot(project_site_year_domains,
aes(x = year, y = domain_score, group = domain, linetype = domain)) +
geom_errorbar(aes(ymin = ci_low, ymax = ci_high), width = 0.10, alpha = 0.55) +
geom_line(linewidth = 0.8) +
geom_point(size = 2.1) +
facet_wrap(~ project_site, ncol = 2) +
scale_y_continuous(limits = c(0, 100), breaks = seq(0, 100, 25)) +
scale_x_continuous(breaks = sort(unique(project_site_year_domains$year))) +
labs(
title = "Project-site domain scores by year",
subtitle = "Use cautiously: sample sizes and implementation context vary across site-years; error bars show approximate 95% CIs",
x = "Survey year",
y = "Mean domain score, 0–100",
linetype = "Domain"
) +
theme(
legend.position = "bottom",
strip.text = element_text(face = "bold"),
axis.text.x = element_text(angle = 45, hjust = 1)
)
ggplot(project_site_year_domains,
aes(x = factor(year), y = fct_reorder(project_site, domain_score, .fun = mean_na), fill = domain_score)) +
geom_tile(color = "white") +
geom_text(aes(label = if_else(is.na(domain_score), "", round(domain_score, 0) %>% as.character())), size = 3) +
facet_wrap(~ domain, ncol = 2) +
scale_fill_gradient(low = "grey95", high = "grey20", limits = c(0, 100), na.value = "white") +
labs(
title = "Project-site domain scores by year",
subtitle = "Numbers are mean scores on a 0–100 scale",
x = "Survey year",
y = "Project site",
fill = "Score\n0–100"
)
These plots show the negative livelihood conditions directly.
project_livelihood_diagnostics <- project_site_indicators %>%
filter(indicator %in% c("financial_strain", "food_worry_any", "food_worry_often"))
project_livelihood_diagnostics %>%
mutate(across(c(pct, se, ci_low, ci_high), ~round(.x, 1))) %>%
select(project_site, district, label, n_hhs, n_valid, pct, se, ci_low, ci_high) %>%
arrange(district, project_site, label) %>%
kable(caption = "Livelihood diagnostic indicators by project site")
| project_site | district | label | n_hhs | n_valid | pct | se | ci_low | ci_high |
|---|---|---|---|---|---|---|---|---|
| Ilha Insular | Ilha de Mocambique | Household covers needs with difficulty | 1124 | 1121 | 73.1 | 1.3 | 70.5 | 75.7 |
| Ilha Insular | Ilha de Mocambique | Often worried about food | 1124 | 1123 | 36.1 | 1.4 | 33.3 | 38.9 |
| Ilha Insular | Ilha de Mocambique | Sometimes/often worried about food | 1124 | 1123 | 96.3 | 0.6 | 95.3 | 97.4 |
| Quissanga | Ilha de Mocambique | Household covers needs with difficulty | 365 | 363 | 80.7 | 2.1 | 76.7 | 84.8 |
| Quissanga | Ilha de Mocambique | Often worried about food | 365 | 364 | 46.4 | 2.6 | 41.3 | 51.6 |
| Quissanga | Ilha de Mocambique | Sometimes/often worried about food | 365 | 364 | 97.3 | 0.9 | 95.6 | 98.9 |
| Sanculo | Ilha de Mocambique | Household covers needs with difficulty | 430 | 424 | 92.2 | 1.3 | 89.7 | 94.8 |
| Sanculo | Ilha de Mocambique | Often worried about food | 430 | 428 | 40.7 | 2.4 | 36.0 | 45.3 |
| Sanculo | Ilha de Mocambique | Sometimes/often worried about food | 430 | 428 | 98.1 | 0.7 | 96.8 | 99.4 |
| Baixo Pinda | Memba | Household covers needs with difficulty | 382 | 380 | 95.5 | 1.1 | 93.4 | 97.6 |
| Baixo Pinda | Memba | Often worried about food | 382 | 381 | 24.9 | 2.2 | 20.6 | 29.3 |
| Baixo Pinda | Memba | Sometimes/often worried about food | 382 | 381 | 99.5 | 0.4 | 98.7 | 100.0 |
| Memba Sede | Memba | Household covers needs with difficulty | 559 | 547 | 58.0 | 2.1 | 53.8 | 62.1 |
| Memba Sede | Memba | Often worried about food | 559 | 551 | 4.9 | 0.9 | 3.1 | 6.7 |
| Memba Sede | Memba | Sometimes/often worried about food | 559 | 551 | 75.9 | 1.8 | 72.3 | 79.4 |
| Meculuvelane | Mogincual | Household covers needs with difficulty | 22 | 22 | 59.1 | 10.7 | 38.1 | 80.1 |
| Meculuvelane | Mogincual | Often worried about food | 22 | 22 | 4.5 | 4.5 | 0.0 | 13.5 |
| Meculuvelane | Mogincual | Sometimes/often worried about food | 22 | 22 | 100.0 | 0.0 | 100.0 | 100.0 |
| Namalungo | Mogincual | Household covers needs with difficulty | 263 | 263 | 73.4 | 2.7 | 68.0 | 78.7 |
| Namalungo | Mogincual | Often worried about food | 263 | 263 | 14.8 | 2.2 | 10.5 | 19.1 |
| Namalungo | Mogincual | Sometimes/often worried about food | 263 | 263 | 100.0 | 0.0 | 100.0 | 100.0 |
| Namige Sede | Mogincual | Household covers needs with difficulty | 308 | 308 | 51.6 | 2.9 | 46.0 | 57.2 |
| Namige Sede | Mogincual | Often worried about food | 308 | 308 | 6.5 | 1.4 | 3.7 | 9.2 |
| Namige Sede | Mogincual | Sometimes/often worried about food | 308 | 308 | 62.7 | 2.8 | 57.3 | 68.1 |
| Mahelene | Nacala Porto | Household covers needs with difficulty | 244 | 244 | 63.1 | 3.1 | 57.0 | 69.2 |
| Mahelene | Nacala Porto | Often worried about food | 244 | 244 | 34.4 | 3.0 | 28.5 | 40.4 |
| Mahelene | Nacala Porto | Sometimes/often worried about food | 244 | 244 | 86.1 | 2.2 | 81.7 | 90.4 |
| Quissimajulo | Nacala Porto | Household covers needs with difficulty | 197 | 197 | 69.0 | 3.3 | 62.6 | 75.5 |
| Quissimajulo | Nacala Porto | Often worried about food | 197 | 197 | 36.0 | 3.4 | 29.3 | 42.8 |
| Quissimajulo | Nacala Porto | Sometimes/often worried about food | 197 | 197 | 78.2 | 3.0 | 72.4 | 84.0 |
ggplot(project_livelihood_diagnostics,
aes(x = fct_reorder(project_site, pct), y = pct, fill = label)) +
geom_col(position = position_dodge(width = 0.75), width = 0.7) +
geom_errorbar(
aes(ymin = ci_low, ymax = ci_high),
position = position_dodge(width = 0.75),
width = 0.18
) +
coord_flip() +
facet_wrap(~ district, scales = "free_y") +
scale_y_continuous(limits = c(0, 100), labels = label_percent(scale = 1)) +
labs(
title = "Sustainable Livelihoods diagnostic indicators by project site",
subtitle = "Higher values here indicate more livelihood stress; error bars show approximate 95% CIs",
x = "Project site",
y = "% of valid responses",
fill = "Diagnostic indicator"
) +
theme(legend.position = "bottom")
Income is useful context but still requires more cleaning and checks for outliers, currency consistency, recall period, and inflation. Prefer medians and IQRs.
income_summary <- hhs_if %>%
summarise(
n_valid_income = sum(!is.na(g13_hh_average_income)),
min = min(g13_hh_average_income, na.rm = TRUE),
p25 = p25_na(g13_hh_average_income),
median = median_na(g13_hh_average_income),
mean = mean_na(g13_hh_average_income),
p75 = p75_na(g13_hh_average_income),
p95 = as.numeric(quantile(g13_hh_average_income, 0.95, na.rm = TRUE)),
max = max(g13_hh_average_income, na.rm = TRUE)
)
income_summary %>%
mutate(across(where(is.numeric), ~round(.x, 1))) %>%
kable(caption = "Raw average monthly household income summary")
| n_valid_income | min | p25 | median | mean | p75 | p95 | max |
|---|---|---|---|---|---|---|---|
| 6877 | 0 | 2000 | 5000 | 9420.7 | 9800 | 25000 | 9e+05 |
# Clean income variable for plotting only --------------------------------
income_plot_data <- hhs_if %>%
mutate(
income_raw = g13_hh_average_income,
income_mzn = readr::parse_number(as.character(g13_hh_average_income))
) %>%
filter(
!is.na(income_mzn),
income_mzn >= 0
)
# Use the 99th percentile as a conservative plotting cutoff.
# This removes extreme values that dominate the plot but keeps most observations.
income_cutoff_99 <- quantile(
income_plot_data$income_mzn,
probs = 0.99,
na.rm = TRUE
)
income_plot_data_clean <- income_plot_data %>%
filter(income_mzn <= income_cutoff_99)
income_outlier_summary <- tibble::tibble(
records_with_income = nrow(income_plot_data),
records_kept_for_plots = nrow(income_plot_data_clean),
records_removed_from_income_plots = nrow(income_plot_data) - nrow(income_plot_data_clean),
income_cutoff_99 = income_cutoff_99
)
income_outlier_summary %>%
knitr::kable(
caption = "Income values excluded from income plots using the 99th percentile cutoff"
)
| records_with_income | records_kept_for_plots | records_removed_from_income_plots | income_cutoff_99 |
|---|---|---|---|
| 6877 | 6811 | 66 | 75000 |
ggplot(
income_plot_data_clean,
aes(x = income_mzn)
) +
geom_histogram(
bins = 40,
fill = "grey40",
color = "white"
) +
scale_x_continuous(
labels = scales::comma
) +
labs(
title = "Reported average monthly household income",
subtitle = paste0(
"Values above the 99th percentile excluded for readability; cutoff = ",
scales::comma(round(income_cutoff_99, 0))
),
x = "Average monthly household income",
y = "HHS records"
) +
theme_minimal(base_size = 12)
project_income <- hhs_project %>%
group_by(project_site, district) %>%
summarise(
n_valid_income = sum(!is.na(g13_hh_average_income)),
median_income = median_na(g13_hh_average_income),
income_p25 = p25_na(g13_hh_average_income),
income_p75 = p75_na(g13_hh_average_income),
.groups = "drop"
)
project_income %>%
mutate(across(where(is.numeric), ~round(.x, 1))) %>%
kable(caption = "Income context by project site")
| project_site | district | n_valid_income | median_income | income_p25 | income_p75 |
|---|---|---|---|---|---|
| Baixo Pinda | Memba | 380 | 1500 | 800 | 4850 |
| Ilha Insular | Ilha de Mocambique | 1117 | 8000 | 5000 | 12000 |
| Mahelene | Nacala Porto | 244 | 7000 | 3000 | 13000 |
| Meculuvelane | Mogincual | 22 | 2820 | 2040 | 3550 |
| Memba Sede | Memba | 482 | 500 | 200 | 2000 |
| Namalungo | Mogincual | 263 | 6000 | 3800 | 7000 |
| Namige Sede | Mogincual | 308 | 10000 | 4475 | 36250 |
| Quissanga | Ilha de Mocambique | 359 | 2500 | 1900 | 8825 |
| Quissimajulo | Nacala Porto | 197 | 5000 | 2500 | 8007 |
| Sanculo | Ilha de Mocambique | 418 | 6000 | 3800 | 14475 |
income_plot_data_clean %>%
filter(!is.na(project_site)) %>%
ggplot(
aes(
x = reorder(project_site, income_mzn, median, na.rm = TRUE),
y = income_mzn
)
) +
geom_boxplot(outlier.alpha = 0.25) +
coord_flip() +
scale_y_continuous(
labels = scales::comma
) +
labs(
title = "Reported average monthly household income by project site",
subtitle = paste0(
"Values above the 99th percentile excluded for readability; cutoff = ",
scales::comma(round(income_cutoff_99, 0))
),
x = NULL,
y = "Average monthly household income"
) +
theme_minimal(base_size = 12)
income_plot_data_clean %>%
filter(!is.na(year)) %>%
ggplot(
aes(
x = factor(year),
y = income_mzn
)
) +
geom_boxplot(outlier.alpha = 0.25) +
scale_y_continuous(
labels = scales::comma
) +
labs(
title = "Reported average monthly household income by year",
subtitle = paste0(
"Values above the 99th percentile excluded for readability; cutoff = ",
scales::comma(round(income_cutoff_99, 0))
),
x = "Survey year",
y = "Average monthly household income"
) +
theme_minimal(base_size = 12)
project_site_income_year <- income_plot_data_clean %>%
filter(
!is.na(project_site),
!is.na(year),
!is.na(income_mzn)
) %>%
group_by(project_site, year) %>%
summarise(
n = n(),
median_income = median(income_mzn, na.rm = TRUE),
mean_income = mean(income_mzn, na.rm = TRUE),
q25 = quantile(income_mzn, 0.25, na.rm = TRUE),
q75 = quantile(income_mzn, 0.75, na.rm = TRUE),
.groups = "drop"
)
project_site_income_year %>%
mutate(
median_income = round(median_income, 0),
mean_income = round(mean_income, 0),
q25 = round(q25, 0),
q75 = round(q75, 0)
) %>%
arrange(project_site, year) %>%
knitr::kable(
caption = "Reported average monthly household income by project site and year"
)
| project_site | year | n | median_income | mean_income | q25 | q75 |
|---|---|---|---|---|---|---|
| Baixo Pinda | 2019 | 1 | 5000 | 5000 | 5000 | 5000 |
| Baixo Pinda | 2021 | 99 | 1000 | 994 | 700 | 1300 |
| Baixo Pinda | 2024 | 145 | 5000 | 4163 | 3000 | 6000 |
| Baixo Pinda | 2026 | 135 | 1500 | 1972 | 650 | 2450 |
| Ilha Insular | 2019 | 325 | 5500 | 7105 | 3500 | 9000 |
| Ilha Insular | 2021 | 120 | 5000 | 4966 | 3000 | 6000 |
| Ilha Insular | 2023 | 104 | 9900 | 17176 | 8225 | 24300 |
| Ilha Insular | 2025 | 557 | 9500 | 11506 | 6500 | 13000 |
| Mahelene | 2024 | 134 | 4500 | 6451 | 1500 | 8450 |
| Mahelene | 2026 | 110 | 10125 | 13330 | 6000 | 18000 |
| Meculuvelane | 2025 | 22 | 2820 | 2967 | 2040 | 3550 |
| Memba Sede | 2019 | 153 | 1200 | 2210 | 200 | 3500 |
| Memba Sede | 2021 | 190 | 400 | 566 | 200 | 600 |
| Memba Sede | 2026 | 139 | 1200 | 2322 | 400 | 2700 |
| Namalungo | 2024 | 133 | 6000 | 8130 | 6000 | 8000 |
| Namalungo | 2025 | 129 | 3900 | 5375 | 2000 | 6000 |
| Namige Sede | 2024 | 109 | 25000 | 29954 | 15000 | 40000 |
| Namige Sede | 2025 | 157 | 4600 | 5471 | 3000 | 6300 |
| Quissanga | 2021 | 85 | 3000 | 3331 | 1000 | 5000 |
| Quissanga | 2023 | 102 | 14000 | 13578 | 8562 | 18000 |
| Quissanga | 2025 | 171 | 2000 | 3206 | 1500 | 2500 |
| Quissimajulo | 2024 | 126 | 4000 | 4739 | 2000 | 6950 |
| Quissimajulo | 2026 | 71 | 8000 | 11642 | 5250 | 12500 |
| Sanculo | 2021 | 94 | 3500 | 3471 | 1850 | 5000 |
| Sanculo | 2023 | 102 | 16305 | 18022 | 10000 | 21450 |
| Sanculo | 2025 | 213 | 5200 | 9589 | 4000 | 10000 |
income_plot_data_clean %>%
filter(
!is.na(project_site),
!is.na(year),
!is.na(income_mzn)
) %>%
mutate(
project_site = stringr::str_wrap(project_site, width = 18)
) %>%
ggplot(
aes(
x = factor(year),
y = income_mzn
)
) +
geom_boxplot(
outlier.alpha = 0.15,
width = 0.65
) +
facet_wrap(~ project_site, ncol = 3, scales = "free_y") +
scale_y_continuous(labels = scales::comma) +
labs(
title = "Reported average monthly household income by project site and year",
subtitle = paste0(
"Values above the 99th percentile excluded for readability; cutoff = ",
scales::comma(round(income_cutoff_99, 0))
),
x = "Survey year",
y = "Average monthly household income"
) +
theme_minimal(base_size = 12) +
theme(
strip.text = element_text(face = "bold"),
panel.grid.minor = element_blank()
)
bootstrap_median_ci <- function(x, n_boot = 1000, conf = 0.95) {
x <- x[!is.na(x)]
if (length(x) < 5) {
return(
tibble::tibble(
median_income = median(x, na.rm = TRUE),
ci_low = NA_real_,
ci_high = NA_real_
)
)
}
boot_medians <- replicate(
n_boot,
median(sample(x, size = length(x), replace = TRUE), na.rm = TRUE)
)
alpha <- 1 - conf
tibble::tibble(
median_income = median(x, na.rm = TRUE),
ci_low = quantile(boot_medians, probs = alpha / 2, na.rm = TRUE),
ci_high = quantile(boot_medians, probs = 1 - alpha / 2, na.rm = TRUE)
)
}
# Project-site income summary by year ------------------------------------
project_site_income_year <- income_plot_data_clean %>%
filter(
!is.na(project_site),
!is.na(year),
!is.na(income_mzn)
) %>%
group_by(project_site, year) %>%
summarise(
n = n(),
mean_income = mean(income_mzn, na.rm = TRUE),
q25 = quantile(income_mzn, 0.25, na.rm = TRUE),
q75 = quantile(income_mzn, 0.75, na.rm = TRUE),
median_ci = list(bootstrap_median_ci(income_mzn)),
.groups = "drop"
) %>%
tidyr::unnest(median_ci)
ggplot(
project_site_income_year,
aes(
x = year,
y = median_income,
group = project_site,
color = project_site
)
) +
geom_errorbar(
aes(
ymin = ci_low,
ymax = ci_high
),
width = 0.12,
alpha = 0.45,
linewidth = 0.5
) +
geom_line(linewidth = 0.8) +
geom_point(aes(size = n), alpha = 0.85) +
scale_y_continuous(labels = scales::comma) +
scale_x_continuous(
breaks = sort(unique(project_site_income_year$year))
) +
scale_color_brewer(palette = "Paired") +
labs(
title = "Median reported monthly household income by project site and year",
subtitle = "Error bars show bootstrap 95% CIs for the median; point size reflects number of HHS records with non-missing income",
x = "Survey year",
y = "Median monthly household income",
color = "Project site",
size = "N"
) +
theme_minimal(base_size = 12) +
theme(
legend.position = "bottom",
panel.grid.minor = element_blank()
)
income_heatmap_data <- project_site_income_year %>%
mutate(
project_site = forcats::fct_reorder(
project_site,
median_income,
.fun = median,
na.rm = TRUE
),
label = paste0(
scales::comma(round(median_income, 0)),
"\n",
"n=",
n
),
income_scaled = scales::rescale(
median_income,
to = c(0, 1),
from = range(median_income, na.rm = TRUE)
),
label_color = if_else(income_scaled < 0.45, "white", "black")
)
ggplot(
income_heatmap_data,
aes(
x = factor(year),
y = project_site,
fill = median_income
)
) +
geom_tile(color = "white") +
geom_text(
aes(
label = label,
color = label_color
),
size = 3
) +
scale_color_identity() +
scale_fill_viridis_c(
labels = scales::comma,
option = "C"
) +
labs(
title = "Median reported monthly household income by project site and year",
subtitle = "Cell labels show median income and number of HHS records",
x = "Survey year",
y = NULL,
fill = "Median income"
) +
theme_minimal(base_size = 12) +
theme(
panel.grid = element_blank()
)
The Mozambique HHS provides a useful demonstration of the CCRF as a diagnostic framework. The likely core finding is an imbalance between the two measurable components:
Suggested manuscript language:
In the Mozambique case study, HHS results showed a marked imbalance across CCRF domains. Indicators linked to collective action and co-management were comparatively stronger, suggesting a foundation for local fisheries stewardship. In contrast, Sustainable Livelihoods indicators were consistently weaker: many households reported difficulty covering basic needs and concern about food availability. The CCRF therefore identified livelihoods resilience as a priority management gap, helping justify targeted responses such as fisheries-based microenterprises, Farmer Field Schools, TVET, poultry, aquaculture, apiculture, market linkages, savings groups, and nutrition/WASH interventions.