First, let me start by saying that I've read How to assign levels to nodes in multi-level sankey diagram?
It helps but doesn't fully solve the issue.
Also, in my example code below I use the networkD3 package but I don't need to. Any package is fine with me so long as I'm able to place certain nodes at certain levels in the diagram.
Problem: I'm trying to draw a 3-level sankey diagram where each node is assigned to a "period" or level in the chart. The full chain of links would be something like Period 1-->Period 2-->Period 3. However, there may be cases where a Period 2 node is not connected to a Period 1 node (Period 2 --> Period 3) or where a Period 2 node is not connected to a Period 3 node (Period 1 --> Period 2).
I haven't figured out how to accomplish this on my own. The image below is what I'm trying to produce.
Below is some code to reproduce the problem I'm running into:
(Note: this is a simplified version. My actual data contains 150 nodes, 5 Periods and many hundreds of links.)
library(dplyr)
library(networkD3)
# Create link data
links <- data.frame(source = c("A","A","B","C","D","E","G"),
target = c("D","E","D","F","H","H","I"),
nlink = c(12,27,10,5,1,5,10)
)
# Create node data
nodes <- data.frame(
name=c(as.character(links$source), as.character(links$target)) %>%
unique()
)
# Assign periods to nodes
# I don't know how to actually use this to tell sankeyNetwork
# where to place the nodes but I'm including it here to help in problem solving
period <- data.frame(period = c("Period 1", "Period 1", "Period 1",
"Period 2", "Period 2", "Period 2", "Period 2",
"Period 3", "Period 3"))
nodes$nodeGroup <- period$period
# match to numbers, not names
links$IDsource <- match(links$source, nodes$name)-1
links$IDtarget <- match(links$target, nodes$name)-1
# Plot Sankey Network
p <- sankeyNetwork(
Links = links,
Nodes = nodes,
Source = "IDsource",
Target = "IDtarget",
Value = "nlink",
NodeID = "name",
nodeWidth = 30,
iterations = 5
)
p
You can see here that even though node "C" is a Period 1 node, it is placed with the Period 2 nodes. If I change the code to use "sinksRight = FALSE" as suggested in this thread: How to assign levels to nodes in multi-level sankey diagram? we get the following:
p <- sankeyNetwork(
Links = links,
Nodes = nodes,
Source = "IDsource",
Target = "IDtarget",
Value = "nlink",
NodeID = "name",
nodeWidth = 30,
sinksRight = FALSE,
iterations = 5
)
p
Now you can see that the "C" node is with the other Period 1 nodes as it should be, but the "G" node is now over here too, when it's a Period 2 node and should be in-line with D, E, and F (while I should be in the Period 3 level in-line with H).
Is there a way for me to explicitly assign nodes to a specific level?