Skip to content

Adding vertex names when a named and unnamed graph are combined? #1946

@schochastics

Description

@schochastics

See discussion in #1908 and #1932 (also related: #60)

What should be the strategy when a named and unnamed graph are combined by whatever means
(e.g. disjoint_union(), a graph product, "+",...)

I see two options:

  1. throw an error (consistent with throwing an error when duplicated names are found)
  2. create generic vertex names. An example implementation is at the bottom.

Currently, names are set to NA, which is in my opinion not desirable.

library(igraph)
library(purrr)

consolidate_names <- function(graphs, prefix = "V") {
  have_names <- map_lgl(graphs, function(g) "name" %in% vertex_attr_names(g))
  if (all(have_names)) {
    all_names <- list_c(map(graphs, function(g) V(g)$name))

    if (any(duplicated(all_names))) {
      cli::cli_abort("Duplicated vertex names found across graphs.")
    }
    return(graphs)
  }

  existing_names <- list_c(map(graphs, function(g) V(g)$name))

  # Create a counter for generating new names (check if named graph already has generic names)
  name_counter <- if (any(grepl(paste0(prefix, "[0-9]+"), existing_names))) {
    max(as.integer(gsub(paste0(prefix, "([0-9]+)"), "\\1", existing_names)), na.rm = TRUE) + 1
  } else {
    1
  }

  for (i in seq_along(graphs)) {
    if (!have_names[i]) {
      n <- vcount(graphs[[i]])
      num_id <- seq(name_counter, length.out = n)
      V(graphs[[i]])$name <- paste0(prefix, num_id)
      name_counter <- name_counter + n + 1
    }
  }

  return(graphs)
}

g1 <- g2 <- make_ring(4)
V(g1)$name <- c("A", "B", "C", "D")
graphs <- list(g1, g2)
consolidate_names(graphs)
#> [[1]]
#> IGRAPH 467efa4 UN-- 4 4 -- Ring graph
#> + attr: name (g/c), mutual (g/l), circular (g/l), name (v/c)
#> + edges from 467efa4 (vertex names):
#> [1] A--B B--C C--D A--D
#> 
#> [[2]]
#> IGRAPH 467efa4 UN-- 4 4 -- Ring graph
#> + attr: name (g/c), mutual (g/l), circular (g/l), name (v/c)
#> + edges from 467efa4 (vertex names):
#> [1] V1--V2 V2--V3 V3--V4 V1--V4

V(g1)$name <- c("V1", "V2", "V3", "V4")
graphs <- list(g1, g2)
consolidate_names(graphs)
#> [[1]]
#> IGRAPH 467efa4 UN-- 4 4 -- Ring graph
#> + attr: name (g/c), mutual (g/l), circular (g/l), name (v/c)
#> + edges from 467efa4 (vertex names):
#> [1] V1--V2 V2--V3 V3--V4 V1--V4
#> 
#> [[2]]
#> IGRAPH 467efa4 UN-- 4 4 -- Ring graph
#> + attr: name (g/c), mutual (g/l), circular (g/l), name (v/c)
#> + edges from 467efa4 (vertex names):
#> [1] V5--V6 V6--V7 V7--V8 V5--V8

Created on 2025-07-04 with reprex v2.1.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    breaking changeAPI change likely to affect existing codevertex namesissues related to vertex names (e.g. what to do when named and unnamed graph are combined)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions