Summary

This short analysis explores the overlap between fishing and farming among surveyed households in Honduras. We start by quickly answering the core question for the entire dataset across all provinces and years: What percentage of fishers also engage in farming? We then outline the availability of household survey data by province and year. Following that, we examine the composition of household income sources at the national level, as well as disaggregated by province and by year. Finally, we analyze the extent to which fishing households also engage in farming, presenting results through a series of pie charts for the full sample, by province, and by year.

The raw dataset used for this analysis can be accessed here.


merged_hhs_hon <- merged_hhs %>% 
  filter(g1_country == "HND")


# Create a vector of the income percentage columns
income_cols <- c(
  "g4_hh_average_income_source_a_income_farming",
  "g4_hh_average_income_source_b_income_harvesting",
  "g4_hh_average_income_source_c_income_fishing_artisanal",
  "g4_hh_average_income_source_d_income_fishing_aquaculture",
  "g4_hh_average_income_source_e_income_buying_trading",
  "g4_hh_average_income_source_f_income_processing",
  "g4_hh_average_income_source_g_income_extraction",
  "g4_hh_average_income_source_h_income_tourism",
  "g4_hh_average_income_source_i_income_other_wage",
  "g4_hh_average_income_source_j_income_industrial",
  "g4_hh_average_income_source_k_income_other"
)

# Create a new dataframe with a total income contribution column
merged_hhs_hon_with_sum <- merged_hhs_hon %>%
  mutate(across(all_of(income_cols), ~ as.numeric(.))) %>%
  mutate(total_income_pct = rowSums(select(., all_of(income_cols)), na.rm = TRUE))


sum(merged_hhs_hon_with_sum$total_income_pct != 100) #Great: just 60 non 100 observations!
#> [1] 60

merged_hhs_hon_clean <- merged_hhs_hon_with_sum %>%
  filter(total_income_pct == 100)

# Keep and rename the specified columns
merged_hhs_hon_source <- merged_hhs_hon_clean %>%
  select(
    country = g1_country,
    year,
    province = merged_hhs_province,
    municipality = merged_hhs_municipality,
    community = merged_hhs_community,
    all_of(income_cols)
  )

# Add fisher and farmer flags
df_fisher_farming <- merged_hhs_hon_source %>%
  mutate(
    is_fisher = g4_hh_average_income_source_c_income_fishing_artisanal > 0 |
                g4_hh_average_income_source_j_income_industrial > 0,
    is_farmer = g4_hh_average_income_source_a_income_farming > 0
  )

# Total observations in the dataset
total_obs <- nrow(df_fisher_farming)

# Count total fishers and fishers who also farm
total_fishers <- sum(df_fisher_farming$is_fisher, na.rm = TRUE)
fishers_also_farmers <- sum(df_fisher_farming$is_fisher & df_fisher_farming$is_farmer, na.rm = TRUE)

# Percentages
fisher_share_of_sample <- total_fishers / total_obs * 100
farmers_among_fishers_pct <- fishers_also_farmers / total_fishers * 100


# write.csv(merged_hhs_hon_source, "hhs_honduras_clean.csv", row.names = FALSE)

total_fishers
#> [1] 2823
fishers_also_farmers
#> [1] 830
round(farmers_among_fishers_pct, 1)
#> [1] 29.4

Do Honduras Fishers Also Farm?

Short answer: Out of the 4,829 households surveyed in Honduras from 2019 to 2025, 2,823 were identified as fishers, representing 58% of the total sample. Among them, 830 households also reported income from farming activities—this means that 29% of fishers also farm.


Disaggregated Findings

There is substantial variation across provinces. In Colón, 40% of fishers also report income from farming, while in Cortés the figure is slightly lower at 20%. In Atlántida, 29% of fishers engage in both fishing and farming, whereas in Islas de la Bahía, only 3% of fishers report any farming income (For details, see section ‘Fishing and Farming Households’ → ‘Provincial Breakdown’).

It’s important to note that the year-level disaggregation of results should be interpreted with caution. As shown in the summary table below, different provinces were sampled in different years, making it difficult to distinguish year effects from geographic differences. The observed year-to-year patterns largely reflect changes in where data was collected, rather than temporal shifts in household activity (For details, see section ‘Fishing and Farming Households’ → ‘Yearly Breakdown’).


