I hope someone can help me out.
I have an undirected graph g with n=2071 nodes and m=9023 edges.
I calculated the graph density in R using the igraph package and got the following:
> graph.density(g,loop=FALSE)
[1] 0.00210475
However, using the formula for graph density, i.e. density = mean degree / (n-1), I got the following:
> mean(degree(g))/(vcount(g)-1)
[1] 0.0042095
Why does graph.density() give me a different (is it wrong?) answer?
Another question, doesn't the maximum eccentricity = diameter = maximum shortest path of the graph? Or am I confusing the concepts?
Calculating in R using the igraph package, I got the following:
> max(shortest.paths(g,mode="all"))
[1] 17
> diameter(g,directed=FALSE,unconnected=FALSE,weights=NULL)
[1] 17
> max(eccentricity(g,mode="all"))
[1] 8
I used Gephi to double check and I got the diameter=8.
Why is there a disparity between the values?
Also, I found an almost similar question asked before (igraph radius and diameter), but it does not quite ask/answer what I want. It says that the bug has been fixed.
The diameter calculation in igraph considers the edge weights while performing the calculation, so in order to make the calculated diameter same in both igraph and Gephi we need to set weights parameter to 'NA' in igraph.
diameter(graph_data, weights = NA)
Related
Hi I've been learning data mining and came across this question. I couldn't seem to figure it out myself.
So we have an undirected graph(without attributes) G = (V,E) and want to detect nodes that are outliers within that graph.
an outlier O in dataset D is defined as:
|{o'|dist(o,o'}≤ r}|/|D|≤ π, where D = V.
How can we define the distance function dist between
a pair of nodes? How can we determine suitable values for the parameters r and π?
The distance between two nodes in a graph could be defined as
number_of_intermeidate_nodes + 1
For Determining r and π ,
It can be done empirically that best suits your data.Try for different values of r and π
We have an non square adjacency matrix p (197x190)matrix without weights (only 1 if the 2 telephone numbers have called with each other and 0 otherwise). We tried to visualize this with a graph using this simple code and the igraph package:
p<-as.matrix(dcast(SNA_data, A_NUMBER~B_NUMBER, value.var="W", fill=0))[,]
graph<-graph.adjacency(p, mode="undirected", weighted=NULL)
plot(graph)
The result is a very small graph in plot that is totally unreadable graph anybody knows how to solve this?
Thanks in advance.
Try to use x11() to plot your graph in an external window :
library(igraph)
adjm1<-matrix(sample(0:1,1000,replace=TRUE,prob=c(0.9,01)),nc=10)
g1<-graph.adjacency(adjm1)
x11()
plot(g1)
Reference for the simulation : using graph.adjacency() in R
If your matrix is not a square, it might be worth trying an incidence matrix. By default the matrix is directed from rows to columns.
# create the network object
network <- graph_from_incidence_matrix(p)
network
class(network)
# plot it
plot(network)
I built a graph using bnlearn:hc using the following steps:
bootstrap 500 bns using hc algorithm
calculated the best threshold
extract the best arcs with threshold > "best threshold calculated" and direction > 0.5
So if I try to bootstrap with 1 bn, to be more fast in small tests, sometimes I have some undirected arcs.
In bnlearn how I can know what are the undirected arcs from a bn object (a learned structure) and remove it? This would be the best solution ?
Tks
When there are many nodes it can be hard to pick out the undirected arcs in a graph. In this case you can use undirected.arcs() to find them.
Usage is as follows:
boot = boot.strength(data = df, R=500, algorithm = 'hc',
algorithm.args = list(score = 'bde'))
boot.avg = averaged.network(boot)
undirected.arcs(boot.avg)
You can check the scores of each arc direction to make sure one isn't greater than the other:
score(set.arc(boot.avg, from="A", to="B", df)
score(set.arc(boot.avg, from="B", to="A", df)
And then finally you will want to set a direction like so:
boot.avg = set.arc(boot.avg, from="A", to="B")
If you want to remove the arc entirely you can do so with:
boot.avg = drop.arc(boot.avg, from="A", to="B")
To see which arcs are undirected you can plot the network. Use plot(network) or, if you have the package Rgraphviz, you can use graphviz.plot(network).
I am having trouble interpreting the arguments in the watts strogatz model in igraph and the documentation doesn't really help.
If I generate a network:
watts.strogatz.game(dim=1,size=2000,nei=10, p=0.01)
Here the size argument should indicate the number of nodes and the p argument the probability of rewiring.
I do not undertand the dim and nei arguments. Does dim mean the size of the network when it starts adding edges? Can someone help?
Edges are not added, but rewired.
The initial graph is a lattice, i.e., a very regular graph.
The dim and nei parameters describe this initial lattice (before any rewiring happens).
There are size^dim vertices.
Here are lattices of dimensions 1 and 2.
library(igraph)
g <- graph.lattice(5)
plot(g, layout=layout.grid(g,width=5))
plot(graph.lattice(c(5,5)))
In those examples, each vertex is connected to 1 neighbour in each direction:
you can change nei to increase this number.
g <- graph.lattice(10, nei=2)
plot(g, layout=layout.circle)
The lattices used are actually circular (I set p=0 to remove the rewiring -- you can change it to see how the model works):
g <- watts.strogatz.game(dim=1,size=10,nei=2, p=0)
plot(g)
I'm trying to draw a graph where the distance between vertices correspond to the edge weights* and I've founde that in graphviz there is a way to draw such graph. Is there a way to do this in R with the igraph package (specfically with graph.adkacency)?
Thanks,
Noam
(as once have been asked: draw a graph where the distance between vertices correspond to the edge weights)
This is not possible as you need triangle equality for every triangle to be able to plot such an object. So you can only approximate it. For this you can use "force embedded" algorithms. There are a few in igraph. The one I often use is the Fruchterman-Reingold algorithm.
See for details:
library("igraph")
?layout.fruchterman.reingold
Edit:
Note that the distance between nodes will correspond somewhat with the inverse of the absolute edge weight.
Like Sacha Epskamp mentioned, unless your data is perfect, you cannot draw a graph that would not violate some triangular inequalities. However, there are techniques named Multidimensional scaling (MDS) targeted at minimizing such violations.
One implementation in R is cmdscale from the stats package. I'd recommend the example at the bottom of ?cmdscale:
> require(graphics)
>
> loc <- cmdscale(eurodist)
> x <- loc[,1]
> y <- -loc[,2]
> plot(x, y, type="n", xlab="", ylab="", main="cmdscale(eurodist)")
> text(x, y, rownames(loc), cex=0.8)
Of course, you can plot x and y using any graphics packages (you were inquiring about igraph specifically).
Finally, I'm sure you'll find plenty of other implementations if you search for "multidimensional scaling" or "MDS". Good luck.