I have a large network, which I want to use as a "start.graph" for my Barabasi-Albert-Model, but unfortunately I get this Error.
sample_pa(100, power = 1, m = 2, start.graph = large_network)
Error in sample_pa(100, power = 1, m = 2, start.graph = igraph_worm_traffic_colored[[1]]) :
At games.c:519 : Starting graph has too many vertices, Invalid value
Is there any way to change the maximal number of vertices?
Your error is because you need to have more vertices in your output graph than in your starting graph in order for the BA-model to work. You can take a subgraph of your large network if you want to use it to produce a 100-vertex graph.
g2<-induced.subgraph(large.network, sample(V(large.network), 20))
Or you can increase the number of vertices in your output graph.
Related
I am working with networkx 2.5. in Jupyter notebook, python version 3.6.5 I am working with an indirect graph. I have a graph from which I would like to perform the following steps iteratively
Remove one edge,
Perform some calculations over the remaining graph (number of connected components, diameter and nodes)
Put back the removed edge
Remove another edge
Repeat the whole procedure until all the edges were deleted once
For instance, I have the following graph:
'target' : [3, 2 ,4]})
nodes2 = pd.DataFrame({'nodeS' : [1, 2, 3 , 4],
'density' : [1, 2, 4, 2],
'indiv' : [2, 4, 1, 5]})
G1 = nx.from_pandas_edgelist(edges2, 'source', 'target')
nx.set_node_attributes(G1, pd.Series(nodes2.density, index=nodes2.nodeS).to_dict(), "density")
nx.set_node_attributes(G1, pd.Series(nodes2.indiv, index=nodes2.nodeS).to_dict(), 'indiv')
I plotted the first graph (G1)
The result looks like
Then I make the calculations over the graph:
# largest connected component (it will be necessary for the first calculation after first edge removal)
G1_LCC = G1.subgraph(max(nx.connected_components(G), key=len))
# number of connected components
G1_cc = nx.number_connected_components(G1)
# diameter of largest connected component
G1_diam = nx.diameter(G1_LCC)
# number of connected nodes
G1_nodes = len(nx.nodes(G1_LCC))
Removing an edge:
I tried the next:
e = (1,2)
G2= nx.remove_edge(e)
But it gives me an error:
nx.edges_iter(G)
AttributeError: module 'networkx' has no attribute 'remove_edge'
This should look like (G2)
Then perform operations on G2
Remove an edge which would look like that:
The third G3, (G3)
and so on, until all the edges have been removed once.
Note: I tried with edges iter
nx.edges_iter(G)
but I also got an error
AttributeError: module 'networkx' has no attribute 'edges_iter'
Is there an iterative/ efficient way to remove the edges, make calculations and put them back? Rather than do it one by one? Thank you
remove_edge is a method of the Graph class, not a top-level function in the library. So G2 = G1.remove_edge(e).copy() would be the correct command (you may not need to make a copy if you are adding the edge back in at a later point). edges_iter was also a method of Graph but has been discontinued for edges. So for e in G1.edges(), not for e in nx.edges_iter(G1).
I'm looking for motifs of size 5 in graphs with less than 5000 nodes and less than 10000 edges. (everything uncolored)
To do this I use function provided in igraph library for R subgraph_isomorphisms using method vf2 (see example below). I use adjacency matrix to generate subgraph and edgelist to generate the graph itself.
A lot of isomorphic subgraphs that I find have extra edges. Is there any way to only find subgraphs with exact given structure? Looking for answers using igraph or any other library in R
See reproducible example below (looking at this example is way easier if you just draw graph given by this adjacency matrix on a piece of paper)
library(igraph)
subgraph <- matrix(
data = c(0, 1,
1, 0), ncol = 2)
graph <- matrix(
data = c(0, 1, 0, 0,
1, 1, 0, 1,
1, 0, 0, 1,
0, 0, 1, 0), ncol = 4)
subgraph <- graph_from_adjacency_matrix(subgraph, mode = "directed", weighted = T, diag = T)
graph <- graph_from_adjacency_matrix(graph, mode = "directed", weighted = T, diag = T)
subgraph_isomorphisms(subgraph, graph, method = "vf2")
Output gives you two pairs of (1,2) and (3,4), when in fact adjacency matrix of (1,2) looks like
(0 1)
(1 1)
Which is different from the one we were looking for
The answer to this question is in definitions of what I'm looking for and what I'm finding.
What I was looking for was network motifs of size 5. When I'm looking for network motifs from the graph theory perspective it means that I'm looking for induced subgraphs with given adjacency matrix.
What this function does is it finds subgraphs of a graph that are isomorphic to a given graph. The difference is I was looking for induced subgraph, whereas the function just gives subgraphs, so extra edges are allowed.
That is exactly the problem that I was experiencing. To deal with it I ended up just comparing adjacency matrix of subgraphs that I found with those of the motif. Hope it will be helpful to someone.
Adding to the previous comment, I also noticed that the function returns "True" when I try to find an isomorphic triad of type 210 (2 mutual edges and 1 asymmetric) within a complete graph of four vertices. The solution is to add:
subgraph_isomorphisms(subgraph, graph, method = "vf2", **induced = TRUE**)
I am trying to calculate centrality metrics for a specific node within a graph using statnet (I can't just use igraph since it doesn't have certain metrics I'd like).
How do I use the nodes argument of these functions to specify this? For example, take prestige
# use the faux.magnolia.high dataset from ergm (1461 vertices and 974 edges)
library("ergm")
data(“faux.magnolia.high”)
# Try calculating for node 1
sna::prestige(faux.magnolia.high, nodes = 1, gmode = "graph")
1
# Try calculating for node 2
sna::prestige(faux.magnolia.high, nodes = 2, gmode = "graph")
NA
Looks like this is a bug in degree-related versions of prestige. This will work but calculations will be done on the whole graph:
sna::prestige(faux.magnolia.high, gmode = "graph")[2]
See Skye's full response on the statnet mailing list:
http://mailman13.u.washington.edu/pipermail/statnet_help/2016/002175.html
How can I find, in a directed graph, all vertices that can reach a set of other vertices with the igraph package in R?
I'm able to find them for a single vertex using (e.g. for all vertices that can reach vertex 4):
subcomponent(g, 4, mode="in")
However, how can I replace "4" with a set of many vertices with a similar result? If I give many vertices to the default function, it seems to return only vertices that can reach all the given vertices. I would like to find all vertices that can reach any of the given vertices...
Thanks
You could make the function subcomponent take a vector of arguments for the parameter v:
g <- erdos.renyi.game(100, 1/200)
mySet <- c(1,2,3)
modified <- Vectorize(igraph:::subcomponent, vectorize.args = "v")
modified(g, mySet, "in")
Which could also be done using an apply function or a loop
sapply(mySet, subcomponent, graph=g, mode="in")
I need to draw a network with 5 nodes and 20 directed edges (an edge connecting each 2 nodes) using R, but I need two features to exist:
To be able to control the thickness of each edge.
The edges not to be overlapping (i.e.,the edge form A to B is not drawn over the edge from B to A)
I've spent hours looking for a solution, and tried many packages, but there's always a problem.
Can anybody suggest a solution please and provide a complete example as possible?
Many Thanks in advance.
If it is ok for the lines to be curved then I know two ways. First I create an edgelist:
Edges <- data.frame(
from = rep(1:5,each=5),
to = rep(1:5,times=5),
thickness = abs(rnorm(25)))
Edges <- subset(Edges,from!=to)
This contains the node of origin at the first column, node of destination at the second and weight at the third. You can use my pacake qgraph to plot a weighted graph using this. By default the edges are curved if there are multiple edges between two nodes:
library("qgraph")
qgraph(Edges,esize=5,gray=TRUE)
However this package is not really intended for this purpose and you can't change the edge colors (yet, working on it:) ). You can only make all edges black with a small trick:
qgraph(Edges,esize=5,gray=TRUE,minimum=0,cut=.Machine$double.xmin)
For more control you can use the igraph package. First we make the graph:
library("igraph")
g <- graph.edgelist(as.matrix(Edges[,-3]))
Note the conversion to matrix and subtracting one because the first node is 0. Next we define the layout:
l <- layout.fruchterman.reingold(g)
Now we can change some of the edge parameters with the E()function:
# Define edge widths:
E(g)$width <- Edges$thickness * 5
# Define arrow widths:
E(g)$arrow.width <- Edges$thickness * 5
# Make edges curved:
E(g)$curved <- 0.2
And finally plot the graph:
plot(g,layout=l)
While not an R answer specifically, I would recommend using Cytoscape to generate the network.
You can automate it using a RCytoscape.
http://bioconductor.org/packages/release/bioc/html/RCytoscape.html
The package informatively named 'network' can draw directed networks fairly well, and handle your issues.
ex.net <- rbind(c(0, 1, 1, 1), c(1, 0, 0, 1), c(0, 0, 0, 1), c(1, 0, 1, 0))
plot(network(ex.net), usecurve = T, edge.curve = 0.00001,
edge.lwd = c(4, rep(1, 7)))
The edge.curve argument, if set very low and combined with usecurve=T, separates the edges, although there might be a more direct way of doing this, and edge.lwd can take a vector as its argument for different sizes.
It's not always the prettiest result, I admit. But it's fairly easy to get decent looking network plots that can be customized in a number of different ways (see ?network.plot).
The 'non overlapping' constraint on edges is the big problem here. First, your network has to be 'planar' otherwise it's impossible in 2-dimensions (you cant connect three houses to gas, electric, phone company buildings without crossovers).
I think an algorithm for planar graph layout essentially solves the 4-colour problem. Have fun with that. Heuristics exist, search for planar graph layout, and force-directed, and read Planar Graph Layouts