Skip to content

Instantly share code, notes, and snippets.

@beemyfriend
Last active September 27, 2018 05:40
Show Gist options
  • Save beemyfriend/76ac41b701295d39be7997dc11c1f818 to your computer and use it in GitHub Desktop.
Save beemyfriend/76ac41b701295d39be7997dc11c1f818 to your computer and use it in GitHub Desktop.
Moving around a tree
library(tidyverse)
library(igraph)
###Fake Taxonomy
g <- make_tree(20, 2) %>%
set_edge_attr('arrow.size', value = .5) %>%
set_vertex_attr('name', value = 1:vcount(.)) %>%
set_vertex_attr('label.cex', value = .7) %>%
set_graph_attr('layout', layout_as_tree(.))
plot(g)
####Choose something
n4 <- V(g)[name == '4']
g %>%
plot(
vertex.color = ifelse(V(.) %in% n4, 'gold', 'white'),
main = "Node 4 is our node of interest."
)
######Prune tree
n4Children <- dfs(g, n4, neimode = 'out', unreachable = F) %>%
.$order %>%
.[!is.na(.)]
g %>%
plot(
vertex.color = ifelse(V(.) %in% n4Children, 'gold', 'white'),
edge.color = ifelse(E(.) %in% E(.)[from(n4Children)], 'black', 'lightgrey'),
main = "What are node 4's children?"
)
######Roots
n4Ancestors <- dfs(g, n4, neimode = 'in', unreachable = F) %>%
.$order %>%
.[!is.na(.)]
g %>%
plot(
vertex.color = ifelse(V(.) %in% n4Ancestors, 'gold', 'white'),
edge.color = ifelse(E(.) %in% E(.)[to(n4Ancestors)], 'black', 'lightgrey'),
main = "What are node 4's ancestors?"
)
######Find Connections
n4_n13 <- shortest_paths(g, '4', '13', mode = 'all', output = 'both')
g %>%
plot(
vertex.color = ifelse(V(.) %in% n4_n13$vpath[[1]], 'gold', 'white'),
edge.color = ifelse(E(.) %in% n4_n13$epath[[1]], 'black', 'lightgrey'),
main = 'How are nodes 4 and 13 related?'
)
###### Let's add an ancestor
g_0 <- g %>%
{. + vertices("0") + edges('0', '1')} %>%
set_graph_attr('layout', layout_as_tree(.))
plot(g_0)
####Let's have two trees....probably best to keep them as separate graphs though...
g2 <- make_tree(20, 2)
V(g)$alpha <- letters[seq(vcount(g))]
V(g2)$alpha <- map_chr(seq(vcount(g)), function(i) ifelse(i < 16, letters[i], letters[36-i]))
V(g)$tree = 1
V(g2)$tree = 2
V(g2)$name <- 1:vcount(g2) + 20
g3 <- graph_from_data_frame(
rbind(as_data_frame(g) %>% select(from, to),as_data_frame(g2)),
T,
rbind(as_data_frame(g, 'vertices') %>% select(-label.cex), as_data_frame(g2, 'vertices') )
) %>%
set_edge_attr('arrow.size', value = .5) %>%
set_vertex_attr('name', value = paste0('.',1:vcount(.))) %>%
set_vertex_attr('label', value = V(.)$alpha) %>%
set_graph_attr('layout', layout_as_tree(.))
##### Find similar nodes from both trees
plot(g3,
vertex.color = ifelse(V(g3)$alpha == 'e', 'gold', 'white'),
main = "How are the e nodes for each tree different?",
asp = 0)
eSubTree <- V(g3)[alpha == 'e'] %>%
map(function(x){
dfs(g3, x, 'out', F) %>%
.$order %>%
.[!is.na(.)] %>%
.$name
}) %>%
unlist %>%
{V(g3)[.]}
##### find all their descendents for comparison
g3 %>%
plot(
vertex.color = ifelse(V(.) %in% eSubTree, 'gold', 'white'),
edge.color = ifelse(E(.) %in% E(.)[from(eSubTree)], 'black', 'lightgrey'),
main = 'What are the descendent subgraphs of the e nodes?',
asp = 0
)
#####Let's identify the differences
g3 %>%
{. - V(.)[!name %in% eSubTree$name]} %>%
(function(x){
#components are basically two unattached subgraphs
tempGroups <- x %>%
components %>%
groups()
#if nodes are in all subgraphs/components/trees, then the number of nodes should match the number of trees
tempDiff <- map(tempGroups, function(y){
V(x)[name %in% y]$alpha
}) %>%
unlist() %>%
table()
#If a nodes is not in all trees, then let's point focus on them
diffNodes <- tempDiff %>%
.[. != length(tempGroups)] %>%
names %>%
{V(x)[alpha %in% .]}
plot(
x,
layout = layout_as_tree(x),
vertex.color = ifelse(V(x) %in% diffNodes, 'gold', 'white'),
vertex.frame.color = ifelse(V(x) %in% unlist(ego(x, 1, diffNodes)), 'red', 'black'),
edge.color = ifelse(E(x) %in% E(x)[diffNodes %--% V(x)], 'red', 'lightgrey'),
main = "What's the different between the two e subgraphs?",
asp= 0
)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment