Enteric methane (CH4) emissions from ruminants contribute significantly to greenhouse gas emissions and represent a loss of feed energy. While Asparagopsis-based seaweeds have been widely studied for their methane-reducing potential, they are not locally available in Kenya and may be expensive or difficult to source. Screening local Kenyan non-Asparagopsis seaweeds offers the opportunity to identify affordable, locally adapted feed additives that can reduce methane emissions while improving rumen fermentation.
Similarly, KalPro, a Kenyan-made natural probiotic, may enhance rumen fermentation efficiency by stabilizing microbial populations, promoting beneficial bacteria, and improving volatile fatty acid (VFA) profiles. Evaluating the individual and combined effects of these additives using a 48-hour in vitro rumen fermentation assay allows rapid, controlled screening of their impacts on:
before moving to in vivo trials.
The primary objectives of this study were to:
Screen local Kenyan non-Asparagopsis seaweeds and the natural probiotic KalPro for their effects on rumen fermentation and methane mitigation.
Assess the effects on total gas production, methane production, and methane yield (mL CH4/g DM) during 48-hour in vitro fermentation.
Evaluate changes in rumen fermentation profiles, including total volatile fatty acids, acetate:propionate ratio, and propionate proportion.
Monitor rumen pH and digestibility to ensure additives do not adversely affect fermentation.
Determine whether combinations of seaweed and KalPro produce additive or synergistic effects on methane reduction and fermentation efficiency.
This research was conducted as part of the Africa-Australia-CGIAR-Universities Fellowship (AABCF) program at the ILRI-BecA Hub, Nairobi, Kenya.
| Treatment | Description |
|---|---|
| Control | Substrate only (no additives) |
| KalPro | Basal substrate + KalPro probiotic |
| Red SW | Red seaweed supplementation |
| Brown SW | Brown seaweed supplementation |
| Green SW | Green seaweed supplementation |
| KalPro + Red SW | KalPro with red seaweed |
| KalPro + Brown SW | KalPro with brown seaweed |
| KalPro + Green SW | KalPro with green seaweed |
| KalPro + Mix | KalPro with mixed seaweed |
# Read data - skip first row, header in second row
df <- read_excel("cherinet.xlsx", sheet = "Summary-48H", skip = 1)
# Remove blank samples and clean data
df <- df %>%
filter(!is.na(`Sample Name`) & `Sample Name` != "Blank")
# Clean time variable (extract numeric hours)
df$Time <- as.numeric(gsub("Hrs|Hr|H", "", df$`Gas Sampling Time (Hours)`))
# Display data structure
cat("Number of observations:", nrow(df), "\n")## Number of observations: 211
## Sampling time points: 6 12 24 48 hours
## Treatments: KalPro Red SW Brown SW Green SW KalPro + Red SW KalPro + Brown Sw KalPro + Green SW KalPro + Mix Control
# Calculate mean and SE across replicates
df_summary <- df %>%
group_by(Time, `Sample Name`) %>%
summarise(
n = n(),
CH4_mL_mean = mean(`CH4 (mL)`, na.rm = TRUE),
CH4_mL_se = sd(`CH4 (mL)`, na.rm = TRUE) / sqrt(n()),
CH4_yield_mean = mean(`CH4 (mL/g DM)`, na.rm = TRUE),
CH4_yield_se = sd(`CH4 (mL/g DM)`, na.rm = TRUE) / sqrt(n()),
.groups = "drop"
)
# Display summary table
df_summary %>%
kable(
caption = "Summary Statistics by Treatment and Time Point",
digits = 3,
col.names = c("Time (h)", "Treatment", "n", "CH4 (mL)", "SE", "CH4 Yield", "SE")
) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE
) %>%
scroll_box(height = "400px")| Time (h) | Treatment | n | CH4 (mL) | SE | CH4 Yield | SE |
|---|---|---|---|---|---|---|
| 6 | Brown SW | 6 | 0.914 | 0.106 | 1.864 | 0.217 |
| 6 | Control | 5 | 1.357 | 0.411 | 2.711 | 0.822 |
| 6 | Green SW | 6 | 0.888 | 0.043 | 1.810 | 0.088 |
| 6 | KalPro | 6 | 3.482 | 0.100 | 6.942 | 0.201 |
| 6 | KalPro + Brown Sw | 6 | 7.354 | 2.071 | 14.990 | 4.220 |
| 6 | KalPro + Green SW | 6 | 6.042 | 1.575 | 12.317 | 3.210 |
| 6 | KalPro + Mix | 6 | 2.465 | 0.882 | 5.025 | 1.798 |
| 6 | KalPro + Red SW | 6 | 3.049 | 0.069 | 6.218 | 0.140 |
| 6 | Red SW | 6 | 0.907 | 0.084 | 1.848 | 0.171 |
| 12 | Brown SW | 6 | 3.899 | 0.264 | 7.951 | 0.538 |
| 12 | Control | 5 | 4.293 | 0.650 | 8.571 | 1.293 |
| 12 | Green SW | 6 | 4.049 | 0.233 | 8.255 | 0.474 |
| 12 | KalPro | 6 | 10.717 | 0.467 | 21.359 | 0.904 |
| 12 | KalPro + Brown Sw | 6 | 13.625 | 2.259 | 27.774 | 4.603 |
| 12 | KalPro + Green SW | 6 | 13.407 | 2.259 | 27.332 | 4.605 |
| 12 | KalPro + Mix | 6 | 7.244 | 1.699 | 14.770 | 3.465 |
| 12 | KalPro + Red SW | 6 | 7.106 | 1.499 | 14.491 | 3.057 |
| 12 | Red SW | 6 | 4.055 | 0.257 | 8.269 | 0.522 |
| 24 | Brown SW | 6 | 9.365 | 0.171 | 19.097 | 0.347 |
| 24 | Control | 6 | 10.671 | 1.226 | 21.314 | 2.442 |
| 24 | Green SW | 6 | 8.331 | 0.310 | 16.982 | 0.627 |
| 24 | KalPro | 6 | 20.408 | 0.691 | 40.677 | 1.324 |
| 24 | KalPro + Brown Sw | 6 | 24.439 | 2.849 | 49.821 | 5.803 |
| 24 | KalPro + Green SW | 6 | 23.183 | 2.733 | 47.263 | 5.571 |
| 24 | KalPro + Mix | 6 | 14.494 | 2.648 | 29.553 | 5.400 |
| 24 | KalPro + Red SW | 6 | 11.513 | 3.185 | 23.478 | 6.495 |
| 24 | Red SW | 6 | 8.980 | 0.224 | 18.311 | 0.455 |
| 48 | Brown SW | 6 | 11.064 | 0.698 | 22.562 | 1.424 |
| 48 | Control | 6 | 13.302 | 1.456 | 26.567 | 2.895 |
| 48 | Green SW | 6 | 11.589 | 0.166 | 23.625 | 0.339 |
| 48 | KalPro | 6 | 24.804 | 0.725 | 49.446 | 1.423 |
| 48 | KalPro + Brown Sw | 6 | 26.527 | 3.675 | 54.076 | 7.488 |
| 48 | KalPro + Green SW | 6 | 24.878 | 4.114 | 50.718 | 8.386 |
| 48 | KalPro + Mix | 6 | 18.009 | 3.071 | 36.719 | 6.263 |
| 48 | KalPro + Red SW | 6 | 22.094 | 0.659 | 45.055 | 1.343 |
| 48 | Red SW | 3 | 11.091 | 0.129 | 22.610 | 0.270 |
# Custom color palette
custom_colors <- c(
"Control" = "#E63946",
"KalPro" = "#1D3557",
"Red SW" = "#E76F51",
"Brown SW" = "#8B4513",
"Green SW" = "#2A9D8F",
"KalPro + Red SW" = "#F4A261",
"KalPro + Brown SW" = "#9C6644",
"KalPro + Green SW" = "#52B788",
"KalPro + Mix" = "#7209B7"
)
# Custom shapes
custom_shapes <- c(
"Control" = 16, "KalPro" = 17, "Red SW" = 15, "Brown SW" = 18,
"Green SW" = 8, "KalPro + Red SW" = 4, "KalPro + Brown SW" = 3,
"KalPro + Green SW" = 7, "KalPro + Mix" = 9
)
# Custom line types
custom_linetypes <- c(
"Control" = "solid", "KalPro" = "solid",
"Red SW" = "dashed", "Brown SW" = "dashed", "Green SW" = "dashed",
"KalPro + Red SW" = "dotdash", "KalPro + Brown SW" = "dotdash",
"KalPro + Green SW" = "dotdash", "KalPro + Mix" = "twodash"
)
p1 <- ggplot(df_summary, aes(x = factor(Time), y = CH4_mL_mean,
color = `Sample Name`, shape = `Sample Name`,
linetype = `Sample Name`, group = `Sample Name`)) +
geom_errorbar(aes(ymin = CH4_mL_mean - CH4_mL_se, ymax = CH4_mL_mean + CH4_mL_se),
width = 0.15, linewidth = 0.6, alpha = 0.7,
position = position_dodge(width = 0.4)) +
geom_line(linewidth = 1.3, position = position_dodge(width = 0.4)) +
geom_point(size = 5, position = position_dodge(width = 0.4), stroke = 1.2) +
scale_color_manual(values = custom_colors) +
scale_shape_manual(values = custom_shapes) +
scale_linetype_manual(values = custom_linetypes) +
scale_y_continuous(expand = expansion(mult = c(0.02, 0.08))) +
labs(
x = "\nIncubation Time (Hours)",
y = expression(CH[4]~Production~(mL)~"\n"),
title = "Absolute Methane Production During In Vitro Fermentation\n",
subtitle = "Effect of Kenyan seaweeds and KalPro probiotic on cumulative CH4 output\n",
color = "Treatment", shape = "Treatment", linetype = "Treatment"
) +
theme_minimal(base_size = 15) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5, size = 20),
plot.subtitle = element_text(hjust = 0.5, color = "gray40", size = 14),
legend.position = "bottom",
legend.title = element_text(face = "bold", size = 13),
legend.text = element_text(size = 11),
legend.key.width = unit(2, "cm"),
panel.grid.minor = element_blank(),
axis.title = element_text(face = "bold", size = 14),
plot.margin = margin(20, 30, 20, 20)
) +
guides(color = guide_legend(nrow = 3, byrow = TRUE, override.aes = list(size = 4, linewidth = 1.2)))
print(p1)Figure 1: Absolute methane production (mL) over 48-hour incubation period.
p2 <- ggplot(df_summary, aes(x = factor(Time), y = CH4_yield_mean,
color = `Sample Name`, shape = `Sample Name`,
linetype = `Sample Name`, group = `Sample Name`)) +
geom_errorbar(aes(ymin = CH4_yield_mean - CH4_yield_se, ymax = CH4_yield_mean + CH4_yield_se),
width = 0.15, linewidth = 0.6, alpha = 0.7,
position = position_dodge(width = 0.4)) +
geom_line(linewidth = 1.3, position = position_dodge(width = 0.4)) +
geom_point(size = 5, position = position_dodge(width = 0.4), stroke = 1.2) +
scale_color_manual(values = custom_colors) +
scale_shape_manual(values = custom_shapes) +
scale_linetype_manual(values = custom_linetypes) +
scale_y_continuous(expand = expansion(mult = c(0.02, 0.08))) +
labs(
x = "\nIncubation Time (Hours)",
y = expression(CH[4]~Yield~(mL/g~DM)~"\n"),
title = "Methane Yield During In Vitro Fermentation\n",
subtitle = "Effect of Kenyan seaweeds and KalPro probiotic on CH4 per gram dry matter\n",
color = "Treatment", shape = "Treatment", linetype = "Treatment"
) +
theme_minimal(base_size = 15) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5, size = 20),
plot.subtitle = element_text(hjust = 0.5, color = "gray40", size = 14),
legend.position = "bottom",
legend.title = element_text(face = "bold", size = 13),
legend.text = element_text(size = 11),
legend.key.width = unit(2, "cm"),
panel.grid.minor = element_blank(),
axis.title = element_text(face = "bold", size = 14),
plot.margin = margin(20, 30, 20, 20)
) +
guides(color = guide_legend(nrow = 3, byrow = TRUE, override.aes = list(size = 4, linewidth = 1.2)))
print(p2)Figure 2: Methane yield (mL/g DM) over 48-hour incubation period.
ggsave("plots/02_CH4_yield_timecourse.png", plot = p2, width = 14, height = 9, dpi = 300, bg = "white")df_final <- data.frame(
Treatment = c("Control", "KalPro", "Red SW", "Brown SW", "Green SW",
"KalPro + Red SW", "KalPro + Brown SW", "KalPro + Green SW", "KalPro + Mix"),
CH4_yield = c(50.68, 48.12, 22.33, 22.17, 24.24, 44.65, 50.03, 47.77, 27.75),
SD = c(0.07, 0.04, 0.03, 0.04, 0.03, 0.04, 0.03, 0.04, 0.03)
)
df_final <- df_final %>%
mutate(
Reduction_pct = round((50.68 - CH4_yield) / 50.68 * 100, 1),
Category = case_when(
Treatment %in% c("Red SW", "Brown SW", "Green SW") ~ "Seaweed Only",
Treatment == "KalPro + Mix" ~ "Mixed Seaweed",
Treatment %in% c("Control", "KalPro") ~ "Control",
TRUE ~ "KalPro + Seaweed"
),
Category = factor(Category, levels = c("Control", "Seaweed Only", "Mixed Seaweed", "KalPro + Seaweed"))
)
df_final$Treatment <- reorder(df_final$Treatment, df_final$CH4_yield)p3 <- ggplot(df_final, aes(x = Treatment, y = CH4_yield, fill = Category)) +
geom_col(width = 0.7, color = "gray30", linewidth = 0.4) +
geom_errorbar(aes(ymin = CH4_yield - SD, ymax = CH4_yield + SD),
width = 0.2, linewidth = 0.7) +
geom_text(aes(label = paste0(round(Reduction_pct, 0), "%")),
hjust = -0.3, size = 4.5, fontface = "bold") +
scale_fill_manual(
values = c("Control" = "#E63946", "Seaweed Only" = "#2A9D8F",
"Mixed Seaweed" = "#7209B7", "KalPro + Seaweed" = "#F4A261"),
name = "Treatment Category"
) +
scale_y_continuous(expand = expansion(mult = c(0, 0.18))) +
coord_flip() +
labs(
x = NULL,
y = expression(bold("\n"~CH[4]~Yield~(mL/g~DM))),
title = "Effect of Kenyan Seaweeds and KalPro on Methane Yield at 48 Hours\n",
subtitle = "Percentage values indicate reduction compared to Control\n"
) +
theme_minimal(base_size = 15) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5, size = 20),
plot.subtitle = element_text(hjust = 0.5, color = "gray40", size = 14),
axis.title.x = element_text(face = "bold", size = 14),
axis.text.y = element_text(face = "bold", size = 13),
legend.position = "bottom",
legend.title = element_text(face = "bold", size = 13),
panel.grid.major.y = element_blank(),
plot.margin = margin(20, 40, 20, 20)
)
print(p3)Figure 3: Methane yield at 48 hours across all treatments.
ggsave("plots/03_CH4_yield_barplot.png", plot = p3, width = 12, height = 9, dpi = 300, bg = "white")df_vfa <- data.frame(
Sample = c("Blank", "Blank", "KalPro", "KalPro", "Red SW", "Red SW",
"Brown SW", "Brown SW", "Green SW", "Green SW",
"KalPro + Red SW", "KalPro + Red SW", "KalPro + Brown SW", "KalPro + Brown SW",
"KalPro + Green SW", "KalPro + Green SW", "KalPro + Mix", "KalPro + Mix",
"Control", "Control"),
Acetic = c(2.16, 1.93, 6.59, 6.70, 5.28, 5.13, 5.28, 5.25, 4.47, 5.32,
6.93, 6.74, 6.70, 7.38, 6.80, 7.26, 5.46, 6.78, 5.29, 5.24),
Propionic = c(-0.27, -0.43, 1.92, 1.83, 1.09, 0.87, 1.12, 1.04, 0.62, 1.16,
2.04, 1.76, 1.59, 1.36, 1.63, 1.31, 0.90, 1.39, 0.60, 0.71),
Butyric = c(-0.44, -0.57, 0.06, -0.06, -0.25, -0.25, -0.21, -0.24, -0.35, -0.22,
-0.04, -0.07, -0.06, 0.27, -0.01, 0.19, -0.27, 0.02, -0.23, -0.22)
)
df_vfa_mean <- df_vfa %>%
filter(Sample != "Blank") %>%
group_by(Sample) %>%
summarise(
Acetic_mean = mean(Acetic), Propionic_mean = mean(Propionic), Butyric_mean = mean(Butyric),
.groups = "drop"
) %>%
mutate(AP_ratio = round(Acetic_mean / Propionic_mean, 2))df_vfa_long <- df_vfa_mean %>%
pivot_longer(cols = c(Acetic_mean, Propionic_mean, Butyric_mean),
names_to = "VFA", values_to = "Concentration") %>%
mutate(
VFA = case_when(
VFA == "Acetic_mean" ~ "Acetic Acid",
VFA == "Propionic_mean" ~ "Propionic Acid",
VFA == "Butyric_mean" ~ "Butyric Acid"
),
VFA = factor(VFA, levels = c("Acetic Acid", "Propionic Acid", "Butyric Acid"))
)
sample_order <- df_vfa_mean %>% arrange(desc(Acetic_mean)) %>% pull(Sample)
df_vfa_long$Sample <- factor(df_vfa_long$Sample, levels = sample_order)
p4 <- ggplot(df_vfa_long, aes(x = Sample, y = Concentration, fill = VFA)) +
geom_col(position = position_dodge(width = 0.8), width = 0.7, color = "gray30", linewidth = 0.3) +
scale_fill_manual(
values = c("Acetic Acid" = "#3498db", "Propionic Acid" = "#e74c3c", "Butyric Acid" = "#2ecc71"),
name = "Volatile Fatty Acid"
) +
scale_y_continuous(expand = expansion(mult = c(0.05, 0.1))) +
labs(
x = NULL, y = "\nConcentration (mmol/L)\n",
title = "Volatile Fatty Acid Profile by Treatment\n",
subtitle = "Comparison of Acetic, Propionic, and Butyric acid production after 48-hour fermentation\n"
) +
theme_minimal(base_size = 15) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5, size = 20),
plot.subtitle = element_text(hjust = 0.5, color = "gray40", size = 14),
axis.title.y = element_text(face = "bold", size = 14),
axis.text.x = element_text(face = "bold", size = 11, angle = 45, hjust = 1),
legend.position = "bottom",
legend.title = element_text(face = "bold", size = 13),
panel.grid.major.x = element_blank(),
plot.margin = margin(20, 30, 20, 20)
)
print(p4)Figure 4: Comparison of major VFA concentrations across treatments.
| Treatment | CHâ‚„ Yield (mL/g DM) | Reduction |
|---|---|---|
| Brown SW | 22.17 | 56.2% |
| Red SW | 22.33 | 55.9% |
| Green SW | 24.24 | 52.2% |
| KalPro + Mix | 27.75 | 45.2% |
Local Kenyan seaweeds (Brown, Red, Green) showed remarkable methane reduction potential (52-56%), comparable to Asparagopsis species.
Brown seaweed was the most effective single additive with 56.2% methane reduction.
KalPro + Red SW combination showed the lowest A:P ratio, indicating improved fermentation efficiency.
Results strongly support further in vivo evaluation of local Kenyan seaweeds and KalPro for sustainable methane mitigation.
Report generated: 2026-01-11 11:56:30
AABCF Fellowship | ILRI-BecA Hub | International Livestock Research Institute | Nairobi, Kenya