4 Get network information

Once the graph object is constructed, basic network information can be retrieved, and subnetworks can be extracted.


Load R Package

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

Example data

# ---- Built-in example datasets ----

# Relative abundance table of rarefied ASVs/OTUs (rows = ASVs, cols = samples).
data("otu_rare_relative")
dim(otu_rare_relative)
## [1] 2859   18
otu_rare_relative[1:5, 1:5]
##              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
# Taxonomic annotation; first column must be the ASV/OTU ID.
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 co-occurrence network as the input for downstream queries ----
graph_obj <- build_graph_from_mat(
  mat              = otu_rare_relative,  # variables x samples numeric matrix
  transfrom.method = "none",             # input already relative abundance, no extra transform
  r.threshold      = 0.7,                # |r| cutoff for keeping an edge
  p.threshold      = 0.05,               # adjusted p-value cutoff
  method           = "WGCNA",            # correlation backend: WGCNA::corAndPvalue
  cor.method       = "pearson",          # Pearson correlation
  proc             = "bonferroni",       # multiple-testing correction
  module.method    = "Fast_greedy",      # community detection algorithm
  node_annotation  = tax_tab,            # taxonomy joined onto each node by name
  top_modules      = 15,                 # keep top-15 modules; rest -> "Others"
  seed             = 1115                # fix RNG for reproducibility
)

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

4.1 Full-network information

# ---- Retrieve node-level and edge-level info for the FULL graph ----
# Returns a list with `node_info` and `edge_info` tibbles.
graph_obj_info <- get_info_from_graph(graph_obj = graph_obj)

class(graph_obj_info)         # "list"
## [1] "list"
names(graph_obj_info)         # "node_info", "edge_info"
## [1] "node_info" "edge_info"
graph_obj_info$node_info      # per-node attributes: name, Modularity, Degree, Strength, taxonomy, ...
## # A tibble: 213 × 11
##    name     Modularity Degree Strength Kingdom  Phylum  Class Order Family Genus
##    <chr>    <ord>       <dbl>    <dbl> <chr>    <chr>   <chr> <chr> <chr>  <chr>
##  1 ASV_649  5              27     26.5 Bacteria Proteo… Alph… Rhiz… Unass… Unas…
##  2 ASV_705  5              27     26.5 Bacteria Actino… Acti… Acti… Cellu… Cell…
##  3 ASV_1234 5              27     26.5 Bacteria Gemmat… Gemm… Gemm… Gemma… Gemm…
##  4 ASV_1373 5              27     26.5 Bacteria Actino… Acti… Soli… Solir… Soli…
##  5 ASV_1479 5              27     26.5 Bacteria Verruc… Spar… Unas… Unass… Spar…
##  6 ASV_1481 5              27     26.5 Bacteria Proteo… Gamm… Unas… Unass… Unas…
##  7 ASV_2453 5              27     26.5 Bacteria Bacter… Sphi… Sphi… Chiti… Unas…
##  8 ASV_2562 5              27     26.4 Bacteria Bacter… Sphi… Sphi… Chiti… Unas…
##  9 ASV_2848 5              27     26.5 Bacteria Planct… Plan… Plan… Planc… Unas…
## 10 ASV_2844 5              27     26.5 Bacteria Proteo… Unas… Unas… Unass… Unas…
## # ℹ 203 more rows
## # ℹ 1 more variable: Species <chr>
graph_obj_info$edge_info      # per-edge attributes: from, to, weight, ...
## # A tibble: 844 × 5
##    from    to       weight correlation corr_direction
##    <chr>   <chr>     <dbl>       <dbl> <chr>         
##  1 ASV_6   ASV_39    0.959       0.959 Positive      
##  2 ASV_20  ASV_1852  0.954       0.954 Positive      
##  3 ASV_20  ASV_2911  0.957       0.957 Positive      
##  4 ASV_172 ASV_43    0.969       0.969 Positive      
##  5 ASV_614 ASV_65    0.943       0.943 Positive      
##  6 ASV_69  ASV_173   0.995       0.995 Positive      
##  7 ASV_69  ASV_206   0.994       0.994 Positive      
##  8 ASV_69  ASV_744   0.976       0.976 Positive      
##  9 ASV_945 ASV_69    0.985       0.985 Positive      
## 10 ASV_69  ASV_1418  0.975       0.975 Positive      
## # ℹ 834 more rows

