title: Sankey NetworkD3: set link colours across entire flow
body: <p>I have been following examples on stack to create Sankey charts using the NetworkD3 package. I would like to set the colour of the links specific to column variables <code>event</code>. The data that I have has multiple columns:</p>
  <pre><code>structure(list(names = c(&quot;bell&quot;, &quot;john&quot;, &quot;andrew&quot;, &quot;sam&quot;, &quot;bell&quot;, 
  &quot;bell&quot;, &quot;andrew&quot;), event = c(&quot;Event 1&quot;, &quot;Event 2&quot;, &quot;Event 3&quot;, 
  &quot;Event 1&quot;, &quot;Event 2&quot;, &quot;Event 4&quot;, &quot;Event 1&quot;), response = c(&quot;Yes&quot;, 
  &quot;Yes&quot;, &quot;No&quot;, &quot;Yes&quot;, &quot;No&quot;, &quot;Yes&quot;, &quot;No&quot;)), class = &quot;data.frame&quot;, row.names = c(NA, 
  -7L))
  
  &gt; d
     names   event response
  1   bell Event 1      Yes
  2   john Event 2      Yes
  3 andrew Event 3       No
  4    sam Event 1      Yes
  5   bell Event 2       No
  6   bell Event 4      Yes
  7 andrew Event 1       No
  </code></pre>
  <p>Following CJ Yetman's example (thank you very much for the very followable example if you ever read this!) <a href="https://stackoverflow.com/questions/44132423/creating-a-sankey-diagram-using-networkd3-package-in-r">here</a>, data frames for the links and nodes were created:</p>
  <pre><code>links &lt;- d %&gt;% 
    mutate(row = row_number()) %&gt;% 
    gather('column', 'source', -row) %&gt;% 
    mutate(column = match(column, names(d))) %&gt;%  
    group_by(row) %&gt;% 
    arrange(column) %&gt;% 
    mutate(target = lead(source)) %&gt;% 
    ungroup %&gt;% 
    filter(!is.na(target)) %&gt;% 
    #index
    mutate(source = paste0(source, '_', column)) %&gt;%
    mutate(target = paste0(target, '_', column + 1)) %&gt;%
    select(source, target)
  
  nodes &lt;- data.frame(
    name=c(as.character(links$source), as.character(links$target)) %&gt;% 
      unique()
  )
  </code></pre>
  <p>Then I matched the indices in the <code>nodes</code> data frame to the <code>source</code> and <code>target</code> columns in the <code>links</code> data frame. In this case, I mutated new columns rather than overwriting it because it is easier for me to read:</p>
  <pre><code>link &lt;- links %&gt;% 
    mutate(IDsource = match(links$source, nodes$name)-1) %&gt;% 
    mutate(IDtarget = match(links$target, nodes$name)-1) %&gt;% 
    mutate(value = 1) %&gt;% 
    #remove index 
    mutate(source = sub('_[0-9]+$', '', source)) %&gt;% 
    mutate(target = sub('_[0-9]+$', '', target))
  
  #
  nodes$name &lt;- sub('_[0-9]+$', '', nodes$name)
  </code></pre>
  <p>As mentioned, I would like to set the colour of the links across the entire flow of the Sankey diagram by <code>event</code>. <a href="https://www.r-graph-gallery.com/322-custom-colours-in-sankey-diagram.html" rel="nofollow noreferrer">Here</a> specifies creating a new column in <code>links</code> and <code>nodes</code> to match the colour scale specified in the <code>d3.scaleOrdinal()</code> function.</p>
  <pre><code>#New column to set colour for nodes  
  nodes$node.col &lt;- as.factor(c(&quot;nod.col&quot;)) #set nodes to one colour only
  
  #New column for links 
  col.index &lt;- d %&gt;% 
    select(event) %&gt;% unique(); col.index #get events from original dataframe 
  
  #mutate new column to set colours for links 
  links$links.col &lt;- col.index$event[match(links$source, col.index$event)]
  links$links.col[is.na(links$links.col)] &lt;- col.index$event[match(links$target[is.na(links$links.col)], col.index$event)]
  links$links.col &lt;- as.factor(links$links.col) #change to factors 
  
  #d3.scaleOrdinal()
  my_color &lt;- 'd3.scaleOrdinal() .domain([&quot;Event 1&quot;, &quot;Event 2&quot;, &quot;Event 3&quot;, &quot;Event 4&quot;, &quot;nod.col&quot;]) .range([&quot;red&quot;, &quot;blue&quot;, &quot;red&quot;, &quot;yellow&quot;, &quot;gray&quot;])'
  </code></pre>
  <p>However, the links are all red, when each event should have its own colour (across the entire flows).</p>
  <pre><code>sankeyNetwork(Links = links, Nodes = nodes, Source = 'IDsource',
                Target = 'IDtarget', Value = 'value', NodeID = 'name', colourScale=my_color,
                LinkGroup=&quot;links.col&quot;, NodeGroup=&quot;node.col&quot;)
  </code></pre>
  <p><a href="https://i.stack.imgur.com/2jUw7.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/2jUw7.png" alt="enter image description here" /></a></p>
  <p>Could someone explain what I did wrong? The other issue I have is with manually setting the colours for each event in <code>d3.scaleOrdinal()</code>. If there an efficient way to do this I need to set the colour for up to 30 or more events?</p>