diff --git a/R/attributes.R b/R/attributes.R index 1e3348ac6e..7cbcd784c2 100644 --- a/R/attributes.R +++ b/R/attributes.R @@ -616,6 +616,31 @@ i_set_vertex_attr <- function( igraph_attr_idx_vertex ) + # Uniqueness check for vertex "name" attribute + if (name == "name") { + current_names <- vattrs[["name"]] + if (is.null(current_names)) { + current_names <- rep_len(NA_character_, vcount(graph)) + } + + unaffected <- setdiff(seq_along(current_names), index) + unaffected_names <- current_names[unaffected] + + if (length(value) == 1 && length(index) > 1) { + cli::cli_abort( + "Cannot set vertex attribute {.arg {name}} to a single value ({value}) for multiple vertices because it results in duplicate names." + ) + } + + if (any(value %in% unaffected_names)) { + dupes <- value[value %in% unaffected_names] + cli::cli_abort( + "{cli::qty(length(unique(dupes)))} Vertex {?name/names} already {?exists/exist}: + {paste(unique(dupes), collapse = ', ')}" + ) + } + } + complete <- is_complete_iterator(index) name_available <- (name %in% names(vattrs)) if (!complete && !name_available) { diff --git a/R/interface.R b/R/interface.R index e5317fd54e..da03e1b50c 100644 --- a/R/interface.R +++ b/R/interface.R @@ -213,7 +213,7 @@ add_vertices <- function(graph, nv, ..., attr = list()) { attrs <- append(attrs, attr) nam <- names(attrs) if (length(attrs) != 0 && (is.null(nam) || any(nam == ""))) { - stop("please supply names for attributes") + cli::cli_abort("Attribute names must be supplied.") } vertices.orig <- vcount(graph) diff --git a/tests/testthat/_snaps/attributes.md b/tests/testthat/_snaps/attributes.md index 172c445888..295eeb44f7 100644 --- a/tests/testthat/_snaps/attributes.md +++ b/tests/testthat/_snaps/attributes.md @@ -62,6 +62,22 @@ Error in `set_graph_attr()`: ! `name` must be a single string, not the number 1. +# duplicated vertex names are handled correctly + + Code + add_vertices(g, nv = 2, attr = list(name = c("A", "B"))) + Condition + Error in `i_set_vertex_attr()`: + ! Vertex names already exist: A, B + +--- + + Code + set_vertex_attr(g, "name", 2:3, "C") + Condition + Error in `i_set_vertex_attr()`: + ! Cannot set vertex attribute `name` to a single value (C) for multiple vertices because it results in duplicate names. + # set_vertex_attrs() works Code diff --git a/tests/testthat/test-attributes.R b/tests/testthat/test-attributes.R index 71d70df15f..684dc40ece 100644 --- a/tests/testthat/test-attributes.R +++ b/tests/testthat/test-attributes.R @@ -470,6 +470,19 @@ test_that("good error message when not using character", { }) }) +test_that("duplicated vertex names are handled correctly", { + g <- make_empty_graph(4) + V(g)$name <- LETTERS[1:4] + expect_snapshot(error = TRUE, { + add_vertices(g, nv = 2, attr = list(name = c("A", "B"))) + }) + + g <- graph_from_literal("A"--"B", "C"--"D") + expect_snapshot(error = TRUE, { + set_vertex_attr(g, "name", 2:3, "C") + }) +}) + test_that("set_vertex_attrs() works", { g <- make_ring(10) g <- set_vertex_attrs(g, color = "blue", size = 10, name = LETTERS[1:10])