5 Extract subgraph
Load R Package
library(tidyverse) # data manipulation / piping utilities
library(ggNetView) # graph builders + info-extraction helpersExample data
# Access built-in example datasets in ggNetView
# ---- Dataset 1: Relative abundance table of rarefied ASVs/OTUs ----
# Rows = ASVs/OTUs (features / variables), Columns = samples
data("otu_rare_relative")
dim(otu_rare_relative) # Check matrix dimensions: n_features x n_samples ## [1] 2859 18
otu_rare_relative[1:5, 1:5] # Preview first 5 rows x 5 cols to confirm data layout## KO1 KO2 KO3 KO4 KO5
## ASV_1 0.03306667 0.05453333 0.02013333 0.03613333 0.02686667
## ASV_2 0.05750000 0.03393333 0.06046667 0.05810000 0.07320000
## ASV_3 0.01733333 0.01296667 0.02290000 0.02336667 0.03106667
## ASV_4 0.04266667 0.01093333 0.01416667 0.01933333 0.03346667
## ASV_6 0.02646667 0.01856667 0.02110000 0.02353333 0.03806667
# ---- Dataset 2: Taxonomic annotation table for ASVs/OTUs ----
# Rows = ASVs/OTUs (row names should match the abundance table above)
# Columns = taxonomic ranks (Kingdom ~ Species, etc.)
data("tax_tab")
dim(tax_tab)## [1] 2859 8
tax_tab[1:5, 1:5]## # A tibble: 5 × 5
## OTUID Kingdom Phylum Class Order
## <chr> <chr> <chr> <chr> <chr>
## 1 ASV_2 Archaea Thaumarchaeota Unassigned Nitrososphaerales
## 2 ASV_3 Bacteria Verrucomicrobia Spartobacteria Unassigned
## 3 ASV_31 Bacteria Actinobacteria Actinobacteria Actinomycetales
## 4 ASV_27 Archaea Thaumarchaeota Unassigned Nitrososphaerales
## 5 ASV_9 Bacteria Unassigned Unassigned Unassigned
Build graph object
# Build a correlation-based graph object (tbl_graph) from the abundance matrix.
# This graph object is the foundation for downstream subgraph extraction,
# layout computation, and visualization.
graph_obj <- build_graph_from_mat(
mat = otu_rare_relative, # Input matrix: features (rows) x samples (cols)
transfrom.method = "none", # Data transformation before correlation; Other options: "scale" / "center" / "log2" / "log10" / "ln" / "rrarefy" / "rrarefy_relative"
r.threshold = 0.7, # Correlation cutoff: keep edges only if |r| >= 0.7
p.threshold = 0.05, # Significance cutoff: keep edges only if p < 0.05
method = "WGCNA", # Association method: Other options: "SpiecEasi" / "SPARCC" / "cor" / "Hmisc"
cor.method = "pearson", # Correlation type: Pearson (also: "spearman" / "kendall")
proc = "bonferroni", # Multiple-testing correction for p-values.
# Other options: "BH" / "fdr" / "holm" / "hochberg" / ...
module.method = "Fast_greedy", # Community / module detection algorithm. Other options: "Walktrap" / "Edge_betweenness" / "Spinglass"
node_annotation = tax_tab, # Node metadata (taxonomy) attached to each node
top_modules = 15, # Keep only the top 15 largest modules for downstream use
seed = 1115 # Random seed for reproducible module detection
)
graph_obj # Print the graph object: node/edge counts and attributes## # A tbl_graph: 213 nodes and 844 edges
## #
## # An undirected simple graph with 29 components
## #
## # Node Data: 213 × 14 (active)
## name modularity modularity2 modularity3 Modularity Degree Strength Kingdom
## <chr> <fct> <ord> <chr> <ord> <dbl> <dbl> <chr>
## 1 ASV_649 5 5 5 5 27 26.5 Bacter…
## 2 ASV_705 5 5 5 5 27 26.5 Bacter…
## 3 ASV_12… 5 5 5 5 27 26.5 Bacter…
## 4 ASV_13… 5 5 5 5 27 26.5 Bacter…
## 5 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 6 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 7 ASV_24… 5 5 5 5 27 26.5 Bacter…
## 8 ASV_25… 5 5 5 5 27 26.4 Bacter…
## 9 ASV_28… 5 5 5 5 27 26.5 Bacter…
## 10 ASV_28… 5 5 5 5 27 26.5 Bacter…
## # ℹ 203 more rows
## # ℹ 6 more variables: Phylum <chr>, Class <chr>, Order <chr>, Family <chr>,
## # Genus <chr>, Species <chr>
## #
## # Edge Data: 844 × 5
## from to weight correlation corr_direction
## <int> <int> <dbl> <dbl> <chr>
## 1 194 195 0.959 0.959 Positive
## 2 185 208 0.954 0.954 Positive
## 3 185 213 0.957 0.957 Positive
## # ℹ 841 more rows
5.1 Extract subgraph by module
5.1.1 select subgraph by modularity
Select one modularity
# Extract the subgraph corresponding to module "5".
# Internally, get_subgraph():
# 1) splits all nodes by the `Modularity` attribute,
# 2) builds one subgraph per module and stores them in `sub_graph_all`,
# 3) if `select_module` is provided, also returns `sub_graph_select`
# (the graph filtered to those modules via tidygraph::filter),
# 4) returns `stat_module`: a table of node counts per module across the full graph.
module5_subgraph_info <- get_subgraph(graph_obj = graph_obj,
select_module = "5")## Module Number
## 1 5 31
## 2 2 24
## 3 8 22
## 4 21 15
## 5 1 13
## 6 3 11
## 7 4 11
## 8 6 11
## 9 25 8
## 10 7 6
## 11 12 5
## 12 22 5
## 13 10 4
## 14 11 4
## 15 15 4
## 16 Others 39
class(module5_subgraph_info) ## [1] "list"
names(module5_subgraph_info)## [1] "sub_graph_all" "stat_module" "sub_graph_select"
module5_subgraph_info$stat_module # Per-module node count summary (Module, Number)## Module Number
## 1 5 31
## 2 2 24
## 3 8 22
## 4 21 15
## 5 1 13
## 6 3 11
## 7 4 11
## 8 6 11
## 9 25 8
## 10 7 6
## 11 12 5
## 12 22 5
## 13 10 4
## 14 11 4
## 15 15 4
## 16 Others 39
# module5_subgraph_info$sub_graph_all # Named list of tbl_graphs, one per module
module5_subgraph_info$sub_graph_select # Single tbl_graph containing only module "5"## # A tbl_graph: 31 nodes and 330 edges
## #
## # An undirected simple graph with 1 component
## #
## # Node Data: 31 × 14 (active)
## name modularity modularity2 modularity3 Modularity Degree Strength Kingdom
## <chr> <fct> <ord> <chr> <ord> <dbl> <dbl> <chr>
## 1 ASV_649 5 5 5 5 27 26.5 Bacter…
## 2 ASV_705 5 5 5 5 27 26.5 Bacter…
## 3 ASV_12… 5 5 5 5 27 26.5 Bacter…
## 4 ASV_13… 5 5 5 5 27 26.5 Bacter…
## 5 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 6 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 7 ASV_24… 5 5 5 5 27 26.5 Bacter…
## 8 ASV_25… 5 5 5 5 27 26.4 Bacter…
## 9 ASV_28… 5 5 5 5 27 26.5 Bacter…
## 10 ASV_28… 5 5 5 5 27 26.5 Bacter…
## # ℹ 21 more rows
## # ℹ 6 more variables: Phylum <chr>, Class <chr>, Order <chr>, Family <chr>,
## # Genus <chr>, Species <chr>
## #
## # Edge Data: 330 × 5
## from to weight correlation corr_direction
## <int> <int> <dbl> <dbl> <chr>
## 1 29 30 0.949 0.949 Positive
## 2 21 29 0.952 0.952 Positive
## 3 25 29 0.965 0.965 Positive
## # ℹ 327 more rows
Select multi-modularity
# Extract a combined subgraph for multiple modules at once (modules 5, 2, and 8).
# `sub_graph_select` will contain all nodes from these three modules
# plus the edges among them.
module5_2_8_subgraph_info <- get_subgraph(
graph_obj = graph_obj,
select_module = c("5","2","8")) # Multiple module IDs## Module Number
## 1 5 31
## 2 2 24
## 3 8 22
## 4 21 15
## 5 1 13
## 6 3 11
## 7 4 11
## 8 6 11
## 9 25 8
## 10 7 6
## 11 12 5
## 12 22 5
## 13 10 4
## 14 11 4
## 15 15 4
## 16 Others 39
class(module5_2_8_subgraph_info)## [1] "list"
names(module5_2_8_subgraph_info)## [1] "sub_graph_all" "stat_module" "sub_graph_select"
module5_2_8_subgraph_info$stat_module # Global module stats (same as before; not affected by selection)## Module Number
## 1 5 31
## 2 2 24
## 3 8 22
## 4 21 15
## 5 1 13
## 6 3 11
## 7 4 11
## 8 6 11
## 9 25 8
## 10 7 6
## 11 12 5
## 12 22 5
## 13 10 4
## 14 11 4
## 15 15 4
## 16 Others 39
# module5_2_8_subgraph_info$sub_graph_all # Full per-module subgraph list (unchanged)
module5_2_8_subgraph_info$sub_graph_select # Combined subgraph filtered to modules 5, 2, and 8## # A tbl_graph: 77 nodes and 582 edges
## #
## # An undirected simple graph with 3 components
## #
## # Node Data: 77 × 14 (active)
## name modularity modularity2 modularity3 Modularity Degree Strength Kingdom
## <chr> <fct> <ord> <chr> <ord> <dbl> <dbl> <chr>
## 1 ASV_649 5 5 5 5 27 26.5 Bacter…
## 2 ASV_705 5 5 5 5 27 26.5 Bacter…
## 3 ASV_12… 5 5 5 5 27 26.5 Bacter…
## 4 ASV_13… 5 5 5 5 27 26.5 Bacter…
## 5 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 6 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 7 ASV_24… 5 5 5 5 27 26.5 Bacter…
## 8 ASV_25… 5 5 5 5 27 26.4 Bacter…
## 9 ASV_28… 5 5 5 5 27 26.5 Bacter…
## 10 ASV_28… 5 5 5 5 27 26.5 Bacter…
## # ℹ 67 more rows
## # ℹ 6 more variables: Phylum <chr>, Class <chr>, Order <chr>, Family <chr>,
## # Genus <chr>, Species <chr>
## #
## # Edge Data: 582 × 5
## from to weight correlation corr_direction
## <int> <int> <dbl> <dbl> <chr>
## 1 56 74 0.952 0.952 Positive
## 2 57 74 0.954 0.954 Positive
## 3 58 74 0.947 0.947 Positive
## # ℹ 579 more rows
5.2 Extract subgraph by sample
# ---- Load example datasets shipped with ggNetView ----------------------
# Relative-abundance table of rarefied ASVs/OTUs (rows = features, cols = samples)
data("otu_rare_relative")
# Taxonomic annotation table for those ASVs/OTUs (used as node metadata)
data("tax_tab")
# ---- Build the correlation-based network -------------------------------
# This produces a tbl_graph that downstream subgraph / layout / plotting
# functions all consume.
graph_obj <- build_graph_from_mat(
mat = otu_rare_relative, # Feature-by-sample matrix
transfrom.method = "none", # No transform: input is already relative abundance
r.threshold = 0.7, # Keep edges with |r| >= 0.7
p.threshold = 0.05, # Keep edges with p < 0.05
method = "WGCNA", # WGCNA correlation + p-values
cor.method = "pearson", # Pearson correlation
proc = "bonferroni", # Bonferroni multiple-testing correction
module.method = "Fast_greedy", # Community detection algorithm
node_annotation = tax_tab, # Attach taxonomy to each node
top_modules = 15, # Keep the 15 largest modules
seed = 1115 # Reproducible module assignment
)
graph_obj## # A tbl_graph: 213 nodes and 844 edges
## #
## # An undirected simple graph with 29 components
## #
## # Node Data: 213 × 14 (active)
## name modularity modularity2 modularity3 Modularity Degree Strength Kingdom
## <chr> <fct> <ord> <chr> <ord> <dbl> <dbl> <chr>
## 1 ASV_649 5 5 5 5 27 26.5 Bacter…
## 2 ASV_705 5 5 5 5 27 26.5 Bacter…
## 3 ASV_12… 5 5 5 5 27 26.5 Bacter…
## 4 ASV_13… 5 5 5 5 27 26.5 Bacter…
## 5 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 6 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 7 ASV_24… 5 5 5 5 27 26.5 Bacter…
## 8 ASV_25… 5 5 5 5 27 26.4 Bacter…
## 9 ASV_28… 5 5 5 5 27 26.5 Bacter…
## 10 ASV_28… 5 5 5 5 27 26.5 Bacter…
## # ℹ 203 more rows
## # ℹ 6 more variables: Phylum <chr>, Class <chr>, Order <chr>, Family <chr>,
## # Genus <chr>, Species <chr>
## #
## # Edge Data: 844 × 5
## from to weight correlation corr_direction
## <int> <int> <dbl> <dbl> <chr>
## 1 194 195 0.959 0.959 Positive
## 2 185 208 0.954 0.954 Positive
## 3 185 213 0.957 0.957 Positive
## # ℹ 841 more rows
5.2.1 select subgraph by sample name
# ---- Extract sample-level subgraphs ------------------------------------
# For each sample (column of `mat`), an OTU is treated as "present" when
# its abundance is > `min_abundance` (default 0). The induced subgraph of
# `graph_obj` on those present OTUs is returned per sample. With
# `select_sample` + `combine`, a single merged subgraph is also returned.
res <- get_sample_subgraph(
graph_obj = graph_obj, # The network built above
mat = otu_rare_relative, # Same matrix used to judge "presence"
select_sample = colnames(otu_rare_relative)[1:3],# Merge the first 3 samples
combine = "union" # Keep OTUs present in ANY of the 3 samples (use "intersect" for OTUs present in ALL)
)
class(res)## [1] "list"
names(res)## [1] "sub_graph_all" "stat_sample" "sub_graph_select"
# ---- Inspect outputs ---------------------------------------------------
# Per-sample summary table: Sample / Node / Edge / Status.
# Includes every sample in `mat`, even those whose subgraph is empty.
res$stat_sample## Sample Node Edge Status
## 1 KO1 113 161 OK
## 2 KO2 122 164 OK
## 3 KO3 102 379 OK
## 4 KO4 94 107 OK
## 5 KO5 71 63 OK
## 6 KO6 97 119 OK
## 7 OE1 138 308 OK
## 8 OE2 135 230 OK
## 9 OE3 119 160 OK
## 10 OE4 118 171 OK
## 11 OE5 111 165 OK
## 12 OE6 140 234 OK
## 13 WT1 105 130 OK
## 14 WT2 83 59 OK
## 15 WT3 117 171 OK
## 16 WT4 111 222 OK
## 17 WT5 90 103 OK
## 18 WT6 111 162 OK
# Merged subgraph for the 3 selected samples (a single tbl_graph).
# Its node table carries two extra columns:
# - n_present_samples : how many of the 3 selected samples a node appears in
# - present_in_samples: comma-separated sample IDs, ordered by `select_sample`
res$sub_graph_select## # A tbl_graph: 181 nodes and 602 edges
## #
## # An undirected simple graph with 34 components
## #
## # Node Data: 181 × 16 (active)
## name modularity modularity2 modularity3 Modularity Degree Strength Kingdom
## <chr> <fct> <ord> <chr> <ord> <dbl> <dbl> <chr>
## 1 ASV_649 5 5 5 5 27 26.5 Bacter…
## 2 ASV_705 5 5 5 5 27 26.5 Bacter…
## 3 ASV_12… 5 5 5 5 27 26.5 Bacter…
## 4 ASV_13… 5 5 5 5 27 26.5 Bacter…
## 5 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 6 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 7 ASV_24… 5 5 5 5 27 26.5 Bacter…
## 8 ASV_25… 5 5 5 5 27 26.4 Bacter…
## 9 ASV_28… 5 5 5 5 27 26.5 Bacter…
## 10 ASV_28… 5 5 5 5 27 26.5 Bacter…
## # ℹ 171 more rows
## # ℹ 8 more variables: Phylum <chr>, Class <chr>, Order <chr>, Family <chr>,
## # Genus <chr>, Species <chr>, n_present_samples <int>,
## # present_in_samples <chr>
## #
## # Edge Data: 602 × 5
## from to weight correlation corr_direction
## <int> <int> <dbl> <dbl> <chr>
## 1 164 165 0.959 0.959 Positive
## 2 158 181 0.957 0.957 Positive
## 3 145 147 0.969 0.969 Positive
## # ℹ 599 more rows
# detail information
res$sub_graph_select %>%
tidygraph::activate(., "nodes") %>%
tibble::as_tibble()## # A tibble: 181 × 16
## name modularity modularity2 modularity3 Modularity Degree Strength Kingdom
## <chr> <fct> <ord> <chr> <ord> <dbl> <dbl> <chr>
## 1 ASV_649 5 5 5 5 27 26.5 Bacter…
## 2 ASV_705 5 5 5 5 27 26.5 Bacter…
## 3 ASV_12… 5 5 5 5 27 26.5 Bacter…
## 4 ASV_13… 5 5 5 5 27 26.5 Bacter…
## 5 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 6 ASV_14… 5 5 5 5 27 26.5 Bacter…
## 7 ASV_24… 5 5 5 5 27 26.5 Bacter…
## 8 ASV_25… 5 5 5 5 27 26.4 Bacter…
## 9 ASV_28… 5 5 5 5 27 26.5 Bacter…
## 10 ASV_28… 5 5 5 5 27 26.5 Bacter…
## # ℹ 171 more rows
## # ℹ 8 more variables: Phylum <chr>, Class <chr>, Order <chr>, Family <chr>,
## # Genus <chr>, Species <chr>, n_present_samples <int>,
## # present_in_samples <chr>