Code
library(tidyverse)
library(here)
library(dplyr)
library(gt)
library(knitr)
library(ggplot2)Faecal sludge characteristics play a critical role in the design and performance of sanitation treatment and resource recovery systems. Faecal sludge (FS) characterization is a critical first step in FS management, providing the basis for designing and sizing treatment plant components and reducing associated environmental and public health risks (Ahmed et al. 2019; Ouedraogo et al. 2023). Understanding the organic, nutrient, and solids content of pit latrine faecal sludge is therefore essential for informing treatment strategies and reuse potential. This study explores the physicochemical characteristics of pit latrine faecal sludge in Kampala, with a focus on organic load, nutrients, and solids fractions, using secondary data from field measurements.
The analysis was based on a CSV dataset containing faecal sludge characteristics collected from pit latrines in Kampala (Englund et al. 2020) . Raw data were imported into R and processed by removing metadata rows, selecting relevant physicochemical parameters, and converting character values to numeric format while retaining missing values. The dataset was then filtered to include pit latrine samples only. Descriptive statistics (mean, median, and standard deviation) were calculated for key parameters, and exploratory visualisations were produced to examine distributions and relationships between variables. All data processing and analysis were conducted using R and tidyverse packages.
library(tidyverse)
library(here)
library(dplyr)
library(gt)
library(knitr)
library(ggplot2)raw_data <- read_csv(here::here("data/raw/FS-kampala-data.csv"))raw_data <- read_delim(
here("data/raw/FS-kampala-data.csv"),
delim = ";",
show_col_types = FALSE
)
#Cleaning raw data
processed_data <- raw_data |>
select(CoTyp, "COD g/L":last_col()) |>
slice(-1) |>
mutate(
across(
-CoTyp,
readr::parse_number
)
)
write_csv(
processed_data,
here("data/processed/FS_kampala_processed.csv")
)pit_data <- processed_data |>
filter(CoTyp == "Pit latrine") |>
select(-CoTyp, -"COD mg/L")Pit latrine faecal sludge exhibited substantial variability across all measured physicochemical parameters as shown in Table 1. Organic matter concentrations, represented by chemical oxygen demand (COD) and volatile solids (VS), showed wide ranges and high standard deviations, indicating heterogeneous sludge composition across samples. Median values were generally lower than mean values, suggesting right-skewed distributions influenced by high-strength samples. Solids-related parameters (TS, TSS, VS, and VSS) also displayed pronounced dispersion, reflecting differences in pit usage, moisture content, accumulation processes, and potential dilution effects. Nutrient concentrations, particularly total nitrogen (TN) and total phosphorus (TP), were highly variable, highlighting non-uniform nutrient accumulation and transformation within pit latrines.
summary_tbl <- pit_data |>
select(where(is.numeric)) |>
pivot_longer(
everything(),
names_to = "parameter",
values_to = "value"
) |>
group_by(parameter) |>
summarise(
mean = mean(value, na.rm = TRUE),
median = median(value, na.rm = TRUE),
sd = sd(value, na.rm = TRUE),
) |>
pivot_longer(
-parameter,
names_to = "stat",
values_to = "value"
) |>
pivot_wider(
names_from = parameter,
values_from = value
)summary_tbl |>
mutate(
stat = case_when(
stat == "mean" ~ "Mean",
stat == "median" ~ "Median",
stat == "sd" ~ "SD",
TRUE ~ stat
)
) |>
gt(rowname_col = "stat") |>
tab_stubhead(label = "Parameters") |>
cols_label(
"Fixed solids g/L" = "FS g/L",
"NH4N mg/L" = "NH₄–N mg/L",
"Nitrate mg/L" = "NO₃⁻N mg/L",
"PO4P mg/L" = "PO₄–P mg/L"
) |>
fmt_number(
columns = where(is.numeric),
decimals = 0
) | Parameters | COD g/L | CODsol mg/L | FS g/L | NH₄–N mg/L | NO₃⁻N mg/L | PO₄–P mg/L | TN mg/L | TP mg/L | TS g/L | TSS g/L | VS g/L | VSS g/L |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Mean | 33 | 5,523 | 13 | 1,369 | 17 | 102 | 2,910 | 546 | 32 | 26 | 20 | 16 |
| Median | 25 | 4,732 | 9 | 1,422 | 14 | 82 | 2,887 | 387 | 24 | 19 | 15 | 11 |
| SD | 25 | 4,438 | 17 | 680 | 11 | 63 | 1,389 | 449 | 26 | 28 | 16 | 15 |
Strong relationships were observed between organic strength and solids content in pit latrine faecal sludge. Chemical oxygen demand increased consistently with increasing volatile solids concentrations, indicating that higher organic solids content corresponds to increased organic load. This pattern highlights the close linkage between solids accumulation and organic strength within pit latrines. Figure 1 illustrates the relationship between chemical oxygen demand and volatile solids in pit latrine faecal sludge.
# calculate correlation
rho <- cor(
pit_data$`COD g/L`,
pit_data$`VS g/L`,
method = "spearman",
use = "complete.obs"
)
# plot
ggplot(pit_data, aes(x = `VS g/L`, y = `COD g/L`)) +
geom_point(alpha = 0.6, size = 1) +
geom_smooth(method = "lm", se = FALSE) +
theme_minimal() +
labs(
x = "Volatile solids (g/L)",
y = "Chemical oxygen demand (g/L)",
caption = paste0("Spearman \u03C1 = ", round(rho, 2))
)
The proportions of volatile solids within both total and suspended solids were consistently high across samples. Most observations fell within intermediate VS/TS and VSS/TSS ratio ranges, indicating that a substantial fraction of both total and suspended solids is volatile. These ratios suggest the presence of a significant biodegradable fraction in pit latrine sludge, while the observed variability reflects differences in solids stabilisation between pits. Figure 2 shows the distribution of VS/TS and VSS/TSS ratios across pit latrine samples.
ratio_bins <- pit_data |>
mutate(
VS_TS = `VS g/L` / `TS g/L`,
VSS_TSS = `VSS g/L` / `TSS g/L`
) |>
select(VS_TS, VSS_TSS) |>
pivot_longer(
cols = c(VS_TS, VSS_TSS),
names_to = "Ratio",
values_to = "Value"
) |>
filter(!is.na(Value), is.finite(Value)) |>
mutate(
Ratio = recode(Ratio,
VS_TS = "VS/TS",
VSS_TSS = "VSS/TSS"),
Bin = cut(
Value,
breaks = seq(0, 1, by = 0.1),
include.lowest = TRUE,
right = FALSE,
labels = paste0(
seq(0, 0.9, by = 0.1),
"–",
seq(0.1, 1.0, by = 0.1)
)
)
) |>
filter(!is.na(Bin)) |>
count(Ratio, Bin, name = "n")ggplot(ratio_bins, aes(y = Bin, x = n)) +
geom_col(width = 0.95) +
facet_wrap(~ Ratio, ncol = 1, scales = "free_y") +
theme_minimal() +
labs(x = "Number of pits", y = "Ratio range") +
theme(axis.text.y = element_text(angle = 0))
Nutrient concentrations in pit latrine faecal sludge showed considerable variability across samples as seen in Figure 3. Total nitrogen and total phosphorus exhibited particularly wide interquartile ranges compared to inorganic nutrient species such as nitrate and orthophosphate. This variability reflects differences in nutrient accumulation, degradation, and transformation processes occurring within pit latrines.
nutrient_long <- pit_data |>
select(
"TN mg/L",
"TP mg/L",
"Nitrate mg/L",
"PO4P mg/L"
) |>
pivot_longer(
cols = everything(),
names_to = "Nutrient",
values_to = "Concentration"
)
ggplot(nutrient_long, aes(x = "", y = Concentration)) +
geom_boxplot() +
facet_wrap(~ Nutrient, scales = "free_y") +
theme_minimal() +
labs(
x = NULL,
y = "Concentration (mg/L)"
)
In summary;
AI tools were used to assist with code debugging and to improve grammar and clarity of the text