This vignette demonstrates metabolic flux analysis for single-cell RNA-seq data using METAFLUX’s community modeling approach.
Single-cell metabolic analysis reveals:
┌─────────────────────────────────────────────────────────────────┐
│ Tumor Microenvironment │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Tumor │ ←→ │ T cell │ ←→ │ Macro- │ │
│ │ Cells │ │ │ │ phage │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ │ │
│ ┌────┴────┐ │
│ │ Shared │ │
│ │ Medium │ │
│ └─────────┘ │
└─────────────────────────────────────────────────────────────────┘
| Component | Format | Description |
|---|---|---|
| Seurat object | v4/v5 | Normalized counts in RNA assay |
| Cell annotations | Metadata column | Cell type labels |
| Medium profile | Data frame | Available nutrients |
Single-cell data is sparse. Bootstrap aggregation reduces noise while preserving biological variation.
# Calculate bootstrap-averaged expression
avg_expr <- calculate_avg_exp(
myseurat = sc_test_example,
myident = "Cell_type", # Column with cell type labels
n_bootstrap = 100, # Number of bootstrap iterations
seed = 42 # For reproducibility
)
# Check output dimensions
dim(avg_expr)
# Rows: genes
# Columns: cell_type_1, cell_type_2, ..., cell_type_1, ... (repeated n_bootstrap times)For each bootstrap iteration i:
1. Resample cells within each cell type (with replacement)
2. Compute average expression per cell type
3. Store result
Output: Matrix of [genes × (n_celltypes × n_bootstrap)]
Cell type proportions weight the community model:
# Number of cell types
num_cell <- length(unique(sc_test_example$Cell_type))
# Compute community metabolic fluxes
flux <- compute_sc_flux(
num_cell = num_cell,
fraction = fractions,
fluxscore = mras,
medium = human_blood,
parallel = TRUE, # Enable parallel computing
n_cores = 4, # Number of CPU cores
use_cpp = TRUE # Use C++ acceleration
)
# Check output
dim(flux)
head(rownames(flux), 20)The flux matrix contains:
celltype 1 HMR_0001 # Cell type 1 reactions
celltype 1 HMR_0002
...
celltype 2 HMR_0001 # Cell type 2 reactions
celltype 2 HMR_0002
...
external_medium HMR_XXXX # External exchange reactions
# Get reaction names
reaction_names <- rownames(flux)
# Extract fluxes for specific cell type
get_celltype_flux <- function(flux_matrix, celltype_num) {
pattern <- paste0("^celltype ", celltype_num, " ")
idx <- grep(pattern, rownames(flux_matrix))
result <- flux_matrix[idx, , drop = FALSE]
rownames(result) <- gsub(pattern, "", rownames(result))
return(result)
}
# Extract for each cell type
tumor_flux <- get_celltype_flux(flux, 1)
tcell_flux <- get_celltype_flux(flux, 2)# Extract external exchange reactions
external_idx <- grep("^external_medium", rownames(flux))
external_flux <- flux[external_idx, , drop = FALSE]
# Net nutrient consumption/production
nutrient_balance <- rowMeans(external_flux)
head(sort(nutrient_balance), 10) # Top uptakes
tail(sort(nutrient_balance), 10) # Top secretionsIdentify metabolites competed for by different cell types:
Identify metabolites exchanged between cell types:
# One cell type produces, another consumes
producer <- which(lactate_by_celltype > 0)
consumer <- which(lactate_by_celltype < 0)
if (length(producer) > 0 && length(consumer) > 0) {
cat(sprintf("%s produces lactate\n", names(lactate_by_celltype)[producer]))
cat(sprintf("%s consumes lactate\n", names(lactate_by_celltype)[consumer]))
}# High glycolysis, low oxidative phosphorylation
glycolysis_rxns <- c("HMR_4363", "HMR_4365", "HMR_4367") # Example
oxphos_rxns <- c("HMR_6916", "HMR_6921") # Example
tumor_flux <- get_celltype_flux(flux, 1)
glycolysis_mean <- mean(abs(tumor_flux[glycolysis_rxns, ]))
oxphos_mean <- mean(abs(tumor_flux[oxphos_rxns, ]))
warburg_ratio <- glycolysis_mean / oxphos_mean
cat(sprintf("Warburg ratio: %.2f\n", warburg_ratio))# T cell activation markers
glutamine_rxn <- "HMR_9063" # Glutamine uptake
fa_synthesis <- grep("fatty acid synthesis", rownames(tumor_flux), ignore.case = TRUE)
tcell_flux <- get_celltype_flux(flux, 2)
tcell_glutamine <- mean(abs(tcell_flux[glutamine_rxn, ]))
tcell_fa <- mean(abs(tcell_flux[fa_synthesis, ]))
cat(sprintf("T cell glutamine uptake: %.4f\n", tcell_glutamine))
cat(sprintf("T cell fatty acid synthesis: %.4f\n", tcell_fa))Save results for downstream analysis: