边的权重属性不适用于“DiagrammeR”R 包

weight attribute of edges not working on `DiagrammeR` R package

我正在尝试使用 R 中的 DiagrammeR 包向 GraphViz 图添加一些边属性。特别是,我想添加属性 arrowheadweight,但是只有前者被添加到图中而不是后者。下面的示例不是真实示例,而是为了再现性和清晰度而对其进行的超简化版本。

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)

非常感谢任何帮助。

谢谢。 最好的,

我不确定这是一个错误还是 "weight" 被故意忽略了,但无论如何,罪魁祸首是 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")
}

如果您将 "weight" 添加到该列表 – 或修改 generate_dot 以允许所有属性而不进行检查 –,您的示例工作得很好。