FAO Sub-Signature Decomposition
Related to Figure 3.
The composite FAO UCell score is elevated in captopril-treated mice (Cohen's d = 0.46, small), yet direct measurement of FAO activity in kidney tissue shows significantly reduced mitochondrial fatty acid oxidation (p = 0.032). This apparent discrepancy is addressed by decomposing the 27-gene FAO signature into three mechanistically distinct sub-groups and computing effect sizes for each.
Gene sub-groups
# Transport / CPT1 (rate-limiting step; CPT1 is inhibited by malonyl-CoA)
fao_transport_genes <- c(
"Slc27a1", "Slc27a2", "Slc27a3", "Slc27a4", "Slc27a5",
"Cd36",
"Cpt1a", "Cpt1b", "Cpt1c",
"Cpt2",
"Slc25a20"
)
# Mitochondrial beta-oxidation enzymes
fao_mitochondrial_genes <- c(
"Acadl", "Acadm", "Acads", "Acadvl",
"Echs1",
"Hadha", "Hadhb",
"Acaa1", "Acaa2",
"Eci1", "Eci2",
"Decr1"
)
# Peroxisomal acyl-CoA oxidases (PPAR-alpha targets)
fao_peroxisomal_genes <- c(
"Acox1", "Acox2", "Acox3"
)
Step 1 — Score FAO sub-signatures with UCell
captopril_obj <- AddModuleScore_UCell(
captopril_obj,
features = list(
FAO_transport = fao_transport_genes,
FAO_mitochondrial = fao_mitochondrial_genes,
FAO_peroxisomal = fao_peroxisomal_genes
),
assay = "RNA",
storeRanks = TRUE
)
# Output columns: FAO_transport_UCell, FAO_mitochondrial_UCell, FAO_peroxisomal_UCell
ren1c_obj <- AddModuleScore_UCell(
ren1c_obj,
features = list(
FAO_transport = fao_transport_genes,
FAO_mitochondrial = fao_mitochondrial_genes,
FAO_peroxisomal = fao_peroxisomal_genes
),
assay = "RNA",
storeRanks = TRUE
)
Step 2 — Wilcoxon statistics per sub-signature
for (metric in c("FAO_transport_UCell", "FAO_mitochondrial_UCell", "FAO_peroxisomal_UCell")) {
capt_sub_stats[[metric]] <- calcStatistics(
captopril_obj,
group_var = "condition",
group1 = "ctrl",
group2 = "trt",
metric = metric
)
fwrite(
capt_sub_stats[[metric]]$celltype_results,
paste0(parent_dir, "captopril_", gsub("_UCell", "", metric), "_celltype_stats.csv"),
row.names = FALSE, sep = ","
)
}
Step 3 — Cohen's d effect sizes per sub-group
cohensD is defined in 5B. Effect sizes compare CKD+ACEi vs Healthy (captopril model) and KO vs WT (Ren1c model):
calcSubsigEffectSizes <- function(seurat_obj, group_var, group1, group2, model_label) {
meta <- seurat_obj@meta.data
g1 <- meta[meta[[group_var]] == group1, ]
g2 <- meta[meta[[group_var]] == group2, ]
scores <- c("FAO_transport_UCell", "FAO_mitochondrial_UCell", "FAO_peroxisomal_UCell")
results <- lapply(scores, function(s) {
d <- cohensD(g1[[s]], g2[[s]])
data.frame(
model = model_label, sub_score = gsub("_UCell", "", s),
group1 = group1, group2 = group2,
mean_group1 = mean(g1[[s]]), mean_group2 = mean(g2[[s]]),
cohens_d = d,
magnitude = case_when(
abs(d) >= 0.8 ~ "large",
abs(d) >= 0.5 ~ "medium",
abs(d) >= 0.2 ~ "small",
TRUE ~ "negligible"
)
)
})
do.call(rbind, results)
}
effect_capt <- calcSubsigEffectSizes(captopril_obj, "condition", "ctrl", "trt", "captopril")
effect_ren1c <- calcSubsigEffectSizes(ren1c_obj, "genotype", "WT", "KO", "ren1c")
effect_all <- rbind(effect_capt, effect_ren1c)
fwrite(effect_all, paste0(parent_dir, "FAO_subsignature_cohens_d.csv"), row.names = FALSE, sep = ",")
Results (captopril model, ctrl → trt):
| Sub-group | Cohen's d | Magnitude |
|---|---|---|
| FAO_transport | 0.43 | small |
| FAO_peroxisomal | 0.35 | small |
| FAO_mitochondrial | 0.16 | negligible |
In the Ren1c KO model all three sub-groups are negligible (|d| < 0.11), consistent with the FAO signature elevation being specific to the pharmacologic ACE-inhibitor model.
Step 4 — Individual gene dot plots
The dot plots show percent expressed and average expression for all 27 FAO genes, ordered by sub-group with dashed vertical lines at sub-group boundaries.
all_fao_ordered <- c(fao_transport_genes, fao_mitochondrial_genes, fao_peroxisomal_genes)
makeFaoDotplot <- function(seurat_obj, group_by, group_colors, title_str) {
genes_present <- all_fao_ordered[all_fao_ordered %in% rownames(seurat_obj)]
n_transport <- sum(fao_transport_genes %in% genes_present)
n_mitochondrial <- sum(fao_mitochondrial_genes %in% genes_present)
n_peroxisomal <- sum(fao_peroxisomal_genes %in% genes_present)
vlines <- c(n_transport + 0.5, n_transport + n_mitochondrial + 0.5)
n_groups <- length(unique(seurat_obj@meta.data[[group_by]]))
label_y <- n_groups + 0.6
DotPlot(seurat_obj, features = genes_present, group.by = group_by,
cols = group_colors, dot.scale = 6) +
RotatedAxis() +
ggtitle(title_str) +
geom_vline(xintercept = vlines, linetype = "dashed", color = "grey50", linewidth = 0.4) +
coord_cartesian(clip = "off") +
annotate("text",
x = c(n_transport / 2,
n_transport + n_mitochondrial / 2,
n_transport + n_mitochondrial + n_peroxisomal / 2),
y = label_y,
label = c("Transport / CPT1", "Mitochondrial \u03b2-ox", "Peroxisomal"),
size = 2.8, color = "grey30", hjust = 0.5)
}
p_capt_dot <- makeFaoDotplot(
captopril_obj, group_by = "condition",
group_colors = c("lightgrey", "#d73027"),
title_str = "Captopril model \u2014 FAO gene expression (ctrl vs trt)"
)
ggsave(paste0(parent_dir, "captopril_FAO_gene_dotplot_", Sys.Date(), ".svg"),
p_capt_dot, width = 300, height = 100, units = "mm", dpi = 300)
p_ren1c_dot <- makeFaoDotplot(
ren1c_obj, group_by = "genotype",
group_colors = c("lightgrey", "#4575b4"),
title_str = "Ren1cKO model \u2014 FAO gene expression (WT vs KO)"
)
ggsave(paste0(parent_dir, "ren1c_FAO_gene_dotplot_", Sys.Date(), ".svg"),
p_ren1c_dot, width = 300, height = 100, units = "mm", dpi = 300)
Export the dot plot data as a table too:
dp_capt <- DotPlot(captopril_obj, features = all_fao_ordered[all_fao_ordered %in% rownames(captopril_obj)],
group.by = "condition")
dp_ren1c <- DotPlot(ren1c_obj, features = all_fao_ordered[all_fao_ordered %in% rownames(ren1c_obj)],
group.by = "genotype")
fwrite(dp_capt$data, paste0(parent_dir, "captopril_FAO_dotplot_data.csv"), row.names = FALSE, sep = ",")
fwrite(dp_ren1c$data, paste0(parent_dir, "ren1c_FAO_dotplot_data.csv"), row.names = FALSE, sep = ",")