2

I have a graph object (a weighted network), where nodes belong to different modularity classes defined in a dataframe. I would like to calculate a node's number of links to other nodes in all different modules (its own module and every other module).

How I can write this calculation based on my graph object g and my dataframe modules?. My expected output is a dataframe with each node's (country's) links to module 1, module 2, module 3, etc. Any help appreciated!

Reproducible example:

g <- structure(c(32, 12, 54, 0, 0, 0, 73, 0, 91, 0, 0, 65.27657092, 99, 
                 76, 0, 0, 0, 36.95395031, 0, 88, 44, 0, 0, 86.09277176, 0, 0, 0, 
                 84, 11, 0, 0, 0, 0, 0, 45, 0), .Dim = c(6L, 6L), .Dimnames = list(
                   c("Indonesia", "Iran (Islamic Republic of)", "Iraq", "Ireland", 
                     "Israel", "Italy"), c("Indonesia", "Iran..Islamic.Republic.of.", 
                                           "Iraq", "Ireland", "Israel", "Italy")))                                                                                                                      

library(igraph)
g <- graph_from_adjacency_matrix(g)

modules <- structure(list(Label = structure(73:78, .Label = c("Afghanistan", 
                                                   "Albania", "Algeria", "Angola", "Antigua and Barbuda", "Argentina", 
                                                   "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahrain", 
                                                   "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", 
                                                   "Bhutan", "Bolivia (Plurinational State of)", "Bosnia and Herzegovina", 
                                                   "Botswana", "Brazil", "Brunei Darussalam", "Bulgaria", "Burkina Faso", 
                                                   "Burundi", "C?te d'Ivoire", "Cambodia", "Cameroon", "Canada", 
                                                   "Central African Republic", "Chile", "China", "China, Hong Kong SAR", 
                                                   "China, Macao SAR", "China, Taiwan Province of", "Colombia", 
                                                   "Congo", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czechia", 
                                                   "Democratic People's Republic of Korea", "Democratic Republic of the Congo", 
                                                   "Denmark", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", 
                                                   "Eritrea", "Estonia", "Eswatini", "Ethiopia", "Finland", "France", 
                                                   "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Greece", "Grenada", 
                                                   "Guatemala", "Guinea", "Guinea-Bissau", "Guyana", "Haiti", "Honduras", 
                                                   "Hungary", "India", "Indonesia", "Iran (Islamic Republic of)", 
                                                   "Iraq", "Ireland", "Israel", "Italy", "Jamaica", "Japan", "Jordan", 
                                                   "Kazakhstan", "Kenya", "Kuwait", "Kyrgyzstan", "Lao People's Democratic Republic", 
                                                   "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Lithuania", 
                                                   "Luxembourg", "Madagascar", "Malawi", "Malaysia", "Mali", "Malta", 
                                                   "Mauritania", "Mexico", "Mongolia", "Montenegro", "Morocco", 
                                                   "Mozambique", "Myanmar", "Namibia", "Nepal", "Netherlands", "New Zealand", 
                                                   "Nicaragua", "Niger", "Nigeria", "North Macedonia", "Norway", 
                                                   "Oman", "Pakistan", "Palestine", "Panama", "Papua New Guinea", 
                                                   "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Qatar", 
                                                   "Republic of Korea", "Republic of Moldova", "Romania", "Russian Federation", 
                                                   "Rwanda", "Saint Kitts and Nevis", "Saint Lucia", "Saint Vincent and the Grenadines", 
                                                   "Saudi Arabia", "Senegal", "Serbia", "Sierra Leone", "Singapore", 
                                                   "Slovakia", "Slovenia", "Somalia", "South Africa", "Spain", "Sri Lanka", 
                                                   "Sudan", "Suriname", "Sweden", "Switzerland", "Syrian Arab Republic", 
                                                   "Tajikistan", "Thailand", "Timor-Leste", "Trinidad and Tobago", 
                                                   "Tunisia", "Turkey", "Turkmenistan", "Uganda", "Ukraine", "United Arab Emirates", 
                                                   "United Kingdom of Great Britain and Northern Ireland", "United Republic of Tanzania", 
                                                   "United States of America", "Uruguay", "Uzbekistan", "Venezuela (Bolivarian Republic of)", 
                                                   "Viet Nam", "Yemen", "Zambia", "Zimbabwe"), class = "factor"), 
               modularity_class = c(0L, 3L, 2L, 1L, 4L, 4L)), row.names = c("Indonesia", 
                                                                            "Iran (Islamic Republic of)", "Iraq", "Ireland", "Israel", "Italy"
               ), class = "data.frame")

