Q: In DiagrammeR native syntax, how does one force certain nodes to be on the same rank?
E.g., below I was able to force nodes 4, 5, 6, 7 onto the same rank by creating an invisible node 2, with invisible edges in and out of it. But this is just a hack. And the resulting diagram is a little off balance. There must be a better way to do this, right?
library(DiagrammeR)
g <- create_graph(attr_theme="tb")
g <- add_node(g) # node 1
g <- add_node(g, from=1, node_aes = node_aes(style = "invisible"), edge_aes = edge_aes(style = "invisible", arrowhead = "none")) # node 2, my invisible node
g <- add_node(g, from=1, edge_aes = edge_aes(style = "solid")) # node 3
g <- add_node(g, from=2, edge_aes = edge_aes(style = "invisible", arrowhead = "none")) # node 4
g <- add_node(g, from=2, edge_aes = edge_aes(style = "invisible", arrowhead = "none")) # node 5
g <- add_edge(g, from=1,to=4, edge_aes = edge_aes(style = "solid"))
g <- add_edge(g, from=1,to=5, edge_aes = edge_aes(style = "solid"))
g <- add_node(g, from=3) # node 6
g <- add_node(g, from=3) # node 7
render_graph(g)

I think the answer here is that if you want that level of control of positioning, you have to do all the positioning by yourself. For example,
Created on 2023-09-03 with reprex v2.0.2
There are other graph packages (e.g.
igraph,Rgraphviz) that have functions which do layouts and output the coordinates; perhaps one of those is more flexible thanDiagrammeRand would allow you to do automatic placement subject to some constraints. You might even be able to use a different package for the layout, then use the same layout values inDiagrammeR.