briatte / ggnetwork

Geoms to plot networks with ggplot2
https://briatte.github.io/ggnetwork/
144 stars 28 forks source link

Ineffective `weights` argument in `fortify.network` #52

Open briatte opened 5 years ago

briatte commented 5 years ago

Looking at PR #25 in detail, @jcfisher did not port the weights argument from fortify.network to fortify.igraph — with good reason, since the argument does nothing.

The argument is described as follows:

https://github.com/briatte/ggnetwork/blob/78f575bdcf4b9351e3c019835d892c68f802f830/R/fortify-network.R#L13-L16

And similar information is listed under 'Edge weights' in the vignette.

The problem is that there is no weight argument in sna::gplot.layout.kamadakawai, although its code calls the third column of the edge list at one point (line 754 below), with reference to an undocumented edge.val.as.str argument:

https://github.com/cran/sna/blob/38970cdcfee061c5ca237b885290738f24e0f3ef/R/visualization.R#L747-L758

It might thus well be that sna 'silently' weights the edge list in this case, although it is not very obvious (to me) how that happens, and whether users can provide sna::gplot.layout.kamadakawai (or similar layout algorithms that accept weighted edges) with a network object and expect edge weights to be taken in to account.

In all circumstances, contrary to what the documentation says, fortify.network does not currently take those edge weights into account. Edge weights are added to the edge list, but discarded right after that happens:

https://github.com/briatte/ggnetwork/blob/78f575bdcf4b9351e3c019835d892c68f802f830/R/fortify-network.R#L145-L154

For edge weights to be taken into account by fortify.network, (1) I need to understand better whether the code I highlighted from sna is indeed a weighting technique, and (2) I need to pass the weighted edge list to the layout calculation, i.e. I need to compute edges before computing the layout matrix, and use that (edges) in the layout computation.

Checking our R Journal article revealed that geomnet seems to have a solution to that issue:

https://github.com/sctyner/geomnet/blob/ca44ee77d59f6532b7ab29fcea8c724c5831f4c1/R/stat-net.r#L82-L109

jcfisher commented 4 years ago

After looking into this a bit, I think I can answer (1). According to this statnet_help thread, elen can be used as a weighting technique for sna::gplot.layout.kamadakawai.

In the thread, they suggest using something like

X = matrix(floor(runif(25,0,5)),nrow=5,byrow=T)  # edge weight
Xnet = network(X,matrix.type='adjacency')  # network
set.edge.value(Xnet,'value',X)
plot.network(
  Xnet,
  mode = 'kamadakawai',
  layout.par = list(elen = geodist(as.matrix(Xnet, attrname = 'value')))
  )

The thread also says (I think) that the sna package deliberately did not include a "weights" argument, because there isn't a consistent way to include edge weights across all layout algorithms.

Hopefully that helps a bit!