Details and Assumptions

  • This analysis is based on responses to a survey question about the share of household income coming from different sources. Because of this, the data likely underestimates fishing or farming done solely for household consumption, as it only captures income-generating activities.

  • A household was classified as engaged in fishing if it reported any income from artisanal or industrial fishing. Similarly, a household was classified as engaged in farming if it reported income from farming activities. These classifications are intentionally inclusive: even a small income share from one of these activities was sufficient for a household to be included.


Available Data Overview

merged_hhs_hon_source %>%
  count(province, year) %>%
  pivot_wider(
    names_from = year,
    values_from = n,
    values_fill = 0
  ) %>%
  rename(Province = province) %>%
  select(Province, `2019`, `2021`, `2023`, `2024`, `2025`) %>%
  kable("html", caption = "Number of Observations per Province per Year") %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = TRUE,
    position = "center"
  ) %>%
  column_spec(1, width = "160px")  # Only the first column wider
Number of Observations per Province per Year
Province 2019 2021 2023 2024 2025
Atlántida 0 0 288 288 16
Colón 0 1122 275 1169 0
Cortés 559 0 0 632 0
Islas de la Bahía 205 0 0 275 0

Income Composition by Source

National Overview

# Step 1: Recode labels (same as your global definition)
income_labels <- c(
  "Farming",
  "Forest Harvesting",
  "Artisanal Fishing",
  "Aquaculture",
  "Fish Buying/Trading",
  "Fish Processing",
  "Marine Extraction",
  "Marine Tourism",
  "Other Wage Labor",
  "Industrial Fishing",
  "Other"
)

# Step 2: Long-format and summarise for Honduras
df_income_long <- merged_hhs_hon_source %>%
  select(all_of(income_cols)) %>%
  mutate(across(everything(), as.numeric)) %>%
  filter(if_any(everything(), ~ !is.na(.))) %>%
  pivot_longer(everything(), names_to = "source", values_to = "income_pct") %>%
  mutate(source = recode(source, !!!setNames(income_labels, income_cols))) %>%
  group_by(source) %>%
  summarise(total_pct = sum(income_pct, na.rm = TRUE), .groups = "drop") %>%
  mutate(prop = total_pct / sum(total_pct)) %>%
  arrange(desc(prop))

# Step 3: Set factor levels based on ordering by prop
df_income_long$source <- factor(df_income_long$source, levels = df_income_long$source)

# Step 4: Define custom color palette
source_colors <- c(
  "Artisanal Fishing"    = "#A6CEE3", 
  "Farming"              = "#B2DF8A", 
  "Other Wage Labor"     = "#CAB2D6", 
  "Other"                = "#FDBF6F",  
  "Fish Buying/Trading"  = "#FB9A99", 
  "Fish Processing"      = "#E31A1C", 
  "Industrial Fishing"   = "#1F78B4", 
  "Aquaculture"          = "#FF7F00",  
  "Forest Harvesting"    = "#33A02C", 
  "Marine Tourism"       = "#6A3D9A",  
  "Marine Extraction"    = "#FFFF99"  
)

# Step 5: Reorder colors to match bar order
ordered_colors <- source_colors[names(source_colors) %in% levels(df_income_long$source)]
ordered_colors <- ordered_colors[match(levels(df_income_long$source), names(ordered_colors))]

# Step 6: Create legend labels
legend_labels <- paste0(levels(df_income_long$source), " (", scales::percent(df_income_long$prop, accuracy = 1), ")")
n_total_hon <- nrow(merged_hhs_hon_source)

# Step 7: Create the plot
ggplot(df_income_long, aes(x = source, y = prop, fill = source)) +
  geom_col(width = 0.8) +
  geom_text(aes(label = scales::percent(prop, accuracy = 1)),
            vjust = -0.3, size = 3.5, color = "black") +
  scale_y_continuous(labels = scales::percent_format(), expand = expansion(mult = c(0, 0.1))) +
  scale_fill_manual(
    values = ordered_colors,
    labels = legend_labels
  ) +
  labs(
    title = paste0("Income Share by Source in Honduras (n = ", formatC(n_total_hon, format = "d", big.mark = ","), ")"),
    x = "",
    y = "Proportion of Reported Income Sources",
    fill = "Income Source"
  ) +
  theme_minimal() +
  theme(
    legend.position = "right",
    legend.title = element_text(face = "bold"),
    legend.text = element_text(size = 10),
    axis.text.x = element_text(angle = 45, hjust = 1),
    plot.title = element_text(face = "bold")
  )

Provincial Breakdown

