# Network modularity

**URL:** <https://igraph.discourse.group/t/network-modularity/1356>\
**Category:** Usage\
**Tags:** R\
**Created:** [13 September 2022 09:04 UTC](https://igraph.discourse.group/t/network-modularity/1356 "2022-09-13T09:04:47Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![dg.aragones](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/dg.aragones/32/586_2.png) [@dg.aragones](https://igraph.discourse.group/u/dg.aragones)\
**Post date:** [13 September 2022 09:04 UTC](https://igraph.discourse.group/t/network-modularity/1356/1 "2022-09-13T09:04:47Z")

</div>

I have been exploring recently the igraph (R) documentation, because I’m interested in calculating network modularities for undirected weighted graphs. Currently, I have that calculations done in Mathematica:

```auto
GraphAssortativity[G, FindGraphCommunities[G], 
   "Normalized" -> False]

```

Is there any way in which I can calculate this (or something similar) using the R implementation of igraph?

Thanks in advance for any advice.

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [13 September 2022 11:58 UTC](https://igraph.discourse.group/t/network-modularity/1356/2 "2022-09-13T11:58:55Z")

</div>

R/igraph 1.3 does not support calculating assortativity without normalization. This feature has been implemented in the recently released C/igraph 0.10, and will be present in whichever R/igraph is based on that (1.4 or 2.0). Until then, you would need to implement this calculation from scratch, if you need it.

---

<div class="post-metadata">

**Author:** ![dg.aragones](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/dg.aragones/32/586_2.png) [@dg.aragones](https://igraph.discourse.group/u/dg.aragones)\
**Post date:** [15 September 2022 09:01 UTC](https://igraph.discourse.group/t/network-modularity/1356/3 "2022-09-15T09:01:43Z")

</div>

Thank you for your answer! It’s good that it will be avaible in the future. I will try to implement it from scratch, as you suggested.

---

<div class="post-metadata">

**Author:** ![dg.aragones](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/dg.aragones/32/586_2.png) [@dg.aragones](https://igraph.discourse.group/u/dg.aragones)\
**Post date:** [21 September 2022 18:22 UTC](https://igraph.discourse.group/t/network-modularity/1356/4 "2022-09-21T18:22:34Z")

</div>

I have tried to implement it from scratch using R/igraph. This is my code using a simple example:

```auto
edgelist = matrix(c(1,3, 2,1, 3,6, 4,6, 1,5, 5,4, 6,1), 
                  nrow=7, ncol=2, byrow=TRUE) # Example edge list

G = igraph::graph_from_edgelist(edgelist) # Graph created

igraph::E(G)$weight = c(0.1, 0.2, 0.2, 0.15, 0.3, 0.3, 0.1) # Added weights

communities = c(1,1,2,2,2,2) # Example communities

m = igraph::gsize(G) # Total number of edges

k = igraph::strength(G) # Weighted degrees

delta = outer(communities, communities, FUN="==") # 1 if same community, else 0

w = igraph::as_adjacency_matrix(G, type="both", attr="weight", sparse=FALSE) # Weighted adjacency matrix

modularity = 1/(2*m) * sum((w - k %o% k / (2*m)) * delta) # Modularity

```

Using this code, I obtained `Q = 0.0401`, while in Mathematica and Python I obtained `Q = 0.0741`.

I tried the first equation that can be found in the [NetworkX documentation](https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.community.quality.modularity.html). However, I haven’t obtained the same results.

Do you know why this R/igraph code gives a different result?

Thanks in advance for any help.

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [21 September 2022 19:00 UTC](https://igraph.discourse.group/t/network-modularity/1356/5 "2022-09-21T19:00:41Z")

</div>

I’m sorry, I have to correct what I said above. The non-normalized “nominal” assortativity is actually the same as modularity, just as you show in your last post. So you can use `modularity` in R/igraph.

```r
> modularity(G, communities, weights=E(G)$weight, directed = T)
[1] 0.09876543
> modularity(G, communities, weights=E(G)$weight, directed = F)
[1] 0.07407407

```

The default calculation is directed for directed graphs, which is what you have here. So use `directed=F` if you want undirected.

The assortativity implementation in C/igraph 0.10 which I mentioned does not actually support weights. So if you need weights, then you’d have to use `modularity()` anyway.

Comparison with Mathematica and IGraph/M:

```auto
In[352]:= 
edges = Partition[{1, 3, 2, 1, 3, 6, 4, 6, 1, 5, 5, 4, 6, 1}, 2];

In[353]:= weights = {0.1, 0.2, 0.2, 0.15, 0.3, 0.3, 0.1};

In[354]:= membership = {1, 1, 2, 2, 2, 2};

In[355]:= 
g = Graph[Range[6], DirectedEdge @@@ edges, EdgeWeight -> weights];

In[356]:= communities = IGMembershipToPartitions[g, membership]
Out[356]= {{1, 2}, {3, 4, 5, 6}}

In[357]:= IGModularity[g, communities, DirectedEdges -> True]
Out[357]= 0.0987654

In[358]:= IGModularity[g, communities, DirectedEdges -> False]
Out[358]= 0.0740741

In[359]:= GraphAssortativity[g, communities, "Normalized" -> False]
Out[359]= 0.0987654

```

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [21 September 2022 19:01 UTC](https://igraph.discourse.group/t/network-modularity/1356/6 "2022-09-21T19:01:46Z")

</div>

Regarding your code, the problems are:

- `m` should be the sum of weights
- There’s a mix of directed an undirected concepts. `k` is undirected because `mode='all'` was the default. `w` is directed because the graph itself is directed.

Here’s an implementation of the directed version:

```r
m = sum(E(G)$weight) # Total number of edges

kin = igraph::strength(G, mode='in') # Weighted degrees
kout = igraph::strength(G, mode='out') # Weighted degrees

delta = outer(communities, communities, FUN="==") # 1 if same community, else 0

w = igraph::as_adjacency_matrix(G, type="both", attr="weight", sparse=FALSE) # Weighted adjacency matrix

modularity = 1/m * sum((w - kin %o% kout / m) * delta) # Modularity

```

And undirected:

```r
m = sum(E(G)$weight) # Total number of edges

kin = igraph::strength(G, mode='all') # Weighted degrees

delta = outer(communities, communities, FUN="==") # 1 if same community, else 0

w = igraph::as_adjacency_matrix(igraph::as.undirected(G), type="both", attr="weight", sparse=FALSE) # Weighted adjacency matrix

modularity = 1/(2*m) * sum((w - k %o% k / (2*m)) * delta) # Modularity

```

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [21 September 2022 19:04 UTC](https://igraph.discourse.group/t/network-modularity/1356/7 "2022-09-21T19:04:57Z")

</div>

Finally, just in case you were not aware, python-igraph is igraph’s Python interface and IGraph/M is its Mathematica interface. You can use much of the igraph functionality from those languages as well.

---

<div class="post-metadata">

**Author:** ![dg.aragones](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/dg.aragones/32/586_2.png) [@dg.aragones](https://igraph.discourse.group/u/dg.aragones)\
**Post date:** [22 September 2022 09:21 UTC](https://igraph.discourse.group/t/network-modularity/1356/8 "2022-09-22T09:21:36Z")

</div>

Thank you so much for your time and attention.

It’s weird, but I hadn’t found the `modularity()` function in the R/igraph documentation. It’s good that it’s implemented, it is very useful.

Thank you also for checking my code. I see the problems now. It has been valuable for me to learn, despite being implemented at the end.

Great job working on igraph, congratulations!

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [22 September 2022 12:54 UTC](https://igraph.discourse.group/t/network-modularity/1356/9 "2022-09-22T12:54:22Z")

</div>

> [@dg.aragones](#):
>
> It’s weird, but I hadn’t found the `modularity()` function in the R/igraph documentation.

You can look for functions in the index: [igraph R manual pages](https://igraph.org/r/doc/). The documentation does need some updates and editing, but `modularity` is mostly fine.
