This tutorial illustrates how to use the enaR
package to
perform a selected structural analyses on an ecosystem model.
Load and select a model to analyze
# load data
data(enaModels) # load library of Ecosystem Networks
names(enaModels) # view model names
#> [1] "Marine Coprophagy (oyster)"
#> [2] "Lake Findley "
#> [3] "Mirror Lake"
#> [4] "Lake Wingra"
#> [5] "Marion Lake"
#> [6] "Cone Springs"
#> [7] "Silver Springs"
#> [8] "English Channel"
#> [9] "Oyster Reef "
#> [10] "Baie de Somme"
#> [11] "Bothnian Bay"
#> [12] "Bothnian Sea"
#> [13] "Ythan Estuary"
#> [14] "Sundarban Mangrove (virgin)"
#> [15] "Sundarban Mangrove (reclaimed)"
#> [16] "Baltic Sea"
#> [17] "Ems Estuary"
#> [18] "Swartkops Estuary 15"
#> [19] "Southern Benguela Upwelling"
#> [20] "Peruvian Upwelling"
#> [21] "Crystal River (control)"
#> [22] "Crystal River (thermal)"
#> [23] "Charca de Maspalomas Lagoon"
#> [24] "Northern Benguela Upwelling"
#> [25] "Swartkops Estuary"
#> [26] "Sunday Estuary"
#> [27] "Kromme Estuary"
#> [28] "Okefenokee Swamp"
#> [29] "Neuse Estuary (early summer 1997)"
#> [30] "Neuse Estuary (late summer 1997) "
#> [31] "Neuse Estuary (early summer 1998)"
#> [32] "Neuse Estuary (late summer 1998)"
#> [33] "Gulf of Maine"
#> [34] "Georges Bank"
#> [35] "Middle Atlantic Bight"
#> [36] "Narragansett Bay"
#> [37] "Southern New England Bight"
#> [38] "Chesapeake Bay"
#> [39] "Mondego Estuary (Zostera sp. Meadows)"
#> [40] "Mdloti Estuary (C, March 2002)"
#> [41] "St. Marks Seagrass, site 1 (Jan.)"
#> [42] "St. Marks Seagrass, site 1 (Feb.)"
#> [43] "St. Marks Seagrass, site 2 (Jan.)"
#> [44] "St. Marks Seagrass, site 2 (Feb.)"
#> [45] "St. Marks Seagrass, site 3 (Jan.)"
#> [46] "St. Marks Seagrass, site 4 (Feb.)"
#> [47] "Sylt-Romo Bight (C)"
#> [48] "Graminoids (wet)"
#> [49] "Graminoids (dry)"
#> [50] "Cypress (wet)"
#> [51] "Cypress (dry)"
#> [52] "Lake Oneida (pre-ZM)"
#> [53] "Lake Oneida (post-ZM)"
#> [54] "Bay of Quinte (pre-ZM)"
#> [55] "Bay of Quinte (post-ZM)"
#> [56] "Mangroves (wet)"
#> [57] "Mangroves (dry)"
#> [58] "Florida Bay (wet)"
#> [59] "Florida Bay (dry)"
#> [60] "Hubbard Brook (Ca)(Waide)"
#> [61] "Hardwood Forest, NH (Ca)"
#> [62] "Duglas Fir Forest, WA (Ca)"
#> [63] "Duglas Fir Forest, WA (K)"
#> [64] "Puerto Rican Rain Forest (Ca)"
#> [65] "Puerto Rican Rain Forest (K)"
#> [66] "Puerto Rican Rain Forest (Mg)"
#> [67] "Puerto Rican Rain Forest (Cu)"
#> [68] "Puerto Rican Rain Forest (Fe)"
#> [69] "Puerto Rican Rain Forest (Mn)"
#> [70] "Puerto Rican Rain Forest (Na)"
#> [71] "Puerto Rican Rain Forest (Sr)"
#> [72] "Tropical Rain Forest (N)"
#> [73] "Neuse River Estuary (N, AVG)"
#> [74] "Neuse River Estuary (N, Spring 1985)"
#> [75] "Neuse River Estuary (N, Summer 1985)"
#> [76] "Neuse River Estuary (N, Fall 1985)"
#> [77] "Neuse River Estuary (N, Winter 1986)"
#> [78] "Neuse River Estuary (N, Spring 1986)"
#> [79] "Neuse River Estuary (N, Summer 1986)"
#> [80] "Neuse River Estuary (N, Fall 1986)"
#> [81] "Neuse River Estuary (N, Winter 1987)"
#> [82] "Neuse River Estuary (N, Spring 1987)"
#> [83] "Neuse River Estuary (N, Summer 1987)"
#> [84] "Neuse River Estuary (N, Fall 1987)"
#> [85] "Neuse River Estuary (N, Winter 1988)"
#> [86] "Neuse River Estuary (N, Spring 1988)"
#> [87] "Neuse River Estuary (N, Summer 1988)"
#> [88] "Neuse River Estuary (N, Fall 1988)"
#> [89] "Neuse River Estuary (N, Winter 1989)"
#> [90] "Cape Fear River Estuary (N, oligohaline)"
#> [91] "Cape Fear River Estuary (N, polyhaline)"
#> [92] "Lake Lanier (P) Averaged"
#> [93] "Great Lakes (N)"
#> [94] "Baltic Sea (N)"
#> [95] "Chesapeake Bay (N)"
#> [96] "Chesapeake Bay (P)"
#> [97] "Chesapeake Bay (P, Winter)"
#> [98] "Chesapeake Bay (P, Spring)"
#> [99] "Chesapeake Bay (P, Summer)"
#> [100] "Chesapeake Bay (P, Fall)"
#> [101] "Sylt-Romo Bight (N)"
#> [102] "Sylt-Romo Bight (P)"
#> [103] "Beijing Urban Metabolism (C)"
#> [104] "Vienna Urban Metabolism (C)"
NET <- enaModels[[9]] # select the Oyster Reef model (Dame & Patten 1981) and save it as NET
NET%v%'vertex.names'
#> [1] "Filter Feeders" "Microbiota" "Meiofauna"
#> [4] "Deposit Feeders" "Predators" "Deposited Detritus"
This gives us a model to analyze. If you have your own model to analyze, you can use it instead.
As a first step in our analysis, lets find the size of the network, the number of edges, its conductance or network density, and a metric called link density.
# --- NETWORK DESCRIPTIVE STATISTICS ---
# example analyses
n <- network.size(NET) # number of nodes
L <- network.edgecount(NET) # number of edges (links)
C <- L/n^2 # connectance
LD <- L/n # link density (average links per node)
ns <- c("n"=n, "L"=L, "C"=C, "LD"=LD) # create a summary vector of the network statistics
show(ns)
#> n L C LD
#> 6.0000000 12.0000000 0.3333333 2.0000000
This tells us that the Oyster Reef model has 6 nodes and an edge density of 0.33. On average, there are two edges per node in the network. We can also extract the Adjacency matrix from the model as follows
A <- as.matrix(NET) # get adjacency matrix
show(A)
#> Filter Feeders Microbiota Meiofauna Deposit Feeders
#> Filter Feeders 0 0 0 0
#> Microbiota 0 0 1 1
#> Meiofauna 0 0 0 1
#> Deposit Feeders 0 0 0 0
#> Predators 0 0 0 0
#> Deposited Detritus 0 1 1 1
#> Predators Deposited Detritus
#> Filter Feeders 1 1
#> Microbiota 0 0
#> Meiofauna 0 1
#> Deposit Feeders 1 1
#> Predators 0 1
#> Deposited Detritus 0 0
The elements of the adjacency matrix are 1 if there is a direct connection from node i to j. Otherwise, the element is zero.
Distance
We can use tools from the network package to learn more about the graph. For example we can find the geodesic distance between each of the nodes (ignoring edge weights).
# -- DISTANCE ---
geodist(NET) # returns counts of geodesics and length of geodesics
#> $counts
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 1 1 1 1 1 1
#> [2,] 0 1 1 1 1 2
#> [3,] 0 1 1 1 1 1
#> [4,] 0 1 1 1 1 1
#> [5,] 0 1 1 1 1 1
#> [6,] 0 1 1 1 1 1
#>
#> $gdist
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 0 2 2 2 1 1
#> [2,] Inf 0 1 1 2 2
#> [3,] Inf 2 0 1 2 1
#> [4,] Inf 2 2 0 1 1
#> [5,] Inf 2 2 2 0 1
#> [6,] Inf 1 1 1 2 0
This tells us that the maximum geodesic distance from nodes 2, 3, 4, 5, and 6 to the others is a walk of length 2, but that node 1 is unreachable from the other nodes. While there is a single geodesic between most of the nodes, there are two walks of length 2 from node 2 (Microbiota) to node 6 (Deposited Detritus).
Degree
We can also find the unweighted node degree (positional importance). As this is a directed network, we can find the input, output, and total degree
Using enaStructure()
The enaR
package includes a function that extracts the
adjacency matrix and calculates a number of network statistics.
s <- enaStructure(NET)
attributes(s)
#> $names
#> [1] "A" "ns"
show(s$A)
#> Filter Feeders Microbiota Meiofauna Deposit Feeders
#> Filter Feeders 0 0 0 0
#> Microbiota 0 0 1 1
#> Meiofauna 0 0 0 1
#> Deposit Feeders 0 0 0 0
#> Predators 0 0 0 0
#> Deposited Detritus 0 1 1 1
#> Predators Deposited Detritus
#> Filter Feeders 1 1
#> Microbiota 0 0
#> Meiofauna 0 1
#> Deposit Feeders 1 1
#> Predators 0 1
#> Deposited Detritus 0 0
show(s$ns)
#> n L C LD ppr lam1A mlam1A rho R d
#> [1,] 6 12 0.3333333 2 2.147899 2.147899 1 2.147899 0.4655712 0.147899
#> no.scc no.scc.big pscc
#> [1,] 2 1 0.8333333