I'm trying to make a SEM graph using R and DiagrammeR. I have the graph set up but I'm trying to have some of the nodes (CSEW, ONS and Police) at the bottom of the graph to make it easier to read.
Here is what I have so far. Any recommendations in how to move the three circles to the bottom would be welcomed.
library(DiagrammeR)
grViz("
digraph MTMM {
subgraph {
node [shape = box, fixedsize = true, width = 1]
rank = same; bike_c; bike_p; bike_o
burg_c; burg_p; burg_o
theft_c; theft_p; theft_o
viol_c; viol_p; viol_o
}
subgraph {
node [shape = circle, fixedsize = true, width = 1]
Bicycle; Burglary; Theft; Violence
}
subgraph {
node [shape = circle, fixedsize = true, width = 1]
CSEW; ONS; Police
}
Bicycle -> {bike_c bike_p bike_o}
Burglary -> {burg_c burg_p burg_o}
Theft -> {theft_c theft_p theft_o}
Violence -> {viol_c viol_p viol_o}
CSEW -> {bike_c burg_c theft_c viol_c} [label = '1']
ONS -> {bike_o burg_o theft_o viol_o} [label = '1']
Police -> {bike_p burg_p theft_p viol_p} [label = '1']
{rank = same; CSEW; ONS; Police}
{rank = same; Bicycle; Burglary; Theft; Violence}
}
")
If you want have node A above node B, you must point from A -> B, this is graphviz' fundamental logic. If you want the arrow point in the other direction, you do so by telling graphviz: A -> B[ dir = back].
In your case, replace the three lines concerned with
{bike_c burg_c theft_c viol_c} -> CSEW [dir = back, label = '1']
{bike_o burg_o theft_o viol_o} -> ONS[dir = back, label = '1']
{bike_p burg_p theft_p viol_p} -> Police[dir = back, label = '1']
which gives you
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!
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
")
I can change the fontsize argument below to be either graph [fontsize = 1] or graph [fontsize = 10] or graph [fontsize = 100] and the output in my R Studio viewer is identical. It appears the font defaults to a reasonable size that fills the node it occupies. How do I change the font size?
library(DiagrammeR)
grViz("
digraph test {
graph [fontsize = 10]
node [shape = box]
A [label = 'FooBar']
B [label = 'BarFoo']
A -> B
}
")
You change the font size of the node labels within the node declaration.
You can change it using node: node [shape = box, fontsize=5] or in a specific node label with: A [label = 'FooBar', fontsize=5]
I use GrapViz graphs through R package DiagrammeR and RStudio. In my graphs international symbols like Ąą Čč Ęę Ėė Įį Šš Ųų Ūū Žž which are either in "Latin-4" ("ISO-8859-4") or in "Latin-6" ("ISO-8859-10") chart sets are not displayed correctly. I am aware of parameter charset [link], but it does not seem working with ("Latin-4" or "Latin-6").
Is there a way to use the listed symbols in GraphViz? I wonder if there is a possibility to indicate encoding in some other way?
digraph Latin6 {
graph [label = "Latin 6";
charset = "ISO-8859-10"]
A [label = "<A> Ąą"]
C [label = "<C> Čč"]
E [label = "<E> Ęę"]
E2 [label = "<E2> Ėė"]
I [label = "<I> Įį"]
S [label = "<S> Šš"]
U [label = "<U> Ųų"]
U2 [label = "<U2> Ūū"]
Zz [label = "<Zz> Žž"]
A -> C;
C -> E;
E -> E2;
E2 -> I;
S -> U;
U -> U2;
U2 -> Zz
}
I know that HTML symbols like #261; from UTF-8 Latin Extended A table may be used. If this conversion from international to HTML symbols is the only option, I would like to know if there is a function in R dedicated for direct (International symbol to HTML code) and backward (vice versa) conversion?
Does anybody know if DiagrammeR currently supports left- and right-justification of node labels when using GraphViz?
Here is a quick example, where I would like to left-justify the text within both of the nodes:
library(DiagrammeR)
grViz("
digraph test {
graph [fontsize = 10]
node [shape = box]
A [label = 'Foo\nBar']
B [label = 'Bar\nFoo']
A -> B
}
")
I was able to find one resource here for the native GraphViz that uses /l for left-justification, but when I try that within the grViz function I receive an error. For example:
library(DiagrammeR)
grViz("
digraph test {
graph [fontsize = 10]
node [shape = box]
A [label = 'Foo\lBar']
B [label = 'Bar\lFoo']
A -> B
}
")
I appreciate any help in advance!
You need a double backslash to escape the first slash. Here are left and right justified labels:
grViz("
digraph test {
graph [fontsize = 10]
node [shape = box]
A [label = 'Foo\\lBar\\l']
B [label = 'Bar\\rFoo\\r']
A -> B
}
")