为什么 igraph plot 警告说 "number of items to replace is not a multiple of replacement length"?
Why igraph plot warns that "number of items to replace is not a multiple of replacement length"?
我有一个图,两个节点之间有很多边。当我绘制它时,我收到一条我在这种情况下不理解的警告。
这很好用:
library(igraph)
gg <- graph.empty(n=0, directed=TRUE)
gg <- gg + vertex("10501")
gg <- gg + edge("10501", "10501")
gg <- gg + edge("10501", "10501")
plot(gg)
但是多一条边的同一张图给出警告:
gg <- graph.empty(n=0, directed=TRUE)
gg <- gg + vertex("10501")
gg <- gg + edge("10501", "10501")
gg <- gg + edge("10501", "10501")
gg <- gg + edge("10501", "10501")
plot(gg)
我看不出原因。为什么出现此警告?
在 igraph
包源中搜索发出警告的行,罪魁祸首似乎是 plot.common.R
中的 autocurve.edges
:
autocurve.edges <- function(graph, start=0.5) {
cm <- count.multiple(graph)
el <- apply(get.edgelist(graph, names=FALSE), 1, paste, collapse=":")
ord <- order(el)
res <- numeric(length(ord))
p <- 1
while (p <= length(res)) {
m <- cm[ord[p]]
idx <- p:(p+m-1)
if (m==1) {
r <- 0
} else {
r <- seq(-start, start, length=m)
}
res[ord[idx]] <- r
p <- p + m
}
res
}
根据 ?igraph.plotting
(和包源),默认调用 autocurve.edges
函数来确定如何弯曲边缘:
By default the vector specifying the curvatire is calculated via a call to the autocurve.edges function. This function makes sure that multiple edges are curved and are all visible. This parameter is ignored for loop edges.
从 igraph.plot
的早期开始,我们可以看到调用了这个函数,并传递了整个图形:
curved <- params("edge", "curved")
if (is.function(curved)) { curved <- curved(graph) }
这是有问题的图表上警告的来源:
autocurve.edges(gg)
# [1] -0.5 -0.5 0.0
# Warning messages:
# 1: In res[ord[idx]] <- r :
# number of items to replace is not a multiple of replacement length
# 2: In res[ord[idx]] <- r :
# number of items to replace is not a multiple of replacement length
为了深入研究为什么会出现这些问题,此函数所做的第一件事是调用 count.multiple
,其中 returns 每条边的重复次数。在有问题的图表中:
count.multiple(gg)
# [1] 1.5 1.5 1.5
它没有返回 c(3, 3, 3)
(因为循环边重复了 3 次),而是返回了 c(1.5, 1.5, 1.5)
。虽然我在 ?count.multiple
中没有看到任何提及,但这是因为如果它是一个循环(也就是从节点到自身的边),则边的计数除以 2,原因如下igraph
包源中 structural_properties.c
文件中的 igraph_count_multiple
行:
/* for loop edges, divide the result by two */
if (to == from) VECTOR(*res)[i] /= 2;
生成警告的事实是由于一个错误——autocurve.edges
期望得到 c(3, 3, 3)
但由于 count.multiple
而得到 c(1.5, 1.5, 1.5)
循环边缘。我认为 autocurve.edges
实际上可以使用类似的东西在纯 R 中重新实现:
autocurve.edges <- function(graph, start=0.5) {
el <- apply(get.edgelist(graph, names=FALSE), 1, paste, collapse=":")
ave(rep(NA, length(el)), el, FUN=function(x) {
if (length(x) == 1) {
return(0)
} else {
return(seq(-start, start, length=length(x)))
}
})
}
此外,我认为 count.multiple
的文档应该更新以提及其对循环边缘的特殊处理。
与此同时,我认为您的解决方案是手动指定曲率参数以避免出现警告:
plot(gg, edge.curved=FALSE)
更新: 作为 pull request 提交给 rigraph 项目,现在合并到 R igraph 项目的 dev 分支:https://github.com/igraph/rigraph/pull/80
我有一个图,两个节点之间有很多边。当我绘制它时,我收到一条我在这种情况下不理解的警告。
这很好用:
library(igraph)
gg <- graph.empty(n=0, directed=TRUE)
gg <- gg + vertex("10501")
gg <- gg + edge("10501", "10501")
gg <- gg + edge("10501", "10501")
plot(gg)
但是多一条边的同一张图给出警告:
gg <- graph.empty(n=0, directed=TRUE)
gg <- gg + vertex("10501")
gg <- gg + edge("10501", "10501")
gg <- gg + edge("10501", "10501")
gg <- gg + edge("10501", "10501")
plot(gg)
我看不出原因。为什么出现此警告?
在 igraph
包源中搜索发出警告的行,罪魁祸首似乎是 plot.common.R
中的 autocurve.edges
:
autocurve.edges <- function(graph, start=0.5) {
cm <- count.multiple(graph)
el <- apply(get.edgelist(graph, names=FALSE), 1, paste, collapse=":")
ord <- order(el)
res <- numeric(length(ord))
p <- 1
while (p <= length(res)) {
m <- cm[ord[p]]
idx <- p:(p+m-1)
if (m==1) {
r <- 0
} else {
r <- seq(-start, start, length=m)
}
res[ord[idx]] <- r
p <- p + m
}
res
}
根据 ?igraph.plotting
(和包源),默认调用 autocurve.edges
函数来确定如何弯曲边缘:
By default the vector specifying the curvatire is calculated via a call to the autocurve.edges function. This function makes sure that multiple edges are curved and are all visible. This parameter is ignored for loop edges.
从 igraph.plot
的早期开始,我们可以看到调用了这个函数,并传递了整个图形:
curved <- params("edge", "curved")
if (is.function(curved)) { curved <- curved(graph) }
这是有问题的图表上警告的来源:
autocurve.edges(gg)
# [1] -0.5 -0.5 0.0
# Warning messages:
# 1: In res[ord[idx]] <- r :
# number of items to replace is not a multiple of replacement length
# 2: In res[ord[idx]] <- r :
# number of items to replace is not a multiple of replacement length
为了深入研究为什么会出现这些问题,此函数所做的第一件事是调用 count.multiple
,其中 returns 每条边的重复次数。在有问题的图表中:
count.multiple(gg)
# [1] 1.5 1.5 1.5
它没有返回 c(3, 3, 3)
(因为循环边重复了 3 次),而是返回了 c(1.5, 1.5, 1.5)
。虽然我在 ?count.multiple
中没有看到任何提及,但这是因为如果它是一个循环(也就是从节点到自身的边),则边的计数除以 2,原因如下igraph
包源中 structural_properties.c
文件中的 igraph_count_multiple
行:
/* for loop edges, divide the result by two */
if (to == from) VECTOR(*res)[i] /= 2;
生成警告的事实是由于一个错误——autocurve.edges
期望得到 c(3, 3, 3)
但由于 count.multiple
而得到 c(1.5, 1.5, 1.5)
循环边缘。我认为 autocurve.edges
实际上可以使用类似的东西在纯 R 中重新实现:
autocurve.edges <- function(graph, start=0.5) {
el <- apply(get.edgelist(graph, names=FALSE), 1, paste, collapse=":")
ave(rep(NA, length(el)), el, FUN=function(x) {
if (length(x) == 1) {
return(0)
} else {
return(seq(-start, start, length=length(x)))
}
})
}
此外,我认为 count.multiple
的文档应该更新以提及其对循环边缘的特殊处理。
与此同时,我认为您的解决方案是手动指定曲率参数以避免出现警告:
plot(gg, edge.curved=FALSE)
更新: 作为 pull request 提交给 rigraph 项目,现在合并到 R igraph 项目的 dev 分支:https://github.com/igraph/rigraph/pull/80