zx8754
  • 52,746
  • 12
  • 114
  • 209
MoonS
  • 117
  • 7

1 Answers1

0

Update 2

If you want to have undirected graph with duplicated edges, you can try this code

g <- graph_from_adjacency_matrix(+(df > 0), diag = FALSE) %>%
    as.undirected() %>%
    set_vertex_attr(
        name = "module",
        value = with(modules, modularity_class[match(names(V(.)), Label)])
    )

out <- sapply(V(g), function(x) {
    m <- neighbors(g, x)$module
    table(m[m != V(g)[x]$module])
})

such that

> out
$Indonesia

2 3
1 1

$Iran

0 1 2 4
1 1 1 1

$Iraq

0 1 3 4 
1 1 1 1

$Ireland

2 3 4
1 1 2

$Israel

1
1

$Italy

1 2 3
1 1 1

Update

If you want to see the distribution, you can use table

sapply(V(g), function(x) {
    m <- neighbors(g, x)$module
    table(m[m != V(g)[x]$module])
})

which gives

$Indonesia

 2  3
99 73

$Iran

 0  1  2
12 88 76

$Iraq

 0  1  3
54 44 91

$Ireland

 4
84

$Israel
< table of extent 0 >

$Italy

 1  2  3
86 36 65

We can use set_vertex_attr to set vertex attribute with modularity_class in modules

g <- g %>%
    set_vertex_attr(
        name = "module",
        value = with(modules, modularity_class[match(names(V(.)), Label)])
    )

and then we find neighbors of each vertex and summarize with the counts of neighbors with different modularity class

out <- sapply(V(g), function(x) sum(neighbors(g, x)$module != V(g)[x]$module))[x]$module))

which gives

> out
Indonesia      Iran      Iraq   Ireland    Israel     Italy 
      172       176       189        84         0       187

data

df <- structure(c(
    32, 12, 54, 0, 0, 0, 73, 0, 91, 0, 0, 65.27657092, 99,
    76, 0, 0, 0, 36.95395031, 0, 88, 44, 0, 0, 86.09277176, 0, 0, 0,
    84, 11, 0, 0, 0, 0, 0, 45, 0
), .Dim = c(6L, 6L), .Dimnames = list(
    c(
        "Indonesia", "Iran", "Iraq", "Ireland",
        "Israel", "Italy"
    ), c(
        "Indonesia", "Iran",
        "Iraq", "Ireland", "Israel", "Italy"
    )
))

modules <- structure(list(
    Label = structure(73:78, .Label = c(
        "Afghanistan",
        "Albania", "Algeria", "Angola", "Antigua and Barbuda", "Argentina",
        "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahrain",
        "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin",
        "Bhutan", "Bolivia (Plurinational State of)", "Bosnia and Herzegovina",
        "Botswana", "Brazil", "Brunei Darussalam", "Bulgaria", "Burkina Faso",
        "Burundi", "C?te d'Ivoire", "Cambodia", "Cameroon", "Canada",
        "Central African Republic", "Chile", "China", "China, Hong Kong SAR",
        "China, Macao SAR", "China, Taiwan Province of", "Colombia",
        "Congo", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czechia",
        "Democratic People's Republic of Korea", "Democratic Republic of the Congo",
        "Denmark", "Dominican Republic", "Ecuador", "Egypt", "El Salvador",
        "Eritrea", "Estonia", "Eswatini", "Ethiopia", "Finland", "France",
        "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Greece", "Grenada",
        "Guatemala", "Guinea", "Guinea-Bissau", "Guyana", "Haiti", "Honduras",
        "Hungary", "India", "Indonesia", "Iran",
        "Iraq", "Ireland", "Israel", "Italy", "Jamaica", "Japan", "Jordan",
        "Kazakhstan", "Kenya", "Kuwait", "Kyrgyzstan", "Lao People's Democratic Republic",
        "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Lithuania",
        "Luxembourg", "Madagascar", "Malawi", "Malaysia", "Mali", "Malta",
        "Mauritania", "Mexico", "Mongolia", "Montenegro", "Morocco",
        "Mozambique", "Myanmar", "Namibia", "Nepal", "Netherlands", "New Zealand",
        "Nicaragua", "Niger", "Nigeria", "North Macedonia", "Norway",
        "Oman", "Pakistan", "Palestine", "Panama", "Papua New Guinea",
        "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Qatar",
        "Republic of Korea", "Republic of Moldova", "Romania", "Russian Federation",
        "Rwanda", "Saint Kitts and Nevis", "Saint Lucia", "Saint Vincent and the Grenadines",
        "Saudi Arabia", "Senegal", "Serbia", "Sierra Leone", "Singapore",
        "Slovakia", "Slovenia", "Somalia", "South Africa", "Spain", "Sri Lanka",
        "Sudan", "Suriname", "Sweden", "Switzerland", "Syrian Arab Republic",
        "Tajikistan", "Thailand", "Timor-Leste", "Trinidad and Tobago",
        "Tunisia", "Turkey", "Turkmenistan", "Uganda", "Ukraine", "United Arab Emirates",
        "United Kingdom of Great Britain and Northern Ireland", "United Republic of Tanzania",
        "United States of America", "Uruguay", "Uzbekistan", "Venezuela (Bolivarian Republic of)",
        "Viet Nam", "Yemen", "Zambia", "Zimbabwe"
    ), class = "factor"),
    modularity_class = c(0L, 3L, 2L, 1L, 4L, 4L)
), row.names = c(
    "Indonesia",
    "Iran", "Iraq", "Ireland", "Israel", "Italy"
), class = "data.frame")
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
  • Thank you so much! My expected output is however a node's number of links to module 1, module 2, module 3 etc. respectively rather than their aggregated weights which don't really matter. Eg. I can see that Ireland has 1 link to Isreal, which is in module 4. Is it possible to update the function accordingly? (Also, in the sapply function, I get the error message ```Error: unexpected ')' in "out <- sapply(V(g), function(x) sum(neighbors(g, x)$module != V(g)[x]$module))[x]$module)```".) – MoonS Jun 22 '21 at 08:29
  • Hm, I don't understand how I with this can see if a node has multiple links in the same module (don't the weights now become aggregated? I would like it to return a node's summed number of links in module 1, module 2, etc.)? Also, when I run it, I for some reason get ```< table of extent 0 >``` for all countries. – MoonS Jun 22 '21 at 08:48
  • @MoonS You should notice that your graph is directed. There is link from `Ireland` to `Israel`, but no backwards link. In this sense, the only neighbor of `Israel` is `Itlay`, which has the same modularity class with `Israel`, thus being dropped, That's why you see `< table of extent 0 >`. – ThomasIsCoding Jun 22 '21 at 09:50
  • Your latest update is exactly what I want! I however get this error message ```Error in df > 0 : comparison (6) is possible only for atomic and list types.``` Should something be changed? And thanks for the important note on direction, when I ran this previously I however got ```< table of extent 0 >``` for all countries, not only Ireland. – MoonS Jun 22 '21 at 10:28
  • @MoonS Did you try the data in my answer? – ThomasIsCoding Jun 22 '21 at 10:46
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/234067/discussion-between-moons-and-thomasiscoding). – MoonS Jun 22 '21 at 12:47