我正在尝试使用 R 中的DiagrammeR
包向 GraphViz 图添加一些边缘属性。特别是,我想添加属性arrowhead
和weight
,但只有前者添加到图形中,而不是后者。下面的示例不是真实的示例,而是为了可重复性和清晰度而对其进行的超简化版本。
library(tidyverse)
library(DiagrammeR)
# create nodes
nd <- tibble(
label = c("A", "B", "C", "D"),
rank = c("1", "0", "2", "2")
)
node <- create_node_df(
n = nrow(nd),
label = nd$label,
id = c(1:nrow(nd)),
# rank = nd$rank
)
# create edges
ed <- tribble(
~from, ~to, ~arrowhead, ~weight,
1, 2, 'normal', "5",
1, 3, 'normal', "1",
3, 4, 'normal', "1",
3, 2, 'normal', "1"
)
edge <- create_edge_df(
from = ed$from,
to = ed$to,
arrowhead = ed$arrowhead,
weight = ed$weight
)
# create graph
graph <-
create_graph(
nodes_df = node,
edges_df = edge) %>%
add_global_graph_attrs(
attr = "overlap",
value = "false",
attr_type = "graph") %>%
add_global_graph_attrs(
attr = "layout",
value = "dot",
attr_type = "graph")
然而,当我生成dot
代码时,weight
属性不是边缘的一部分,而是arrowhead
graph %>%
generate_dot() %>%
cat()
#> digraph {
#>
#> graph [layout = 'dot',
#> outputorder = 'edgesfirst',
#> bgcolor = 'white',
#> overlap = 'false']
#>
#> node [fontname = 'Helvetica',
#> fontsize = '10',
#> shape = 'circle',
#> fixedsize = 'true',
#> width = '0.5',
#> style = 'filled',
#> fillcolor = 'aliceblue',
#> color = 'gray70',
#> fontcolor = 'gray50']
#>
#> edge [fontname = 'Helvetica',
#> fontsize = '8',
#> len = '1.5',
#> color = 'gray80',
#> arrowsize = '0.5']
#>
#> '1' [label = 'A']
#> '2' [label = 'B']
#> '3' [label = 'C']
#> '4' [label = 'D']
#> '1'->'2' [arrowhead = 'normal']
#> '1'->'3' [arrowhead = 'normal']
#> '3'->'4' [arrowhead = 'normal']
#> '3'->'2' [arrowhead = 'normal']
#> }
我还尝试使用set_edge_attrs()
添加属性,但它仍然不起作用。
graph <- graph %>%
set_edge_attrs(edge_attr = "weight",
values = "5",
from = 1,
to = 2
)
# digraph {
#
# graph ...
# {trimmed output}
#
# '1'->'2' [arrowhead = 'normal']
# '1'->'3' [arrowhead = 'normal']
# '3'->'4' [arrowhead = 'normal']
# '3'->'2' [arrowhead = 'normal']
# }
最后,我不得不手动修改dot
代码(见下文(,但鉴于我必须从数据框中的信息生成多个图表,这并不理想。
graph2 <- "digraph {
graph [layout = 'dot',
outputorder = 'edgesfirst',
bgcolor = 'white',
overlap = 'false']
node [fontname = 'Helvetica',
fontsize = '10',
shape = 'circle',
fixedsize = 'true',
width = '0.5',
style = 'filled',
fillcolor = 'aliceblue',
color = 'gray70',
fontcolor = 'gray50']
edge [fontname = 'Helvetica',
fontsize = '8',
len = '1.5',
color = 'gray80',
arrowsize = '0.5']
'1' [label = 'A']
'2' [label = 'B']
'3' [label = 'C']
'4' [label = 'D']
'1'->'2' [arrowhead = 'normal', weight = 5]
'1'->'3' [arrowhead = 'normal', weight = 0]
'3'->'4' [arrowhead = 'normal', weight = 0]
'3'->'2' [arrowhead = 'normal', weight = 0]
}
"
grViz(graph2)
我非常感谢任何帮助。
谢谢。 最好
我不确定这是一个错误还是故意忽略了"权重",但无论如何,罪魁祸首是DiagrammeR
中的一个辅助函数,它生成允许属性的向量generate_dot()
并且只允许来自该向量的属性。
# DiagrammeR/R/utils.R
gv_edge_attributes <- function() {
c("style", "penwidth", "color", "arrowsize",
"arrowhead", "arrowtail",
"fontname", "fontsize", "fontcolor",
"len", "tooltip", "URL",
"label", "labelfontname", "labelfontsize",
"labelfontcolor", "labeltooltip", "labelURL",
"edgetooltip", "edgeURL",
"headtooltip", "headURL",
"headclip", "headlabel", "headport",
"tailtooltip", "tailURL",
"tailclip", "taillabel", "tailport",
"dir", "decorate")
}
如果将"权重"添加到该列表中 - 或修改generate_dot
以允许所有属性而不进行检查 - 您的示例工作正常。