10

Consider a dataframe df where the first two columns are node pairs and successive columns V1, V2, ..., Vn represent flows between the nodes (potentially 0, implying no edge for that column's network). I would like to conduct analysis on degree, community detection, and other network measures using the flows as weights.

Then to analyze the graph with respect to the weights in V1 I do:

# create graph and explore unweighted degrees with respect to V1
g <- graph.data.frame( df[df$V1!=0,] )
qplot(degree(g))
x <- 0:max(degree(g))
qplot(x,degree.distribution(g))

# set weights and explore weighted degrees using V1
E(g)$weights <- E(g)$V1
qplot(degree(g))

The output from the third qplot is no different than the first. What am I doing wrong?

Update:

So graph.strength is what I am looking for, but graph.strength(g) in my case gives standard degree output followed by:

Warning message:
In graph.strength(g) :
At structural_properties.c:4928 :No edge weights for strength calculation,
normal degree

I must be setting the weights incorrectly, is it not sufficient to do E(g)$weights <- E(g)$V1 and why can g$weights differ from E(g)$weights?

mindless.panda
  • 4,014
  • 4
  • 35
  • 57
  • 2
    Re the difference between ``g$weights`` and ``E(g)$weights``: ``g$weights`` looks for a *graph* attribute named ``weights``, ``E(g)$weights`` looks for an *edge* attribute named ``weights``. Incidentally, there is also ``V(g)$weights``, which looks for a *vertex* attribute named ``weights``. – Tamás Dec 01 '11 at 21:29
  • The graph.strength documentation (linked in question now) indicates it looks for the _graph_ attribute named weight, however in my example once I fix the type to E(g)$weight, `graph.strength` works as expected. Why? Does it first search for the graph attribute and then the edge attribute? – mindless.panda Dec 01 '11 at 22:13
  • 1
    Looking for a graph attribute would not make sense since such an attribute would be attached to the graph itself and not the individual edges. `graph.strength` looks only for the edge attribute. The documentation says "if the graph has a `weight` edge attribute...", so I guess it is clear that you need an edge attribute here. – Tamás Dec 02 '11 at 08:35
  • Right, I'll eventually learn to read. Thanks – mindless.panda Dec 02 '11 at 13:13

2 Answers2

7

The function graph.strength can be given a weights vector with the weights argument. I think what is going wrong in your code is that you should call the weights attribute E(g)$weight not E(g)$weights.

Sacha Epskamp
  • 46,463
  • 20
  • 113
  • 131
4

I created an equivalent degree.distribution function for weighted graphs for my own code by taking the degree.distribution code and making one change:

graph.strength.distribution <- function (graph, cumulative = FALSE, ...)
{
  if (!is.igraph(graph)) {
    stop("Not a graph object")
  }
  # graph.strength() instead of degree()
  cs <- graph.strength(graph, ...)
  hi <- hist(cs, -1:max(cs), plot = FALSE)$density
  if (!cumulative) {
    res <- hi
  }
  else {
    res <- rev(cumsum(rev(hi)))
  }
  res
}
Community
  • 1
  • 1
mindless.panda
  • 4,014
  • 4
  • 35
  • 57
  • This is indeed very useful. Would you mind adding it to the `igraph` wiki as well? This is the link to the appropriate wiki page: http://igraph.wikidot.com/r-recipes – Tamás Dec 02 '11 at 08:36
  • Thank you for sharing! Not sure if this is the right place to ask, but, do you have an example of how to use this graph.strength.distribution() function? I checked https://rdrr.io/github/abnormally-distributed/rsfcNet/man/strength_distribution.html but there is an error in installing that package due to my version of R studio, so referring back to this thread. – Grace Oct 17 '21 at 14:18