I'm trying to customize node position on an x and y axis in a network diagram using DiagrammeR, using the following node, position and edges dfs:
nodesdat <- read.table(text = "
id label color fillcolor fontcolor fontsize
1 1 A1 black white black 16
2 2 A3 black white black 16
5 5 A6 black white black 16
18 18 Si black white black 16
19 19 Z1 black white black 16
", header = TRUE)
positionsdat <- read.table(text = "
label id color fillcolor fontcolor fontsize x y
1 A1 1 black white black 16 3 3
2 A3 2 black white black 16 3 4
5 A6 5 black white black 16 3 5
18 Si 18 black white black 16 2 4
19 Z1 19 black white black 16 5 4
", header = TRUE)
edgesdat <- read.table(text = "
id from to rel dir arrowhead arrowtail style color
1 1 1 1 connected_to both odot none dashed black
2 2 2 2 connected_to both odot none dashed black
5 5 5 5 connected_to both odot none dashed black
39 39 18 1 connected_to both normal odot dashed black
40 40 18 5 connected_to both normal odot solid black
41 41 18 18 connected_to both odot none solid black
42 42 19 2 connected_to both odot normal solid black
43 43 19 19 connected_to both odot none solid black
68 68 18 2 connected_to both none normal dashed black
69 69 18 2 connected_to both normal odot solid black
", header = TRUE)
library(DiagrammeR)
library(DiagrammeRsvg)
library(dplyr)
g <- create_graph(nodes_df = nodesdat, edges_df = edgesdat, directed = TRUE)
render_graph(g)
g2 <- g %>%
add_global_graph_attrs(attr = "width",value = 0.5, attr_type = "node") %>% #node size %>%
add_global_graph_attrs(attr = "penwidth",value = 2, attr_type = "edge" ) %>% #edge size
set_node_position(node=nodesdat$id,x = positionsdat$x, positionsdat$y)
I get the error "Error in !use_labels && !(node %in% graph$nodes_df[, 1]) : 'length = 5' in coercion to 'logical(1)'" from the set_node_position line.
This error doesn't happen when I run the code in R vers 4.0.2, but I've upgraded to 4.4.2
Might be the case that this worked in an older version of R or perhaps an older version of DiagrammeR
. But at least for the most recent version of DiagrammeR
, i.e. 1.0.11
the docs mention that set_node_position
can only be used to set the position of one node at a time, i.e. node=
should be
A single-length vector containing either a node ID value (integer) or a node label (character) for which position information should be applied.
Hence, to fix you issue set the node positions for each node in sequence, e.g. you can loop over the rows of positionsdat
using Reduce
like so:
library(DiagrammeR)
library(DiagrammeRsvg)
library(dplyr)
g <- create_graph(
nodes_df = nodesdat,
edges_df = edgesdat,
directed = TRUE
)
render_graph(g)
g2 <- g %>%
add_global_graph_attrs(
attr = "width", value = 0.5,
attr_type = "node"
) %>% # node size %>%
add_global_graph_attrs(
attr = "penwidth", value = 2,
attr_type = "edge"
) %>% # edge size
Reduce(
\(x, y) {
set_node_position(
x,
node = y$id,
x = y$x,
y = y$y
)
},
x = split(positionsdat, ~id),
init = .
)
render_graph(g2)