knitr::opts_chunk$set(echo = TRUE) library(collapsibleTree) load(system.file("extdata/Geography.rda", package = "collapsibleTree"))
When working with data in R, it makes sense (at least to me) to represent everything as a data frame. I'm a big fan of tidy data, but this structure does not lend itself to easily designing hierarchical networks.
collapsibleTree uses data.tree to handle all of that, freeing you from a lot of recursive list construction.
Here is an example geography dataset from data.world:
With your data frame in hand, and a vector of columns to graph, creating an interactive collapsible tree diagram can be done like so:
collapsibleTree( Geography, hierarchy = c("continent", "type", "country"), width = 800 )
You can add colors to each node in the diagram manually by declaring a
fill value. Fill is declared as a hierarchy, applied down the tree. In order to get your vectors to the right length for complex trees (this one has 385 nodes), you could use a pattern like this:
collapsibleTree( Geography, hierarchy = c("continent", "type", "country"), width = 800, fill = c( # The root "white", # Unique continents rep("firebrick", length(unique(Geography$continent))), # Unique types per continent rep("steelblue", length(unique(paste(Geography$continent, Geography$type)))), # Unique countries rep("green", length(unique(Geography$country))) ) )
Throw in some gradients if you'd like! Each node can have its own distinct color. Let's use some
dplyr to help us with the data aggregation and use
colorspace to make some nice looking palettes.
The fill order is depends on the order of the data frame. This time we'll sort alphabetically rather than using the order the dataset originally came in.
library(dplyr, warn.conflicts = FALSE) # Continents are a simple gradient continentColors <- RColorBrewer::brewer.pal(length(unique(Geography$continent)), "Reds") # Types will be a gradient that resets between continents typeColors <- Geography %>% arrange(continent, type) %>% group_by(continent) %>% distinct(type) %>% mutate(colors = colorspace::sequential_hcl(length(type))[seq_along(type)]) # Countries will also be a gradient that resets between continents, but not types countryColors <- Geography %>% arrange(continent, type) %>% group_by(continent) %>% distinct(country) %>% mutate(colors = colorspace::rainbow_hcl(length(country))[seq_along(country)]) Geography %>% arrange(continent, type, country) %>% collapsibleTree( hierarchy = c("continent", "type", "country"), root = "Geography", width = 800, fill = c("white", continentColors, typeColors$colors, countryColors$colors) )
colorspace again, we can create a new column in the source data frame for the total number of countries on each continent, and map that column to the fill gradient of the nodes.
collapsibleTreeSummary serves as a convenience function around
Looking at this chart, you can tell that Africa has roughly the same number of countries as Europe, and that most countries are... countries. Hovering over the node can confirm this fact.
Also note that the nodes are a little bit further apart on this example, due to individual countries not being represented. Link length and chart margins are automatically calculated based on the number of nodes and the length of the labels.
Geography %>% group_by(continent, type) %>% summarise(`Number of Countries` = n()) %>% collapsibleTreeSummary( hierarchy = c("continent", "type"), root = "Geography", width = 800, attribute = "Number of Countries" )
Sometimes you need to represent trees with varying levels of depth. In the below example, every continent besides Antartica has a subregion. Antartica has an
NA for its subregion, so no leafs will be drawn.
collapsibleTree( Geography, hierarchy = c("continent", "sub_region"), width = 800 )
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.