# Create long-format dataset with province included
df_income_long_province <- merged_hhs_hon_source %>%
  select(province, all_of(income_cols)) %>%
  mutate(across(all_of(income_cols), as.numeric)) %>%
  filter(if_any(all_of(income_cols), ~ !is.na(.))) %>%
  pivot_longer(cols = all_of(income_cols), names_to = "source", values_to = "income_pct") %>%
  mutate(source = recode(source, !!!setNames(income_labels, income_cols))) %>%
  group_by(province, source) %>%
  summarise(total_pct = sum(income_pct, na.rm = TRUE), .groups = "drop") %>%
  group_by(province) %>%
  mutate(prop = total_pct / sum(total_pct)) %>%
  arrange(province, desc(prop)) %>%
  mutate(source = factor(source, levels = income_labels))  # to keep source order consistent

province_sample_sizes <- merged_hhs_hon_source %>%
  count(province, name = "n")

df_income_long_province <- df_income_long_province %>%
  left_join(province_sample_sizes, by = "province") %>%
  mutate(province_label = paste0(province, " (n = ", n, ")"))

# Ensure factor levels match
df_income_long_province <- df_income_long_province %>%
  mutate(source = factor(source, levels = income_labels))

source_colors <- c(
  "Artisanal Fishing"    = "#A6CEE3", 
  "Other"                = "#FDBF6F",  
  "Farming"              = "#B2DF8A", 
  "Other Wage Labor"     = "#CAB2D6", 
  "Fish Buying/Trading"  = "#FB9A99", 
  "Fish Processing"      = "#E31A1C", 
  "Industrial Fishing"   = "#1F78B4", 
  "Aquaculture"          = "#FF7F00",  
  "Marine Tourism"       = "#6A3D9A",  
  "Forest Harvesting"    = "#33A02C", 
  "Marine Extraction"    = "#FFFF99"  
)

# Create the plot
ggplot(df_income_long_province, aes(x = source, y = prop, fill = source)) +
  geom_col(width = 0.8) +
  geom_text(aes(label = scales::percent(prop, accuracy = 1)),
            vjust = -0.3, size = 3, color = "black") +
  facet_wrap(~ province_label) +
  scale_y_continuous(labels = scales::percent_format(), expand = expansion(mult = c(0, 0.1))) +
  scale_fill_manual(values = source_colors)+
  labs(
    title = "Income Share by Source and Province",
    x = "Income Source",
    y = "Proportion of Total Reported Income",
    fill = "Income Source"
  ) +
  theme_minimal() +
  theme(
    legend.position = "bottom",
    legend.title = element_text(face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    strip.text = element_text(face = "bold"),
    panel.border = element_rect(color = "black", fill = NA, linewidth = 0.8)
  )

Yearly Breakdown

# Create long-format dataset with year included
df_income_long_year <- merged_hhs_hon_source %>%
  select(year, all_of(income_cols)) %>%
  mutate(across(all_of(income_cols), as.numeric)) %>%
  filter(if_any(all_of(income_cols), ~ !is.na(.))) %>%
  pivot_longer(cols = all_of(income_cols), names_to = "source", values_to = "income_pct") %>%
  mutate(source = recode(source, !!!setNames(income_labels, income_cols))) %>%
  group_by(year, source) %>%
  summarise(total_pct = sum(income_pct, na.rm = TRUE), .groups = "drop") %>%
  group_by(year) %>%
  mutate(prop = total_pct / sum(total_pct)) %>%
  arrange(year, desc(prop)) %>%
  mutate(source = factor(source, levels = income_labels))

# Get sample size by year
year_sample_sizes <- merged_hhs_hon_source %>%
  count(year, name = "n")

# Add year (n = ...) label
df_income_long_year <- df_income_long_year %>%
  left_join(year_sample_sizes, by = "year") %>%
  mutate(year_label = paste0("Year ", year, " (n = ", n, ")"))

# Ensure factor levels match again
df_income_long_year <- df_income_long_year %>%
  mutate(source = factor(source, levels = income_labels))

# Define consistent source colors manually
source_colors <- c(
  "Artisanal Fishing"    = "#A6CEE3", 
  "Other"                = "#FDBF6F",  
  "Farming"              = "#B2DF8A", 
  "Other Wage Labor"     = "#CAB2D6", 
  "Fish Buying/Trading"  = "#FB9A99", 
  "Fish Processing"      = "#E31A1C", 
  "Industrial Fishing"   = "#1F78B4", 
  "Aquaculture"          = "#FF7F00",  
  "Marine Tourism"       = "#6A3D9A",  
  "Forest Harvesting"    = "#33A02C", 
  "Marine Extraction"    = "#FFFF99"  
)

# Create the plot faceted by year
ggplot(df_income_long_year, aes(x = source, y = prop, fill = source)) +
  geom_col(width = 0.8) +
  geom_text(aes(label = scales::percent(prop, accuracy = 1)),
            vjust = -0.3, size = 3, color = "black") +
  facet_wrap(~ year_label) +
  scale_y_continuous(labels = scales::percent_format(), expand = expansion(mult = c(0, 0.1))) +
  scale_fill_manual(values = source_colors) +
  labs(
    title = "Income Share by Source and Year",
    x = "Income Source",
    y = "Proportion of Total Reported Income",
    fill = "Income Source"
  ) +
  theme_minimal() +
  theme(
    legend.position = "bottom",
    legend.title = element_text(face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    strip.text = element_text(face = "bold"),
    panel.border = element_rect(color = "black", fill = NA, linewidth = 0.8)
  )


Fishing and Farming Households

National Overview

# Define is_fisher and is_farmer up front
df_national <- merged_hhs_hon_source %>%
  mutate(
    is_fisher = if_else(
      coalesce(g4_hh_average_income_source_c_income_fishing_artisanal, 0) > 0 |
      coalesce(g4_hh_average_income_source_j_income_industrial, 0) > 0,
      TRUE, FALSE, missing = FALSE
    ),
    is_farmer = if_else(
      coalesce(g4_hh_average_income_source_a_income_farming, 0) > 0,
      TRUE, FALSE, missing = FALSE
    )
  )

# --- WHOLE POPULATION PIE ---
df_full <- df_national %>%
  mutate(
    group = if_else(is_fisher, "Fishers", "Non-Fishers")
  ) %>%
  count(group) %>%
  mutate(
    prop = n / sum(n),
    label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
  )

n_total <- sum(df_full$n)

pie1 <- ggplot(df_full, aes(x = "", y = prop, fill = group)) +
  geom_col(width = 1, color = "white") +
  coord_polar(theta = "y") +
  geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 5) +
  scale_fill_manual(values = c("Fishers" = "#6baed6", "Non-Fishers" = "#fb6a4a")) +
  labs(title = paste0("Whole Population in Honduras (n = ", n_total, ")")) +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
    legend.position = "none"
  )

# --- FISHING POPULATION PIE ---
df_fishers <- df_national %>%
  filter(is_fisher) %>%
  mutate(
    group = if_else(is_farmer, "Fishers who also farm", "Fishers only")
  ) %>%
  count(group) %>%
  mutate(
    prop = n / sum(n),
    label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
  )

n_fishers <- sum(df_fishers$n)

pie2 <- ggplot(df_fishers, aes(x = "", y = prop, fill = group)) +
  geom_col(width = 1, color = "white") +
  coord_polar(theta = "y") +
  geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 3.5) +
  scale_fill_manual(values = c("Fishers only" = "#6baed6", "Fishers who also farm" = "#B2DF8A")) +
  labs(title = paste0("Fishing Population (n = ", n_fishers, ")")) +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 11),
    legend.position = "none"
  )

# --- Combine and display ---
ggdraw() +
  draw_plot(pie1, x = -0.2, y = 0, width = 1, height = 1) +         
  draw_plot(pie2, x = 0.44, y = 0.1, width = 0.6, height = 0.6)

Provincial Breakdown


# List of provinces
provinces <- unique(na.omit(merged_hhs_hon_source$province))

# Loop through each province and display plot
for (prov in provinces) {
  
  df_prov <- merged_hhs_hon_source %>%
    filter(province == prov) %>%
    mutate(
      is_fisher = if_else(
        coalesce(g4_hh_average_income_source_c_income_fishing_artisanal, 0) > 0 |
        coalesce(g4_hh_average_income_source_j_income_industrial, 0) > 0,
        TRUE, FALSE, missing = FALSE
      ),
      is_farmer = if_else(
        coalesce(g4_hh_average_income_source_a_income_farming, 0) > 0,
        TRUE, FALSE, missing = FALSE
      )
    )
  
  ## --- WHOLE POPULATION PIE ---
  df_full <- df_prov %>%
    mutate(
      group = if_else(is_fisher, "Fishers", "Non-Fishers")
    ) %>%
    count(group) %>%
    mutate(
      prop = n / sum(n),
      label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
    )

  n_total <- sum(df_full$n)

  pie1 <- ggplot(df_full, aes(x = "", y = prop, fill = group)) +
    geom_col(width = 1, color = "white") +
    coord_polar(theta = "y") +
    geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 5) +
    scale_fill_manual(values = c("Fishers" = "#6baed6", "Non-Fishers" = "#fb6a4a")) +
    labs(title = paste0("Whole Population in ", prov, " (n = ", n_total, ")")) +
    theme_void() +
    theme(
      plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
      legend.position = "none"
    )
  
  ## --- FISHERS ONLY PIE ---
  df_fishers <- df_prov %>%
    filter(is_fisher) %>%
    mutate(
      group = if_else(is_farmer, "Fishers who also farm", "Fishers only")
    ) %>%
    count(group) %>%
    mutate(
      prop = n / sum(n),
      label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
    )

  n_fishers <- sum(df_fishers$n)

  pie2 <- ggplot(df_fishers, aes(x = "", y = prop, fill = group)) +
    geom_col(width = 1, color = "white") +
    coord_polar(theta = "y") +
    geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 4) +
    scale_fill_manual(values = c("Fishers only" = "#6baed6", "Fishers who also farm" = "#B2DF8A")) +
    labs(title = paste0("Fishing Population (n = ", n_fishers, ")")) +
    theme_void() +
    theme(
      plot.title = element_text(hjust = 0.5, face = "bold", size = 11),
      legend.position = "none"
    )

  # Combine and display
  final_plot <- cowplot::ggdraw() +
    draw_plot(pie1, x = -0.2, y = 0, width = 1, height = 1) +
    draw_plot(pie2, x = 0.44, y = 0.1, width = 0.6, height = 0.6)

  print(final_plot)
}

