Search code examples
rigraphsocial-networking

igraph: discount edge weights based on node attributes


I have an undirected network with edge weights. each node has an attribute "group". I want to change the existing weights discounting those edges between nodes within the same group.

for instance if node1 and node2 have an edge weight of 10 and they both have attribute "group" equal to "A" then i want to divide the weight by - let's say- 2 , if not (they have belong to different groups) their weight shall remain 10.

I am not sure how to proceed.

I can visuaize the weights using E(g)$weight and the attributes with V(g)$group, but I can't think of a way to make to use the vertex attributes to change edge weights.


Solution

  • You can use the igraph::%--% operator to help. As in your example: if both vertices are in group A, divide weight by 2

    v_a <- which(V(g)$group == "A")  # All vertices in group A
    e_a <- E(g)[v_a %--% v_a]  # All edges between those vertices
    
    edge_attr(g)$weight[e_a] <- edge_attr(g)$weight[e_a] / 2
    

    If each group is handled in a similar way, you can use a for-loop. In this example, you divide the weight by some constant, depending on which group its vertices are in.

    group_constants <- c("A" = 2, "B" = 20, "C" = 200)
    
    for (i in unique(V(g)$group)) {
      v_a <- which(V(g)$group == i)
      e_a <- E(g)[v_a %--% v_a]
      
      edge_attr(g)$weight[e_a] <- edge_attr(g)$weight[e_a] / group_constants[i]
    }
    

    Here's the data I used. It's an undirected graph with vertex groups and edge weights.

    verts <- letters[1:10]
    
    g_df <- data.frame(
      from = sample(verts, 15, replace = TRUE),
      to = sample(verts, 15, replace = TRUE),
      weight = sample(1:10, 15, replace = TRUE)
    )
    
    g_df_v <- data.frame(
      name = verts,
      group = sample(LETTERS[1:3], 10, replace = TRUE)
    )
    
    g <- graph_from_data_frame(g_df, directed = FALSE, vertices = g_df_v)
    
    # Edges
    #    from to weight
    # 1     h  i      5
    # 2     i  e      9
    # 3     d  i      8
    # 4     c  a     10
    # 5     f  c      7
    # 6     a  b      5
    # 7     j  i      1
    # 8     j  b      8
    # 9     a  f      4
    # 10    h  i      7
    # 11    g  a      7
    # 12    f  b      6
    # 13    e  c      8
    # 14    b  f      4
    # 15    g  c      8
    
    # Vertices
    #    name group
    # 1     a     C
    # 2     b     B
    # 3     c     C
    # 4     d     B
    # 5     e     A
    # 6     f     A
    # 7     g     A
    # 8     h     B
    # 9     i     B
    # 10    j     B