4.2 Sub-network (modularity) information

# ---- Split the graph by `Modularity` (one subgraph per module) ----
# `select_module = NULL` -> no merged subgraph; only per-module split + stats.
subgraph_info <- get_subgraph(
  graph_obj     = graph_obj,   # input tbl_graph (must have a `Modularity` column on nodes)
  select_module = NULL         # NULL -> don't build a merged subgraph
)
##    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(subgraph_info)          # "list"
## [1] "list"
names(subgraph_info)          # "sub_graph_all", "stat_module", "sub_graph_select"
## [1] "sub_graph_all"    "stat_module"      "sub_graph_select"
# Per-module node counts (data.frame with columns: Module, Number).
subgraph_info$stat_module
##    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

We select modulerity 5

# ---- Build a merged subgraph for a chosen module ----
# `select_module = "5"` keeps nodes whose Modularity == "5"
# (and the edges between them) in `sub_graph_select`.
graph_module5 <- get_subgraph(
  graph_obj     = graph_obj,
  select_module = "5"          # character vector of module labels to retain
)
##    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
# ---- Inspect the module-5 subgraph using the same info helper ----
graph_obj_info <- get_info_from_graph(
  graph_obj = graph_module5$sub_graph_select   # the merged tbl_graph for module 5
)

class(graph_obj_info)         # "list"
## [1] "list"
names(graph_obj_info)         # "node_info", "edge_info"
## [1] "node_info" "edge_info"
graph_obj_info$node_info      # nodes belonging to module 5
## # A tibble: 31 × 11
##    name     Modularity Degree Strength Kingdom  Phylum  Class Order Family Genus
##    <chr>    <ord>       <dbl>    <dbl> <chr>    <chr>   <chr> <chr> <chr>  <chr>
##  1 ASV_649  5              27     26.5 Bacteria Proteo… Alph… Rhiz… Unass… Unas…
##  2 ASV_705  5              27     26.5 Bacteria Actino… Acti… Acti… Cellu… Cell…
##  3 ASV_1234 5              27     26.5 Bacteria Gemmat… Gemm… Gemm… Gemma… Gemm…
##  4 ASV_1373 5              27     26.5 Bacteria Actino… Acti… Soli… Solir… Soli…
##  5 ASV_1479 5              27     26.5 Bacteria Verruc… Spar… Unas… Unass… Spar…
##  6 ASV_1481 5              27     26.5 Bacteria Proteo… Gamm… Unas… Unass… Unas…
##  7 ASV_2453 5              27     26.5 Bacteria Bacter… Sphi… Sphi… Chiti… Unas…
##  8 ASV_2562 5              27     26.4 Bacteria Bacter… Sphi… Sphi… Chiti… Unas…
##  9 ASV_2848 5              27     26.5 Bacteria Planct… Plan… Plan… Planc… Unas…
## 10 ASV_2844 5              27     26.5 Bacteria Proteo… Unas… Unas… Unass… Unas…
## # ℹ 21 more rows
## # ℹ 1 more variable: Species <chr>
graph_obj_info$edge_info      # edges between module-5 nodes
## # A tibble: 330 × 5
##    from     to      weight correlation corr_direction
##    <chr>    <chr>    <dbl>       <dbl> <chr>         
##  1 ASV_244  ASV_367  0.949       0.949 Positive      
##  2 ASV_1119 ASV_244  0.952       0.952 Positive      
##  3 ASV_1531 ASV_244  0.965       0.965 Positive      
##  4 ASV_649  ASV_322  0.958       0.958 Positive      
##  5 ASV_705  ASV_322  0.954       0.954 Positive      
##  6 ASV_913  ASV_322  0.954       0.954 Positive      
##  7 ASV_996  ASV_322  0.949       0.949 Positive      
##  8 ASV_1234 ASV_322  0.962       0.962 Positive      
##  9 ASV_1373 ASV_322  0.958       0.958 Positive      
## 10 ASV_1479 ASV_322  0.958       0.958 Positive      
## # ℹ 320 more rows

