4 Anaylize networks with bipartite
The
bipartite package offers several powerful tools for the analysis of
bipartite networks.
As a preliminary step to integrate Web of life with this package, one needs to convert network data into a bipartite graph (see Section 2.4).
For instance, after having downloaded and converted the relative data into an incidence matrix, one can visualize the network M_SD_002 using the function plotweb()
the bipartite package:
# import the bipartite package (if not done at the beginning)
library(bipartite)
plotweb(inc_matrix)
The two groups of species within this bipartite network are shown on different layers: seed dispersers (top) and plants (bottom).
Bipartite also offer also the the function visweb()
to visualize the incidence matrix:
visweb(inc_matrix)
4.1 Network-level indices
Among other network properties, some indices characterizing an entire network can be computed calling the function networklevel()
of the
bipartite package.
Here we just focus on the connectance.
The definition of connectance given at the beginning of Chapter 3 can be generalized to any bipartite network replacing:
plants \(\Rightarrow\) resources
animals \(\Rightarrow\) consumers
According to our convention, resources correspond to the rows of the incidence matrix while consumers to the columns. Counting the number of links, rows, and columns of the incidence matrix the connectance can readily be estimated.
Alternatively, one can obtain this index calling the function networklevel()
.
It is instructive to show how the connectance of the bipartite networks present in Web of life (i.e., all but foodwebs) can be computed with both approaches. In code, this is done as follows
<- "https://www.web-of-life.es/"
base_url
# download all the networks
<- paste0(base_url,"get_networks.php")
json_url <- jsonlite::fromJSON(json_url)
all_nws head(all_nws)
# create a list of networks names filtering out food-webs
<- distinct(all_nws, network_name) %>%
nw_names ::filter(., !(network_name %like% "FW_"))
dplyr
# initialize dataframe to store results
<- NULL
connectance_df
for (nw_name in nw_names$network_name){
<- filter(all_nws, network_name == nw_name)
nw <- nw %>% nrow()
links
# select the 3 relevant columns and create the igraph object
<- nw %>% select(species1, species2, connection_strength) %>%
my_graph graph_from_data_frame(directed = FALSE)
<- from_wol_graph_to_incidence_matrix(base_url, nw_name, my_graph, inc_matrix)
inc_matrix
<- networklevel(inc_matrix,
nw_prop_bipartite index=c("connectance"),
SAmethod="log")
<- nrow(inc_matrix)
resources_num <- ncol(inc_matrix)
consumers_num <- links/(resources_num*consumers_num)
conn
<- data.frame(nw_name,
connectance_row
resources_num,
consumers_num,
conn,"connectance"])
nw_prop_bipartite[
<- rbind(connectance_df, connectance_row)
connectance_df
print(paste0("connectance of ", nw_name, " network"))
}
rownames(connectance_df) <- NULL
colnames(connectance_df) <- NULL
colnames(connectance_df) <- c("network_name",
"num_resources",
"num_consumers",
"connectance",
"bipartite_connectance")
where we have gathered all the commands to convert the igraph object my_graph into a bipartirte graph and, subsequently, into
an incidence matrix within the function from_wol_graph_to_incidence_matrix()
, which reads
<- function(base_url, nw_name, wol_graph, inc_mat){
from_wol_graph_to_incidence_matrix
# get info about species
<- read.csv(paste0(base_url,"get_species_info.php?network_name=",nw_name))
my_info
<- my_info$is.resource %>% as.logical() # 0/1 converted to FALSE/TRUE
isResource
# Add the "type" attribute to the vertices of the graph
V(wol_graph)$type <- !(isResource)
# convert the igraph object into incidence matrix
<- as_incidence_matrix(
inc_mat
wol_graph,attr = "connection_strength",
names = TRUE,
sparse = FALSE
)
# convert elements into numeric values
class(inc_mat) <-"numeric"
# remove NA values (previous empty strings)
which(is.na(inc_mat) == T)]<-0
inc_mat[
return(inc_mat)
}
The reader can appreciate the perfect agreement between the two approaches running the command below.
%>% formattable() connectance_df
To let the function networklevel()
return multiple indices, one has to pass them to the index
argument as a vector:
networklevel(inc_matrix, index=c("connectance", "nestedness","weighted nestedness","compartment diversity","Shannon diversity"), SAmethod="log")
The reader is addressed to the bipartite manual to get more information about the network properties that can be computed using this package and about their definitions.