# res is the output from Step 2 (annotate_feature)
res <- extract_subnetwork(
res = res,
feature = "all",
mrn = NULL,
workers = 4,
times = 100,
b = 20,
mu = 1e-4,
w = 25,
r = 0.20,
grid_tune = FALSE
)4 Subnetwork Extraction
This chapter describes Step 3 of the FeatureMAP pipeline: extracting a robust metabolic subnetwork with extract_subnetwork() using the prize-collecting Steiner forest (PCSF) strategy.
Prerequisites: You need a featuremap_result object from Feature Annotation, with stage "feature_annotated".
4.1 What extract_subnetwork() Does
extract_subnetwork() integrates the refined feature annotations from Step 2 with a metabolic reaction network (MRN) and applies repeated PCSF optimization to identify a robust subnetwork.
At a high level, this step does the following:
Compute feature importance: Feature-level statistical evidence is summarized from
conditionandpvalue. Both are min–max rescaled and combined asimportance = sqrt(score_fc * score_p), and the result is written back intores$feature_table.Build feature–metabolite mappings: The refined annotation table is projected onto MRN metabolite nodes, using
HMDB.IDfirst andKEGG.IDas fallback, so that observed LC–MS features become terminal nodes attached to candidate metabolites.Run repeated PCSF optimization: PCSF is run
timestimes with relative Gaussian perturbation of the edge costs, so that the result does not depend on a single optimization run.Aggregate robust network components: Node and edge frequencies are recorded across repeated runs, and the final subnetwork is constructed as the union of recurrent PCSF solutions.
Refine annotation using network support: Feature–metabolite mappings are updated based on network evidence, producing
anno_feature_table2.
This step moves the analysis from individual annotated features to a network-supported metabolite subnetwork, which is then used in downstream module extraction and interpretation.
4.2 Key Parameters
| Parameter | Default | Description |
|---|---|---|
res |
required | featuremap_result returned by annotate_feature() |
feature |
"all" |
Use all annotated features ("all") or only significant features ("sig") |
pcutoff |
0.05 |
Significance cutoff used when feature = "sig" |
mrn |
NULL |
Optional custom metabolic reaction network (tidygraph::tbl_graph); automatically loaded if NULL |
workers |
4 |
Number of parallel workers |
times |
100 |
Number of repeated PCSF runs |
b |
20 |
Prize scaling factor in PCSF |
mu |
1e-4 |
Hub penalty coefficient; non-terminal nodes receive a negative prize proportional to their degree |
w |
25 |
Dummy edge cost in PCSF |
r |
0.20 |
Relative Gaussian edge-cost noise across repeated runs |
grid_tune |
FALSE |
Whether to tune b and w over a parameter grid |
b_grid |
seq(20, 40, by = 5) |
Candidate values of b when grid tuning is enabled |
w_grid |
seq(20, 40, by = 5) |
Candidate values of w when grid tuning is enabled |
times_tune |
10 |
Number of repeated runs for each (b, w) combination during tuning |
The MRN is loaded automatically from the cached mrn resource when mrn = NULL, and is stored in res$mrn so that later steps reuse exactly the same network.
4.3 Basic Usage
Use feature = "all" when you want the network to see the full statistical landscape, and feature = "sig" together with pcutoff when you prefer to seed the network only with significantly changed features.
4.4 Optional: Grid Tuning for b and w
If you want data-driven parameter selection, enable grid tuning:
res <- extract_subnetwork(
res = res,
feature = "all",
workers = 4,
times = 100,
grid_tune = TRUE,
b_grid = seq(20, 40, by = 5),
w_grid = seq(20, 40, by = 5),
times_tune = 10
)When grid_tune = TRUE, FeatureMAP records:
res$tuning_grid: full tuning resultsres$tuning_best: selected best(b, w)and summary metrics
4.5 Result Interpretation
After successful extraction, first confirm that the subnetwork step completed successfully:
res$stage
# [1] "subnetwork_extracted"
names(res)
# [1] "anno_feature_table2" "edge_frequency" "node_frequency"
# [4] "pcsf_subnet" "mrn" "anno_redundancy"
# [7] "anno_feature_table1" "refdata" "feature_table"
# [10] "stage" "object_type" ".__enclos_env__"
# [13] "clone" "initialize"4.5.1 Extracted PCSF subnetwork
The extracted metabolic subnetwork is stored as an igraph object, where metabolite nodes are named by their InChI string and feature nodes by their variable_id:
res$pcsf_subnet
# IGRAPH ... UNWB 2217 4949 --
# + attr: name (v/c), prize (v/n), type (v/c), freq (e/n), weight (e/n)
# + edges from ... (vertex names):
# + ... omitted several edgesNode attribute type is "Terminal" for LC–MS feature nodes and "Steiner" for metabolite nodes; prize stores the node appearance frequency, and edge attributes freq / weight store how often each edge was recovered across the repeated runs. In res$node_frequency, the type column instead distinguishes "feature" from "metabolite" nodes.
4.5.2 Network-refined annotation table
After PCSF extraction, FeatureMAP updates the feature–metabolite annotation table by incorporating network evidence:
dim(res$anno_feature_table2)
head(res$anno_feature_table2[, c(
"variable_id", "Compound.name", "HMDB.ID", "KEGG.ID",
"edge_freq", "weighted_anno_score", "confidence_rank", "importance"
)])
# [1] 2909 34
# variable_id Compound.name HMDB.ID KEGG.ID edge_freq weighted_anno_score
# 1 M105T384_POS Peroxynitrite HMDB0002179 C16845 0.72 0.272
# 2 M105T384_POS 4-Hydroxymethylcatechol <NA> C14110 0.19 0.113
# 3 M105T384_POS 2,4,6-Trihydroxytoluene <NA> C16401 0.16 0.104
# 4 M105T384_POS 2-Hydroxybenzaldehyde HMDB0034170 C06202 0.15 0.101
# 5 M105T384_POS 2,4,5-Trihydroxytoluene <NA> C18317 0.14 0.098
# 6 M105T384_POS Benzoic acid HMDB0001870 C00539 0.12 0.092
# confidence_rank importance
# 1 1 0.06651944
# 2 2 0.06651944
# 3 3 0.06651944
# 4 4 0.06651944
# 5 5 0.06651944
# 6 6 0.06651944anno_feature_table2 keeps all columns of anno_feature_table1 for the surviving rows, and adds:
| Column | Description |
|---|---|
INCHI_ID |
InChI of the metabolite node in the MRN |
edge_freq |
How often the feature–metabolite edge appeared across the repeated PCSF runs |
weighted_anno_score |
Combination of score_norm and edge_freq, using an adaptive edge weight bounded between 0.1 and 0.3 |
confidence_rank |
Rank of the candidate within each feature, 1 being the most confident |
importance |
Feature-level statistical importance carried over from res$feature_table |
Compared with anno_feature_table1, this table incorporates network support from the extracted subnetwork. Metabolite candidates that are more consistently supported by the extracted metabolic network receive higher weighted_anno_score and better confidence_rank.
A quick way to see how much the network narrowed the candidate space:
length(unique(res$anno_feature_table1$variable_id))
length(unique(res$anno_feature_table2$variable_id))
# [1] 1106
# [1] 7254.5.3 Other Result Components
res$feature_table: now containsscore_fc,score_pandimportanceres$mrn: the metabolic reaction network actually usedres$node_frequency: node appearance frequency across repeated runsres$edge_frequency: edge appearance frequency across repeated runsres$tuning_grid,res$tuning_best: available when grid tuning is used
4.6 Next Step
Once subnetwork extraction is complete, continue to Module Identification to detect connected functional modules from the extracted network.