4.3 Sub-network (sample) information

# ---- 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" (rownames must match node names)
  select_sample = colnames(otu_rare_relative)[1:3], # sample IDs to merge into one subgraph (here: first 3 samples)
  combine       = "union"                           # "union" = OTUs present in ANY selected sample; "intersect" = OTUs present in ALL
)
names(res)   # "sub_graph_all", "stat_sample", "sub_graph_select"
## [1] "sub_graph_all"    "stat_sample"      "sub_graph_select"
# ---- Inspect the merged 3-sample subgraph ----
res$sub_graph_select   # tbl_graph: nodes = union/intersect of present OTUs across the 3 samples
## # 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
graph_obj_info <- get_info_from_graph(graph_obj = res$sub_graph_select)

graph_obj_info$node_info   # node attributes + n_present_samples / present_in_samples columns
## # A tibble: 181 × 13
##    name     Modularity Degree Strength Kingdom  Phylum  Class Order Family Genus
##    <chr>    <ord>       <dbl>    <dbl> <chr>    <chr>   <chr> <chr> <chr>  <chr>
##  1 ASV_649  5              27     26.5 Bacteria Proteo… Alph… Rhiz… Unass… Unas…
##  2 ASV_705  5              27     26.5 Bacteria Actino… Acti… Acti… Cellu… Cell…
##  3 ASV_1234 5              27     26.5 Bacteria Gemmat… Gemm… Gemm… Gemma… Gemm…
##  4 ASV_1373 5              27     26.5 Bacteria Actino… Acti… Soli… Solir… Soli…
##  5 ASV_1479 5              27     26.5 Bacteria Verruc… Spar… Unas… Unass… Spar…
##  6 ASV_1481 5              27     26.5 Bacteria Proteo… Gamm… Unas… Unass… Unas…
##  7 ASV_2453 5              27     26.5 Bacteria Bacter… Sphi… Sphi… Chiti… Unas…
##  8 ASV_2562 5              27     26.4 Bacteria Bacter… Sphi… Sphi… Chiti… Unas…
##  9 ASV_2848 5              27     26.5 Bacteria Planct… Plan… Plan… Planc… Unas…
## 10 ASV_2844 5              27     26.5 Bacteria Proteo… Unas… Unas… Unass… Unas…
## # ℹ 171 more rows
## # ℹ 3 more variables: Species <chr>, n_present_samples <int>,
## #   present_in_samples <chr>
graph_obj_info$edge_info   # induced edges between surviving nodes
## # A tibble: 602 × 5
##    from    to       weight correlation corr_direction
##    <chr>   <chr>     <dbl>       <dbl> <chr>         
##  1 ASV_6   ASV_39    0.959       0.959 Positive      
##  2 ASV_20  ASV_2911  0.957       0.957 Positive      
##  3 ASV_172 ASV_43    0.969       0.969 Positive      
##  4 ASV_614 ASV_65    0.943       0.943 Positive      
##  5 ASV_69  ASV_173   0.995       0.995 Positive      
##  6 ASV_69  ASV_206   0.994       0.994 Positive      
##  7 ASV_69  ASV_744   0.976       0.976 Positive      
##  8 ASV_945 ASV_69    0.985       0.985 Positive      
##  9 ASV_69  ASV_1418  0.975       0.975 Positive      
## 10 ASV_69  ASV_2350  0.967       0.967 Positive      
## # ℹ 592 more rows