J. Doe
J. Doe

Reputation: 619

Applying threshold on specific vertices' weight

Given the dataframe:

> dput(rel.matrix)
structure(list(from = c("A", "A", "A", "A", "B", "B", "B", "B", 
"C", "C", "C", "C", "C", "C", "D", "D", "D", "D", "E", "E", "E", 
"E", "F", "F", "F", "F", "F", "F", "G", "G", "G", "G", "H", "H", 
"H", "H", "I", "I", "I", "I", "J", "J", "J", "J", "K", "K"), 
    to = c("B", "C", "D", "E", "A", "C", "D", "E", "A", "B", 
    "D", "E", "F", "K", "A", "B", "C", "E", "A", "B", "C", "D", 
    "C", "G", "H", "I", "J", "K", "F", "H", "I", "J", "F", "G", 
    "I", "J", "F", "G", "H", "J", "F", "G", "H", "I", "C", "F"
    ), weight = c(0.09137056, 0.2677665, 0.09137056, 0.09137056, 
    0.09137056, 0.09517766, 0.02284264, 0.02284264, 0.2677665, 
    0.09517766, 0.09517766, 0.09517766, 0.3730964, 0.1675127, 
    0.09137056, 0.02284264, 0.09517766, 0.02284264, 0.09137056, 
    0.02284264, 0.09517766, 0.02284264, 0.3730964, 0.09517766, 
    0.09517766, 0.2677665, 0.09517766, 0.1675127, 0.09517766, 
    0.02284264, 0.09137056, 0.02284264, 0.09517766, 0.02284264, 
    0.09137056, 0.02284264, 0.2677665, 0.09137056, 0.09137056, 
    0.09137056, 0.09517766, 0.02284264, 0.02284264, 0.09137056, 
    0.1675127, 0.1675127)), row.names = c(NA, -46L), class = "data.frame")

and two sets of nodes

> dput(soi)
c("A", "I", "G")
> dput(all_nodes)
c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K")

I'm having the following function that, applies a threshold on the weights' nodes, gives different node's color between the nodes of soi and all_nodes variables and finally, plots the graph out.

The thing now is that as you can see, the threshold is applied to all of the nodes' weights regardless of the set (soi OR all_nodes) they belong to. That has as the result to remove vertices from the plot that belong to soi set and that is something that I don't want.

Actually, I want to plot out all the vertices that belong to soi set and filter using the threshold only the ones that don't belong to soi which are the setdiff(all_nodes,soi).

Here is the function.

graph_rel_network <- function ( rel.matrix, nodes.names, soi.names, threshold )
{
  # setup vertices meta data which contain soi and not soi
  meta <- cbind( nodes.names, issoi = nodes.names %in% soi.names )

  # read in a graph: the weights are in the edge attributes
  g <- igraph::graph_from_data_frame(rel.matrix, directed = TRUE, vertices =  meta)
  g <- as.undirected(g, mode = "collapse")
  # rescale weights
  E(g)$weight2 <- 9 * E(g)$weight / max(E(g)$weight)

  # remove edges acoarding to the threshold
  g_sub <- delete.edges(g, E(g)[weight2 <= threshold ])

  # remove vertices with 0 degree
  g_sub <- delete.vertices(simplify(g_sub), degree(g_sub)==0)

  # color vertices that belongs to soi
  V(g_sub)$color <- ifelse(V(g_sub)$issoi == TRUE, "gold", "tomato")

  # plot the graph
  plot.igraph( g_sub,
               edge.width=E(g_sub)$weight2,
               vertex.label.dist=0,
               vertex.frame.color="gray",
               vertex.label.color="black")

  legend(x=-1.5, y=-1.1,
         c("Nodes of interest","Most Relevant nodes"),
         pch=21,
         pt.bg= c('gold','tomato'),
         pt.cex=2,
         cex=1,
         bty="n",
         ncol=1)

}

For example, you can execute graph_rel_network( rel.matrix, all_nodes, soi, 3)

and in the final plot node, G will not be appeared while it belongs to soi.

Is there any way NOT to filter the soi nodes?

Upvotes: 0

Views: 513

Answers (1)

emilliman5
emilliman5

Reputation: 5966

To retain all soi nodes you just need to add a bit of logic to the delete.vertices call:

graph_rel_network <- function (rel.matrix, nodes.names, soi.names, threshold )
{
  # setup vertices meta data which contain soi and not soi
  ###changed meta to a data.frame so that issoi is stored as logical instead of character
  meta <- data.frame(nodes.names, issoi = nodes.names %in% soi.names )  
  # read in a graph: the weights are in the edge attributes
  g <- igraph::graph_from_data_frame(rel.matrix, directed = TRUE, vertices =  meta)
  g <- as.undirected(g, mode = "collapse")

  # rescale weights
  E(g)$weight2 <- 9 * E(g)$weight / max(E(g)$weight)

  ###Create a subnetwork of soi nodes only
  g_soi  <- induced_subgraph(g, vids = V(g)[V(g)$name %in% soi.names])
  # remove edges acoarding to the threshold
  g_sub <- delete.edges(g, E(g)[E(g)$weight2 <= threshold])

  # remove vertices with 0 degree
  g_sub <- delete.vertices(g_sub, (degree(g_sub)==0 & !V(g)$issoi))

  ###Merge the tresholded allnode network with the soi network
  g_merge <- union(g_sub, g_soi)

  ###Resolve some attribute naming conflicts from the merge
  E(g_merge)$weight2 <- colMeans(rbind(E(g_merge)$weight2_2, E(g_merge)$weight2_1), na.rm = T)
  # color vertices that belongs to soi
  V(g_merge)$color <- ifelse(V(g_merge)$issoi_1, "gold", "tomato")

  # plot the graph
  plot.igraph( g_merge,
               edge.width=E(g_merge)$weight2,
               vertex.label.dist=0,
               vertex.frame.color="gray",
               vertex.label.color="black")

  legend(x=-1.5, y=-1.1,
         c("Nodes of interest","Most Relevant nodes"),
         pch=21,
         pt.bg= c('gold','tomato'),
         pt.cex=2,
         cex=1,
         bty="n",
         ncol=1)

}

enter image description here

Upvotes: 1

Related Questions