5 Extract subgraph

Load R Package

library(tidyverse)   # data manipulation / piping utilities
library(ggNetView)   # graph builders + info-extraction helpers

Example 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>