From 0b37d50c62bf8913d1af5fed7f39802d200bdf4a Mon Sep 17 00:00:00 2001 From: Allen Larocque Date: Thu, 9 Jul 2026 16:25:08 -0700 Subject: [PATCH] Fix davidson-harel layout crash on graphs > 1024 nodes (#362) heat_tree(layout = "davidson-harel") errored with "The value is not representable as an integer. Invalid value" from igraph whenever a connected component of the graph exceeded 1024 nodes. igraph::layout_with_dh() requires an integer `fineiter`, but layout_functions() computed it as `max(10, log2(vcount(graph))) * effort`. `log2(vcount)` is non-integer once vcount > 1024 (2^10), so igraph rejected it. Round `fineiter` (and `maxiter`, defensively for non-integer `effort`) to integers. Co-Authored-By: Claude Opus 4.8 --- NEWS.md | 4 ++++ R/heat_tree--layouts.R | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 89adae45..3088436b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ # News +## metacoder 0.3.9.9000 (development version) + +* Fixed `heat_tree()` erroring with `The value is not representable as an integer. Invalid value` when using `layout = "davidson-harel"` on a graph with a connected component larger than 1024 nodes. The `fineiter` argument passed to `igraph::layout_with_dh()` must be an integer, but was computed as `max(10, log2(vcount(graph)))`, which is non-integer once `vcount > 1024`. It is now rounded (issue [#362](https://github.com/grunwaldlab/metacoder/issues/362)). + ## metacoder 0.3.9 * Maintenance release to fix CRAN check issues. diff --git a/R/heat_tree--layouts.R b/R/heat_tree--layouts.R index cbc61e5a..f68cc574 100644 --- a/R/heat_tree--layouts.R +++ b/R/heat_tree--layouts.R @@ -46,8 +46,13 @@ layout_functions <- function(name = NULL, graph = NULL, intitial_coords = NULL, "reingold-tilford" = list(circular = TRUE, mode = "out"), "davidson-harel" = list(coords = intitial_coords, - maxiter = 10 * effort, - fineiter = max(10, log2(igraph::vcount(graph))) * effort, + maxiter = round(10 * effort), + # `fineiter` is passed to igraph::layout_with_dh(), which + # requires an integer. `log2(vcount)` is non-integer once a + # (connected component of the) graph exceeds 1024 nodes, so + # round to avoid igraph's "not representable as an integer" + # error (grunwaldlab/metacoder#362). + fineiter = round(max(10, log2(igraph::vcount(graph))) * effort), cool.fact = 0.75 - effort * 0.1, weight.node.dist = 13, #* ifelse(is.null(v_weight), 1, list(rescale(v_weight, c(.1, 10))))[[1]], #higher values spread out nodes weight.border = 0,