How do you build a graph from a data frame using the igraph package?
igraph is very flexible and I'm sure there are a number ways to accomplish this. I found the tutorials provided on the website to be very helpful.
Here's one simple way to create a network plot from a data.frame:
library(igraph)
df <- data.frame(
A = c("Berlin", "Amsterdam", "New York") ,
B = c("Munich", "Utrecht", "Chicago"))
df.g <- graph.data.frame(d = df, directed = FALSE)
plot(df.g, vertex.label = V(df.g)$name)
Note: For current versions of igraph
(as of Version 1.2.1), the graph.data.frame()
function is changed to graph_from_data_frame()
, which is the only function out of these two to appear in the documentation. The graph.data.frame()
function will still work, though.
How to make a network plot using a from-to-dataframe ?
You can plot this using the igraph package like so:
library(igraph)
graph <- graph_from_edgelist(data)
plot(graph)
R, Igraph: convert edges to tibble or data frame
You have extracted edge identifiers from the graph-object. Now you need to understand how the graphs and edges are represented. So use the plot
and str
commands to examine the details of the g
and dd
objects:
> g <- make_ring(10)
> plot(g)
> dd <- E(g)[from(1:4)]
> dd
+ 5/10 edges from 96250aa:
[1] 1-- 2 2-- 3 3-- 4 4-- 5 1--10
> str(dd)
'igraph.es' int [1:5] 1 2 3 4 10 # so it's really just a numeric vector
- attr(*, "env")=<weakref>
- attr(*, "graph")= chr "96250aab-d2ab-43aa-882d-6ef695323b0a"
> help(pack=igraph)
> as_edgelist(g)
[,1] [,2] # whereas the original graph (list) converts to two columns
[1,] 1 2
[2,] 2 3
[3,] 3 4
[4,] 4 5
[5,] 5 6
[6,] 6 7
[7,] 7 8
[8,] 8 9
[9,] 9 10
[10,] 1 10
> as_edgelist(dd)
Error in as_edgelist(dd) : Not a graph object
After looking at the results I opened the igraph help index and noted a function named as_ids that was described as: "Convert a vertex or edge sequence to an ordinary vector"
> as_ids(dd)
[1] 1 2 3 4 10
> str(g)
List of 10
$ :List of 1
..$ : 'igraph.vs' int [1:2] 2 10
.. ..- attr(*, "env")=<weakref>
.. ..- attr(*, "graph")= chr "96250aab-d2ab-43aa-882d-6ef695323b0a"
$ :List of 1
..$ : 'igraph.vs' int [1:2] 1 3
.. ..- attr(*, "env")=<weakref>
.. ..- attr(*, "graph")= chr "96250aab-d2ab-43aa-882d-6ef695323b0a"
$ :List of 1
..$ : 'igraph.vs' int [1:2] 2 4
.. ..- attr(*, "env")=<weakref>
.. ..- attr(*, "graph")= chr "96250aab-d2ab-43aa-882d-6ef695323b0a"
$ :List of 1
..$ : 'igraph.vs' int [1:2] 3 5
.. ..- attr(*, "env")=<weakref>
.. ..- attr(*, "graph")= chr "96250aab-d2ab-43aa-882d-6ef695323b0a"
$ :List of 1
..$ : 'igraph.vs' int [1:2] 4 6
.. ..- attr(*, "env")=<weakref>
.. ..- attr(*, "graph")= chr "96250aab-d2ab-43aa-882d-6ef695323b0a"
$ :List of 1
..$ : 'igraph.vs' int [1:2] 5 7
.. ..- attr(*, "env")=<weakref>
.. ..- attr(*, "graph")= chr "96250aab-d2ab-43aa-882d-6ef695323b0a"
$ :List of 1
..$ : 'igraph.vs' int [1:2] 6 8
.. ..- attr(*, "env")=<weakref>
.. ..- attr(*, "graph")= chr "96250aab-d2ab-43aa-882d-6ef695323b0a"
$ :List of 1
..$ : 'igraph.vs' int [1:2] 7 9
.. ..- attr(*, "env")=<weakref>
.. ..- attr(*, "graph")= chr "96250aab-d2ab-43aa-882d-6ef695323b0a"
$ :List of 1
..$ : 'igraph.vs' int [1:2] 8 10
.. ..- attr(*, "env")=<weakref>
.. ..- attr(*, "graph")= chr "96250aab-d2ab-43aa-882d-6ef695323b0a"
$ :List of 1
..$ : 'igraph.vs' int [1:2] 1 9
.. ..- attr(*, "env")=<weakref>
.. ..- attr(*, "graph")= chr "96250aab-d2ab-43aa-882d-6ef695323b0a"
- attr(*, "class")= chr "igraph"
So if you wanted a data.frame to hold the edge identifiers, you could get a dataframe with a single column, by just doing:
dd_df <- data.frame( ids <- as_ids(dd) )
But if you wanted a two column result that use as_data_frame
method for graph object and then select the first 4 rows of the graph:
> as_data_frame(g)[1:4, ]
from to
1 1 2
2 2 3
3 3 4
4 4 5
Create bipartite graph in R?
If the graph is created straight from the data.frame it will not be a bipartite graph.
library(igraph)
g <- graph_from_data_frame(df)
is.bipartite(g)
#[1] FALSE
But it will be a bipartite graph if created from the incidence matrix.
tdf <- table(df)
g <- graph.incidence(tdf, weighted = TRUE)
is.bipartite(g)
#[1] TRUE
Now plot it.
colrs <- c("green", "cyan")[V(g)$type + 1L]
plot(g, vertex.color = colrs, layout = layout_as_bipartite)
Add new edges to a igraph using dataframe in R
igraph
has a union()
method that combines graphs:
library(igraph)
df<-data.frame(from=c(1,2,3), to=c(1,2,3), time=c(1,2,3))
g<-graph_from_data_frame(df,directed=TRUE,vertices=NULL)
df1<-data.frame(from=c(1,2,3), to=c(2,3,1), time=c(4,5,6))
g2 <- graph_from_data_frame(df1, directed = TRUE)
g3 <- union(g, g2)
plot(g3)
Created on 2020-04-15 by the reprex package (v0.3.0)
Related Topics
Number Formatting Axis Labels in Ggplot2
Check If R Is Running in Rstudio
How to Filter a Table's Row Based on an External Vector
Trying to Use Dplyr to Group_By and Apply Scale()
Labeling Center of Map Polygons in R Ggplot
How to Plot Barchart Onto Ggplot2 Map
What Do . (Dot) and % (Percentage) Mean in R
Data.Table in R - Multiple Filters Using Multiple Keys - Binary Search
Detect Non Ascii Characters in a String
Get the Number of Lines in a Text File Using R
Apply a Function to Groups Within a Data.Frame in R
Applying the Same Factor Levels to Multiple Variables in an R Data Frame
Developing Geographic Thematic Maps with R