packages = c('igraph', 'tidygraph', 'ggraph', 'visNetwork', 'lubridate', 'tidyverse')
for(p in packages){library
if(!require(p, character.only = T)){
install.packages(p)
}
library(p, character.only = T)
}
## Loading required package: igraph
##
## Attaching package: 'igraph'
## The following objects are masked from 'package:stats':
##
## decompose, spectrum
## The following object is masked from 'package:base':
##
## union
## Loading required package: tidygraph
##
## Attaching package: 'tidygraph'
## The following object is masked from 'package:igraph':
##
## groups
## The following object is masked from 'package:stats':
##
## filter
## Loading required package: ggraph
## Loading required package: ggplot2
## Loading required package: visNetwork
## Loading required package: lubridate
##
## Attaching package: 'lubridate'
## The following object is masked from 'package:igraph':
##
## %--%
## The following object is masked from 'package:base':
##
## date
## Loading required package: tidyverse
## -- Attaching packages ---------------------------------------------------------------------------------------------------------------------- tidyverse 1.2.1 --
## v tibble 2.1.3 v purrr 0.3.2
## v tidyr 1.0.0 v dplyr 0.8.3
## v readr 1.3.1 v stringr 1.4.0
## v tibble 2.1.3 v forcats 0.4.0
## -- Conflicts ------------------------------------------------------------------------------------------------------------------------- tidyverse_conflicts() --
## x lubridate::%--%() masks igraph::%--%()
## x lubridate::as.difftime() masks base::as.difftime()
## x dplyr::as_data_frame() masks tibble::as_data_frame(), igraph::as_data_frame()
## x purrr::compose() masks igraph::compose()
## x tidyr::crossing() masks igraph::crossing()
## x lubridate::date() masks base::date()
## x dplyr::filter() masks tidygraph::filter(), stats::filter()
## x dplyr::groups() masks tidygraph::groups(), igraph::groups()
## x lubridate::intersect() masks base::intersect()
## x dplyr::lag() masks stats::lag()
## x lubridate::setdiff() masks base::setdiff()
## x purrr::simplify() masks igraph::simplify()
## x lubridate::union() masks igraph::union(), base::union()
GAStech_nodes <- read_csv("data/GAStech_email_node.csv")
## Parsed with column specification:
## cols(
## id = col_double(),
## label = col_character(),
## Department = col_character(),
## Title = col_character()
## )
GAStech_edges <- read_csv("data/GAStech_email_edge-v2.csv")
## Parsed with column specification:
## cols(
## source = col_double(),
## target = col_double(),
## SentDate = col_character(),
## SentTime = col_time(format = ""),
## Subject = col_character(),
## MainSubject = col_character(),
## sourceLabel = col_character(),
## targetLabel = col_character()
## )
GAStech_edges$SentDate = dmy(GAStech_edges$SentDate)
GAStech_edges$Weekday = wday(GAStech_edges$SentDate, label = TRUE, abbr = FALSE)
GAStech_edges_aggregated <- GAStech_edges %>%
filter(MainSubject == "Work related") %>%
group_by(source, target, Weekday) %>%
summarise(Weight = n()) %>%
filter(source!=target) %>%
filter(Weight > 1) %>%
ungroup()
GAStech_graph <- tbl_graph(nodes = GAStech_nodes, edges = GAStech_edges_aggregated, directed = TRUE)
GAStech_graph %>%
activate(edges) %>%
arrange(desc(Weight))
## # A tbl_graph: 54 nodes and 1456 edges
## #
## # A directed multigraph with 1 component
## #
## # Edge Data: 1,456 x 4 (active)
## from to Weekday Weight
## <int> <int> <ord> <int>
## 1 40 41 Tuesday 23
## 2 40 43 Tuesday 19
## 3 41 43 Tuesday 15
## 4 41 40 Tuesday 14
## 5 42 41 Tuesday 13
## 6 42 40 Tuesday 12
## # ... with 1,450 more rows
## #
## # Node Data: 54 x 4
## id label Department Title
## <dbl> <chr> <chr> <chr>
## 1 1 Mat.Bramar Administration Assistant to CEO
## 2 2 Anda.Ribera Administration Assistant to CFO
## 3 3 Rachel.Pantanal Administration Assistant to CIO
## # ... with 51 more rows
With reference to the organisation network graph in Section 6.1 of Hands-on Exercise 10, you are required to complete the following tasks:
g <- GAStech_graph %>%
mutate(betweenness_centrality = centrality_betweenness()) %>%
mutate(closeness_centrality = centrality_closeness()) %>%
ggraph(layout = "nicely") +
geom_edge_link(aes()) +
geom_node_point(aes(colour = closeness_centrality, size=betweenness_centrality))
g + theme_graph()
ggraph 2.0 utilizes the qgraph function. This function works as a Quickplot wrapper for networks.
We no longer need to create variables for closeness_centrality and betweenness_centrality as ggraph 2.0 can directly call these functions as inputs in the Aesthetic.
qgraph(
GAStech_graph,
node_colour = centrality_closeness(),
node_size = centrality_betweenness()
)+theme_graph()
Problem: There is no indication of which node refers to which job title or Person
Solution: Use labels to indetify the nodes. I have used the job title as the identifying label.
Problem: No indication of which node refers to which department.
Solution: Use node outlines to specify which node belongs to which department.
Problem: The node edges are too dark which makes it difficult to see the nodes.
Solution: Use a lighter colour for the node edges.
Sketch_1
alt_graph <-
ggraph(GAStech_graph, layout = "nicely") +
geom_edge_link(colour = "grey80") +
#geom_node_point(aes( size=centrality_betweenness())) +
geom_node_circle(aes(fill = centrality_closeness(),r=log(centrality_betweenness())/70, col = Department), size = 1) +
geom_node_text(aes(label=GAStech_nodes$Title), size = 2, check_overlap = TRUE, repel = TRUE)
alt_graph + theme_graph()
GAStech_edges_aggregated <- GAStech_edges %>%
left_join(GAStech_nodes, by = c("sourceLabel" = "label")) %>%
rename(from = id) %>%
left_join(GAStech_nodes, by = c("targetLabel" = "label")) %>%
rename(to = id) %>%
filter(MainSubject == "Work related") %>%
group_by(from, to) %>%
summarise(weight = n()) %>%
filter(from!=to) %>%
filter(weight > 1) %>%
ungroup()
GAStech_nodes <- GAStech_nodes %>%
rename(group = Department)
visNetwork(GAStech_nodes, GAStech_edges_aggregated) %>%
visIgraphLayout(layout = "layout_with_fr") %>%
visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE)
With reference to the organisation network graph in Section 7.4 of Hands-on Exercise 10, you are required to complete the following tasks:
Improve the design of the graph by incorporating the following interactivity:
When a name is selected from the drop-down list, the corresponding node will not only be highlighted but also will be labelled. Furthermore, all the linked nodes of the selected node will also be labelled too.
When a node of the interactive graph is selected, the node will not only be highlighted but also will be labelled. Furthermore, all the linked nodes of the selected node will be labelled as well.
visNetwork(GAStech_nodes, GAStech_edges_aggregated) %>%
visIgraphLayout(layout = "layout_with_fr") %>%
visNodes(label=GAStech_nodes$id, shape="circle") %>%
visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE)
Problem 1: We do not know which colour refers to which department
Solution: add a legend for the departments
Problem 2: Labels are not clearly visible
Solution: Add the labels to the centre of the graph and change node shape to box to clearly enclose the label.
Problem 3: Arrow directions are unknown
Solution: Add direction to the arrows
Sketch_2
visNetwork(GAStech_nodes, GAStech_edges_aggregated) %>%
visEdges(
arrows = list(
to = list(enabled = TRUE),
from = list(enabled = TRUE)
)
)%>%
visIgraphLayout(layout = "layout_with_fr") %>%
visNodes(label=GAStech_nodes$id ,shape="box") %>%
#visOptions(selectedBy = "group")%>%
visOptions(highlightNearest = list(enabled = TRUE, hover = T), nodesIdSelection = TRUE)%>%
visInteraction(navigationButtons = TRUE)%>%
visLegend(width = 0.3, position = "right", main = "Departments",zoom = FALSE)