问题
The R package networkD3 provides an interface for R users to make network plots in D3, but the input data and ability to map data to network aesthetics differs over the available plots (e.g., simpleNetwork, forceNetwork).
Recently I've been trying to apply custom colors to each node in a radialNetwork(), similar to this thread, but I can't figure out how the custom coloring was mapped to the nodes.
The code to produce a custom coloring:
library(networkD3)
library(tidyverse)
library(data.tree)
## Data
input <- list(number=50)
Data_tree <- data.frame(Start="Class",
Asset = sample(c("FI","Equity","Currency","Commodities"),input$number,replace = TRUE),
Sub_Asset = sample(c("Asia","Europe","USA","Africa","ME"),input$number,replace = TRUE),
Ticker = replicate(input$number,paste0(sample(LETTERS,3),collapse=""))) %>%
unite(col="pathString",Start,Asset,Sub_Asset,Ticker,sep="-",remove=FALSE) %>%
select(-Start) %>% as.Node(pathDelimiter = "-")
colorVector <- c("black", "red", "blue", "green", "orange",
rep("red", 5), rep("blue", 5), rep("green", 4), rep("orange", 4),
rep("red", 11), rep("blue", 14), rep("green", 14), rep("orange", 11))
jsarray <- paste0('["', paste(colorVector, collapse = '", "'), '"]')
nodeStrokeJS <- JS(paste0('function(d, i) { return ', jsarray, '[i]; }'))
radialNetwork(ToListExplicit(Data_tree, unname = TRUE ),
linkColour = "#ccc",
nodeColour = "#fff",
nodeStroke = nodeStrokeJS,
textColour = "#cccccc")
I would argue that this example is somewhat incomplete since it isn't explained how the colors are mapped to the nodes ( is it via the list-of-list output of ToListExplicit or data_tree? I couldn't find a matching length), especially since adding additional elements to colorVector doesn't break the script. So how are the custom colors implemented in the input data for radialNetwork()?
回答1:
In your example, the nodes are ordered by level and then by how they are ordered in the original data. So...
- Class (top level)
- Equity (2nd level)
- Currency (2nd level)
- Commodities (2nd level)
- FI (2nd level)
- USA (3rd level)
- Asia (3rd level)
- etc.
If your color palette is not long enough to match each of your nodes, then it will loop back to the beginning (much like how R does when you combine vectors of different lengths, for example paste(c("node1","node2","node3"), c("d", "e"))
)
回答2:
OK, so I jumped the gun by posting this too early. One solution is to convert the data.tree to a data.frame and then construct a vector with a length and order that corresponds to the nodes/rows in the data.frame (as the data.frame yields a to/from/name column scheme):
tree.df <- ToDataFrameNetwork(tree, "name")
colorVector <- rep("red", nrow(tree.df))
jsarray <- paste0('["', paste(colorVector, collapse = '", "'), '"]')
nodeStrokeJS <- JS(paste0('function(d, i) { return ', jsarray, '[i]; }'))
radialNetwork(ToListExplicit(Data_tree, unname = TRUE ),
linkColour = "#ccc",
nodeColour = "#fff",
nodeStroke = nodeStrokeJS,
textColour = "#cccccc")
来源:https://stackoverflow.com/questions/48992732/r-networkd3-custom-node-color-for-radialnetwork