Search code examples
rnodesdiagrammer

using diagrammeR, how can I make a node fillcolor dependent on a condition?


Firstly... I could be approaching this task incorrectly. I am new to diagrammeR functionality, and if what I am understanding about diagrammeR is fallacious, from a programming perspective, I would not be surprised.

The issue arises in the 'node [fillcolor = COLOR]' statement of the code.
If I simply write 'fillcolor = Green, style = filled' instead of fillcolor = object1, then it works perfectly. Similarly, if I replace Green with 'Crimson', or any other color, no problems.

My issue is that I want this color to change, depending on the value of an object that is determined by a condition. Basically, if too few sick people are going to see a doctor, this should raise a red flag on a report I'm creating on a daily basis, and programming this manually every day would be a bit of a pain.

What I have tried:
instead of specifying a color, I am trying to use the output of a conditional object as the fillcolor (e.g. what I have tried below)

fillcolor = object1 - fills the final box with black
fillcolor = ', object1 ' - final box is black-filled again
fillcolor = object1[1] - outputs results in an error
fillcolor = ', object1[1] ' - final box is black-filled again

# Just create some random data for a flow chart
a = 100              # Total people
b = 60               # Number of total that are sick
c = 19               # Number of sick that saw a doctor
d = round(c/b * 100) # percent of sick who saw a doctor

# create a flowchart-list-object
flow <- list(a=a, b=b, c=c, d=d)

# this could be where I am going wrong
# Condition that determines if the Percentage of sick people who saw a doctor
# is above 40%
if (d > 40) {
  object1 <- 'Green'
} else
  object1 <- 'Crimson'

# Output the flowchart using grViz
DiagrammeR::grViz("
                  digraph dot {

                  graph[layout = dot, fontsize = 15]

                  # Node numbers with labelled text
                  node [shape = box,
                        width = 3, 
                        fontname = Helvetica]

                  a [label = '@@1']
                  b [label = '@@2']
                  c [label = '@@3']

                  # First set of node to edge connections
                  a -> b -> c

                  node [fillcolor = object1, style = filled]
                  d [label = '@@4']
                  c -> d

                  }

                  [1]: paste0('Total Sick \\n ', flow$a, '')
                  [2]: paste0('Number of total sick \\n ', flow$b, '')
                  [3]: paste0('Number of Sick who see a doctor \\n ', flow$c, '')
                  [4]: paste0('% of sick who see a doctor \\n ', flow$d, '')

                  ")

I would expect the final box in the flowchart to be green if the percentage of those sick is above 40% or crimson(red) if it is below 40%.

Thanks for all/any help!


Solution

  • You must define the color as a footnote, just like the nodes' labels. This is because object1 is an R variable, not an actual value. I have defined it at the end as footnote [5]:.

    DiagrammeR::grViz("
                      digraph dot {
    
                      graph[layout = dot, fontsize = 15]
    
                      # Node numbers with labelled text
                      node [shape = box,
                      width = 3, 
                      fontname = Helvetica]
    
                      a [label = '@@1']
                      b [label = '@@2']
                      c [label = '@@3']
    
                      # First set of node to edge connections
                      a -> b -> c
    
                      d [style = filled, fillcolor = '@@5', label = '@@4']
                      c -> d
    
                      }
    
                      [1]: paste0('Total Sick \\n ', flow$a, '')
                      [2]: paste0('Number of total sick \\n ', flow$b, '')
                      [3]: paste0('Number of Sick who see a doctor \\n ', flow$c, '')
                      [4]: paste0('% of sick who see a doctor \\n ', flow$d, '')
                      [5]: object1
                      ")
    

    enter image description here