Convert directed graph to undirected graph without loosing directionality - graph

Is it possible to convert/transform a directed graph into an undirected graph without losing the notion of directionality?
For example d(i,j) = 10, and d(j,i) = infinity or d(i,j) = 10 and d(j,i) = 20
Is it possible to create a new (undirected) graph that has all this information? I can add more nodes and edges if necessary.
By undirected I mean this: A graph where d(i,j) = d(j,i) and if d(i,j) exists then d(j,i) exists.

Related

Can an igraph object have directed and undirected edges?

I am trying to use igraph/ggraph to plot a network, in which some of the edges are directed and others are not.
A small example from my edgelist. Here the protein-site edges are what I want to represent as undirected and the phosphorylation edge as directed.
df <- data.frame(
stringsAsFactors = FALSE,
from = c("RPS6KA3", "RPS6KA3", "RPS6KA3", "RPS6KA3", "RPS6KA3"),
to = c("RPS6KA3_Y529-p",
"RPS6KA3_S227-p","RPS6KA3_S369-p","RPS6KA3_T577-p","ATF4"),
action = c("protein-site","protein-site",
"protein-site","protein-site","phosphorylation")
)
I have tried subsetting the undirected edges and specifying them as such, but it didn't work:
library(igraph)
nw <- graph_from_data_frame(df)
E(nw)[E(nw)$action == "protein-site"] <- as.undirected(subgraph.edges(nw, E(nw)[E(nw)$action == "protein-site"] ))
Does anyone have any other suggestions?
As I say, I am really only wanting to plot this (using ggraph).
Thanks!
If you would be willing to plot with igraph you can import the list of edges as directed and then use edge.arrow.mode.
nw <- graph_from_data_frame(df, directed = T)
plot(nw)
plot(nw,
edge.arrow.mode = ifelse(E(nw)$action=="protein-site", "-", ">"))
I am not sure ggraph supports anything similar. I thought it might be possible to change the size of the arrows, and set it to 0 for undirected edges. This doesnt work, as arrows inherit the style of the rest of the edge.

R igraph: Barabasi-Model start.graph too many vertices

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.

Visualizing relation between two objects using R and export to HTML

I am using R to visualize relation between, say, 5-6 different nodes. Now, a graph is probably the best way to do it. The issue is, the edges are way too many. There can be a hundred edges between two vertexes. That makes the graph look very clumsy. I want the edge name to be displayed. With a hundred edge name being displayed, they overlap over each other and hence not comprehensible.
So, I have two questions-
Is there any other way in which I can represent the data? Some kind of chart probably?
I want to export the final output to HTML, which uses d3.js or any other similar library, keeping the edge name and a few other similar information intact. What will be the best plugin to use in that case?
I am using the igraph library to create the graph in R.
I also tried using the networkD3 library to export it to an HTML and make it interactive.
graph <- graph.data.frame(edges, directed = TRUE, vertices = vertex)
plot(graph, edge.label = E(graph)$name)
wc <- cluster_walktrap(graph)
members <- membership(wc)
graph_d3 <- igraph_to_networkD3(graph, group = members)
graph_forceNetwork <- forceNetwork(Links = graph_d3$links, Nodes = graph_d3$nodes,
Source = 'source',
Target = 'target',
NodeID = 'name',
Group = 'group',
zoom = TRUE,
fontSize = 20)
Right now, it is a graph with only two vertex and about 60-70 edges between them. So, I did not use any particular layout.

How to study the interaction between a set of nodes when the network is quite dense, using igraph?

I have 4 undirected graph with 1000 vertices and 176672, 150994, 193477, 236060 edges. I am trying to see interaction between a specific set of nodes (16 in number) for each graph. This visualization in tkplot is not feasible as 1000 vertices is already way too much for it. I was thinking of if there is some way to extract the interaction of these 16 nodes from the parent graph and view separately, which will be then more easy to handle and work with in tkplot. I don't want the loss of information as in what is the node(s) in he path of interaction if it comes from other than 16 pre-specified nodes. Is there a way to achieve it?
In such a dense graph, if you only take the shortest paths connecting each pair of these 16 vertices, you will still get a graph too large for tkplot, or even to see any meaningful on a cairo pdf plot.
However, if you aim to do it, this is one possible way:
require(igraph)
g <- erdos.renyi.game(n = 1000, p = 0.1)
set <- sample(1:vcount(g), 16)
in.shortest.paths <- NULL
for(v in set){
in.shortest.paths <- c(in.shortest.paths,
unlist(get.all.shortest.paths(g, from = v, to = set)$res))
}
subgraph <- induced.subgraph(g, unique(in.shortest.paths))
In this example, subgraph will include approx. half of all the vertices.
After this, I think you should consider to find some other way than visualization to investigate the relationships between your vertices of interest. It can be some topological metric, but it really depends on the aims of your analysis.

igraph nonreciprocal edges after converting to undirected graph using mutual

I'm working on a directed graph in igraph for R. I'm trying to convert it to an undirected graph where just reciprocal edges of the former persist. Should be easy but I'm getting strange results.
first I did it like that
library(igraph)
load("dmNet.Rdata")
#http://www.unet.univie.ac.at/~a0406222/dmNet.Rdata
recNet <- as.undirected(net, mode = "mutual",edge.attr.comb="sum")
when I check E(recNet)$weight there are a lot of edges with a weight of 1, which should not be possible since the sum of two reciprocal edges has to be at least 2. Then I did it like that
recNet <- as.undirected(net, mode = "mutual",edge.attr.comb="c")
now I can see that there are actually some edges containing just one value. My new graph recNet seems to contain nonreciprocal edges of net. What am I doing wrong, or am I missunderstandig the "mutual option"?
This happens because some edges are self-loops in your graph. All the edges that end up with a weight of 1 are self-loops:
all(which(E(recNet)$weight == 1) %in% which(is.loop(recNet)))
# [1] TRUE
Apparently, a self-loop is considered as a mutual edge in a directed graph. If you want to consider self-loops as non-mutual, then you can just remove them from the graph. Be careful, though, because some vertices have multiple self-loops, and you might not want to remove these.

Resources