0

I just performed a code to get a consistent graph using igraph and tidygraph. In my example, the weight between A and C is just one. So the network graph from igraph package appropriately reflect weight as distance.

enter image description here

However,I think tidygraph failed to incorporate weight as distance. For example, B and E has no connection despite strong weight.

enter image description here

How can I reflect weight as distance?

   source target weight
1       A      B      4
2       A      B      7
3       A      C      1
4       A      D      2
5       A      J     11
6       J      A     14
7       B      E     18
8       B      F     19
9       C      G      1
10      C      H     10
11      D      I     14
12      I      I     10

# https://www.r-graph-gallery.com/249-igraph-network-map-a-color.html

# library
library(igraph)
set.seed(1)

# Create data
links <- data.frame(
  source = c("A","A", "A", "A", "A","J", "B", "B", "C", "C", "D","I"),
  target = c("B","B", "C", "D", "J","A","E", "F", "G", "H", "I","I"),
  weight = sample(1:20, 12, replace = T)
)

# Print out weights
links$weight

nodes <- data.frame(
  name=LETTERS[1:10],
  carac = c(rep("young", 3), rep("adult", 2), rep("old", 5))
)

# Turn it into igraph object
network <- graph_from_data_frame(d = links, vertices = nodes, directed = F) 

# Make a palette of 3 colors
library(RColorBrewer)
coul <- brewer.pal(3, "Set1") 

# Create a vector of color
my_color <- coul[as.numeric(as.factor(V(network)$carac))]

# Make the plot
plot(network, vertex.color = my_color)

# See colors
as.factor(nodes$carac)

library(ggraph)
library(tidygraph)
#
g <- tbl_graph(nodes, links, directed = FALSE)
g %>% mutate(degree = centrality_degree(),
         community = carac)%>%
  ggraph(layout = "lgl") +
  geom_edge_link(aes(width = 1),
                 alpha = 0.8,
                 colour = "lightgray") +
  scale_edge_width(range = c(0.1, 1)) +geom_node_point(aes(colour = community, size = degree)) +
  geom_node_text(aes(label = name), repel = TRUE) +
  theme_graph()
Eric Leung
  • 2,354
  • 12
  • 25
user224050
  • 317
  • 3
  • 10

1 Answers1

0

It appears the designer of tidygraph prefers to use indices for the edge connections. So within the function, there is some assumptions tbl_graph() makes on your data to construct the network object.

So I think the easiest way to solve this is to just pass the igraph object you've created into as_tbl_graph() to make sure the connections are correct.

# Library
library(igraph)
#> Attaching package: 'igraph'
#> The following objects are masked from 'package:stats':
#> 
#>     decompose, spectrum
#> The following object is masked from 'package:base':
#> 
#>     union
library(tidygraph)
#> Attaching package: 'tidygraph'
#> The following object is masked from 'package:igraph':
#> 
#>     groups
#> The following object is masked from 'package:stats':
#> 
#>     filter
library(ggraph)
#> Loading required package: ggplot2

set.seed(1)

# Create data
links <- data.frame(
  source = c("A","A", "A", "A", "A","J", "B", "B", "C", "C", "D","I"),
  target = c("B","B", "C", "D", "J","A","E", "F", "G", "H", "I","I"),
  weight = sample(1:20, 12, replace = T)
)
nodes <- data.frame(
  name = LETTERS[1:10],
  carac = c(rep("young", 3), rep("adult", 2), rep("old", 5))
)
network <- graph_from_data_frame(d = links, vertices = nodes, directed = F) 

g <- as_tbl_graph(network)
g %>% mutate(degree = centrality_degree(),
             community = carac)%>%
  ggraph(layout = "lgl") +
  geom_edge_link(aes(width = 1),
                 alpha = 0.8,
                 colour = "lightgray") +
  scale_edge_width(range = c(0.1, 1)) +
  geom_node_point(aes(colour = community, size = degree)) +
  geom_node_text(aes(label = name), repel = TRUE) +
  theme_graph()

Created on 2020-07-03 by the reprex package (v0.3.0)

Edit: upon further inspection, the more root of the issue is that tbl_graph() doesn't like factors and removes them. This then creates the mapping based on the order of nodes being shown. So that is why we see an odd network. So below, I've added stringsAsFactors = FALSE when creating the links data frame.

# Library
library(igraph)
#> Attaching package: 'igraph'
#> The following objects are masked from 'package:stats':
#> 
#>     decompose, spectrum
#> The following object is masked from 'package:base':
#> 
#>     union
library(tidygraph)
#> Attaching package: 'tidygraph'
#> The following object is masked from 'package:igraph':
#> 
#>     groups
#> The following object is masked from 'package:stats':
#> 
#>     filter
library(ggraph)
#> Loading required package: ggplot2

set.seed(1)

# Create data
links <- data.frame(
  source = c("A","A", "A", "A", "A","J", "B", "B", "C", "C", "D","I"),
  target = c("B","B", "C", "D", "J","A","E", "F", "G", "H", "I","I"),
  weight = sample(1:20, 12, replace = T),
  stringsAsFactors = FALSE
)
nodes <- data.frame(
  name = LETTERS[1:10],
  carac = c(rep("young", 3), rep("adult", 2), rep("old", 5))
)

# Create network
g <- tbl_graph(nodes, links, directed = FALSE)
g %>% mutate(degree = centrality_degree(),
             community = carac)%>%
  ggraph(layout = "lgl") +
  geom_edge_link(aes(width = 1),
                 alpha = 0.8,
                 colour = "lightgray") +
  scale_edge_width(range = c(0.1, 1)) +
  geom_node_point(aes(colour = community, size = degree)) +
  geom_node_text(aes(label = name), repel = TRUE) +
  theme_graph()

Created on 2020-07-03 by the reprex package (v0.3.0)

Eric Leung
  • 2,354
  • 12
  • 25