Yearly Breakdown

# List of years
years <- unique(na.omit(merged_hhs_hon_source$year))

# Loop through each year and display plot
for (yr in years) {
  
  df_year <- merged_hhs_hon_source %>%
    filter(year == yr) %>%
    mutate(
      is_fisher = if_else(
        coalesce(g4_hh_average_income_source_c_income_fishing_artisanal, 0) > 0 |
        coalesce(g4_hh_average_income_source_j_income_industrial, 0) > 0,
        TRUE, FALSE, missing = FALSE
      ),
      is_farmer = if_else(
        coalesce(g4_hh_average_income_source_a_income_farming, 0) > 0,
        TRUE, FALSE, missing = FALSE
      )
    )
  
  # --- WHOLE POPULATION PIE ---
  df_full <- df_year %>%
    mutate(
      group = if_else(is_fisher, "Fishers", "Non-Fishers")
    ) %>%
    count(group) %>%
    mutate(
      prop = n / sum(n),
      label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
    )
  
  n_total <- sum(df_full$n)
  
  pie1 <- ggplot(df_full, aes(x = "", y = prop, fill = group)) +
    geom_col(width = 1, color = "white") +
    coord_polar(theta = "y") +
    geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 5) +
    scale_fill_manual(values = c("Fishers" = "#6baed6", "Non-Fishers" = "#fb6a4a")) +
    labs(title = paste0("Whole Population in ", yr, " (n = ", n_total, ")")) +
    theme_void() +
    theme(
      plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
      legend.position = "none"
    )
  
  # --- FISHING POPULATION PIE ---
  df_fishers <- df_year %>%
    filter(is_fisher) %>%
    mutate(
      group = if_else(is_farmer, "Fishers who also farm", "Fishers only")
    ) %>%
    count(group) %>%
    mutate(
      prop = n / sum(n),
      label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
    )
  
  n_fishers <- sum(df_fishers$n)
  
  pie2 <- ggplot(df_fishers, aes(x = "", y = prop, fill = group)) +
    geom_col(width = 1, color = "white") +
    coord_polar(theta = "y") +
    geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 4) +
    scale_fill_manual(values = c("Fishers only" = "#6baed6", "Fishers who also farm" = "#B2DF8A")) +
    labs(title = paste0("Fishing Population (n = ", n_fishers, ")")) +
    theme_void() +
    theme(
      plot.title = element_text(hjust = 0.5, face = "bold", size = 11),
      legend.position = "none"
    )
  
  # Combine and display
  final_plot <- ggdraw() +
    draw_plot(pie1, x = -0.2, y = 0, width = 1, height = 1) +
    draw_plot(pie2, x = 0.44, y = 0.1, width = 0.6, height = 0.6)
  
  print(final_plot)
}