I am trying to calculate network indexes (clustering, modularity, edge density, degree, centrality etc) from 1000 simulated null matrices using the igraph package in R. The data I'm using is a mixed-species bird flock data that I've used to generate the null matrices.
Here's the code:
## Construct null matrices ##
library(EcoSimR)
library(igraph)
# creating a 1000 empty matrices
fl_emp <- lapply(1:1000, function(i) data.frame())
# simulating 1000 matrices by randomization
fl_wp_n <- replicate(1000, sim5(fl_wp[,3:ncol(fl_wp)]),simplify = FALSE) #fl_wp is the raw data
#sim5 function is from the package 'EcoSimR'
for(i in 1:length(fl_emp))
{
fl_wp_ig <- graph_from_incidence_matrix(fl_wp_n[[i]]) #Creating new igraph object to convert the null matrices to igraph objects to calculate network indexes
fl_wp_cw <- cluster_walktrap(fl_wp_ig[[i]])
fl_wp_mod <- modularity(fl_wp_cw[[i]]) ##Network index, this does not work
}
Here's what the simulated matrices look like(fl_wp_n) : [1]: https://i.stack.imgur.com/1Q0Na.png
It is basically a list of 1000 elements, where each element is a simulated 133x74 matrix where the rows represent flock ID and the columns represent Species ID.
This is the error I'm getting when I run the loop:
> for(i in 1:length(fl_emp))
{
fl_wp_ig <- graph_from_incidence_matrix(fl_wp_n[[i]])
fl_wp_cw <- cluster_walktrap(fl_wp_ig[[i]])
fl_wp_mod <- modularity(fl_wp_cw[[i]])
}
Error in cluster_walktrap(fl_wp_ig[[i]]) : Not a graph object!
It seems to be not recognizing fl_wp_ig as an igraph object. Any idea why? Is there a better way to do calculate indices for a 1000 matrices in one loop? Sorry if this is a dumb question, I'm new to igraph and R in general
Thanks a lot in advance!
CodePudding user response:
If you have a look at the documentation for 1. cluster_walktrap, you will see the function expects a graph object. As @Szabolcs pointed out, when you are index fl_wp_ig[[i]]
in the for-loop, you are returning the vertices adjacent to vertex [[i]], but not the graph itself. You only should iterate over fl_wp_n[[i]]
because you want to use every time a 'matrix' but not the other variables.
So you could try:
list_outputs = list()
for(i in 1:length(fl_emp))
{
# fl_wp_n[[i]] gets 1 matrix each iteration. Output -> graph object
fl_wp_ig <- graph_from_incidence_matrix(fl_wp_n[[i]])
# Use the whole graph object fl_wp_ig
fl_wp_cw <- cluster_walktrap(fl_wp_ig)
# Use the whole fl_wp_cw output
fl_wp_mod <- modularity(fl_wp_cw)
# NOTE that you are not storing the result of each iteration in a variable to keep it,
# you are overwritting fl_wp_mod
# You could have create a empty list before the for-loop and then fill it
list_outputs = append(list_outputs, fl_wp_mod)
}
Also, if you find it difficult to see the whole picture, you could try to create a custom function and use apply
methods instead of a for-loop.
# Custom function
cluster_modularity = function(graph_object){
# takes only one graph_object at time
fl_wp_ig <- graph_from_incidence_matrix(graph_object)
fl_wp_cw <- cluster_walktrap(fl_wp_ig)
fl_wp_mod <- modularity(fl_wp_cw)
}
# Iterate using lapply to store the outputs in a list - for example
list_outputs = lapply(fl_wp_n, cluster_modularity)