在Rgraphviz中设置边缘宽度

时间:2015-03-26 15:28:49

标签: r graph graphviz

显然,尽管没有详细记录,但可以在Rgraphviz中设置边缘宽度。这是一种方法:

library(graph)
library(Rgraphviz)
nodes <- c( LETTERS[1:3] )
edgesL <- list( A=c("B", "C"), B=c("A", "C"), C=c("B", "A" ) )
graph <- new( "graphNEL", nodes= nodes, edgemode="undirected", edgeL=edgesL )
rag <- agopen( graph, "" )
rag@AgEdge[[1]]@lwd <- 5
plot(rag)

插槽“lwd”在AgEdge手册页中明确定义。结果:

enter image description here

到目前为止,这么好。但是,我无法使用边缘ID(即“A~C”)访问AgEdge对象,只能使用数字索引。如何使用上述方法告诉graphviz更改A和C之间边缘的lwd?

添加属性值的正确方法是通过agopen()的edgeAttrs选项。让我们尝试使用文档属性:

eAttrs <- list( color=c( "A~C"="red" ) )
rag <- agopen( graph, "", edgeAttrs=eAttrs )
plot(rag)

好的,结果是正确的:

enter image description here

好的,那么lwd怎么样;但是 - 无赖:

> eAttrs <- list( lwd=c( "A~C"=5 ) )
> rag <- agopen( graph, "", edgeAttrs=eAttrs )
Error in buildEdgeList(graph, recipEdges, edgeAttrs, subGList, attrs$edge) : 
  no slot of name "name" for this object of class "pEdge"

奇怪的是,当你查找agopen函数时,你会发现以下代码片段:

if (!is.null(edgeAttrs$lwd)) {
    for (i in seq(along = edgeAttrs$lwd)) {
        attr(attr(g, "AgEdge")[[i]], "lwd") <- edgeAttrs$lwd[i]
    }
}

这看起来理论上,edgeAttrs应该能够处理lwd。不幸的是,文档没有帮助:如果你查看“agopen”的手册页,它会告诉你

 For a description of ‘attrs’, ‘nodeAttrs’ and ‘edgeAttrs’, see the
 ‘Ragraph’ man page.

然而,Ragraph手册页中根本没有提到“edgeAttrs”。我很困惑也很生气。而且绝望了。绝望的人研究源代码。显然,agopen()会抛出错误,因为getDefaultAttrs()不知道lwd插槽。我们可以修改它:

eAttrs <- list( lwd=list( "A~C"=5, "A~B"=1 ) )
rag <- agopen( graph, "", edgeAttrs=eAttrs, attrs= list(edge=list(lwd=2)) )
plot(rag)

这至少不会产生错误信息,但会产生错误的图表:

enter image description here

这是因为上面这个奇怪的代码片段使用seq(along= .. )来填写lwd信息,完全忽略了这是一个命名列表的事实,我们想要通过边缘名称而不是它们的顺序输入信息。 / p>

所以,我的问题。是否有一种简单的,有文件记录的方式来显示R / Rgraphviz中具有不同边缘宽度的图形? (我需要Rgraphviz,因为我想用自定义函数绘制节点,其他包不提供此功能,我认为)。

或者我需要编写自己的拐杖?哦,我可以这样做,这是一个函数,为ID1和ID2之间的边设置一个属性(可以是相同长度的向量,提供的值也是相同长度的向量):

setEdgeAttr <- function( graph, attribute, value, ID1, ID2 ) {

  idfunc <- function(x) paste0( sort(x), collapse="~" )
  all.ids <- sapply( AgEdge(graph), 
    function(e) idfunc( c( attr(e, "head"), attr( e, "tail" ))))

  sel.ids <- apply(cbind( ID1, ID2 ), 1, idfunc )

  if(!all(sel.ids %in% all.ids)) stop( "only existing edges, please" )
  sel <- match( sel.ids, all.ids )

  for(i in 1:length(sel)) {
    attr( attr( graph, "AgEdge" )[[ sel[i] ]], attribute ) <- value[i]
  }

  return(graph)
}

有用吗?哦,是的:

rag <- agopen( graph, "" )
rag <- setEdgeAttr( rag, "lwd", c(5, 20), c("B", "B"), c( "A", "C" ) )
plot(rag)

enter image description here

我简直无法相信没有更简单的方法。

0 个答案:

没有答案