Skip to content

Commit d886780

Browse files
authored
feat: added proper support for adding attributes via data.frames (#1716)
1 parent 07e0ccb commit d886780

File tree

4 files changed

+247
-249
lines changed

4 files changed

+247
-249
lines changed

R/attributes.R

+24-25
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@ graph.attributes <- function(graph) {
349349
"graph.attributes<-" <- function(graph, value) {
350350
ensure_igraph(graph)
351351
assert_named_list(value)
352+
if (inherits(value, "data.frame")) {
353+
value <- as.list(value)
354+
}
352355

353356
.Call(R_igraph_mybracket2_set, graph, igraph_t_idx_attr, igraph_attr_idx_graph, value)
354357
}
@@ -487,12 +490,8 @@ i_set_vertex_attr <- function(graph, name, index = V(graph), value, check = TRUE
487490
} else if (length(value) == length(index)) {
488491
value_in <- unname(value)
489492
} else {
490-
stop(
491-
"Length of new attribute value must be ",
492-
if (length(index) != 1) "1 or ",
493-
length(index),
494-
", the number of target vertices, not ",
495-
length(value)
493+
cli::cli_abort(
494+
"Length of new attribute value must be {if (length(index) != 1) '1 or '}{length(index)}, the number of target vertices, not {length(value)}."
496495
)
497496
}
498497

@@ -541,16 +540,19 @@ set_value_at <- function(value, idx, length_out) {
541540
ensure_igraph(graph)
542541

543542
assert_named_list(value)
543+
if (inherits(value, "data.frame")) {
544+
value <- as.list(value)
545+
}
544546

545547
if (!all(lengths(value) == length(index))) {
546-
stop("Invalid attribute value length, must match number of vertices")
548+
cli::cli_abort("Invalid attribute value length, must match number of vertices.")
547549
}
548550

549551
if (!missing(index)) {
550552
index <- as_igraph_vs(graph, index)
551553

552554
if (anyDuplicated(index) || anyNA(index)) {
553-
stop("Invalid vertices in index")
555+
cli::cli_abort("{.arg index} contains duplicated vertices or NAs.")
554556
}
555557
}
556558

@@ -698,12 +700,8 @@ i_set_edge_attr <- function(graph, name, index = E(graph), value, check = TRUE)
698700
} else if (length(value) == length(index)) {
699701
value_in <- unname(value)
700702
} else {
701-
stop(
702-
"Length of new attribute value must be ",
703-
if (length(index) != 1) "1 or ",
704-
length(index),
705-
", the number of target edges, not ",
706-
length(value)
703+
cli::cli_abort(
704+
"Length of new attribute value must be {if (length(index) != 1) '1 or '}{length(index)}, the number of target edges, not {length(value)}."
707705
)
708706
}
709707

@@ -741,15 +739,18 @@ edge.attributes <- function(graph, index = E(graph)) {
741739
ensure_igraph(graph)
742740

743741
assert_named_list(value)
742+
if (inherits(value, "data.frame")) {
743+
value <- as.list(value)
744+
}
744745

745746
if (any(sapply(value, length) != length(index))) {
746-
stop("Invalid attribute value length, must match number of edges")
747+
cli::cli_abort("Invalid attribute value length, must match number of edges")
747748
}
748749

749750
if (!missing(index)) {
750751
index <- as_igraph_es(graph, index)
751752
if (any(duplicated(index)) || any(is.na(index))) {
752-
stop("Invalid edges in index")
753+
cli::cli_abort("{.arg index} contains duplicated edges or NAs.")
753754
}
754755
}
755756

@@ -855,7 +856,7 @@ delete_graph_attr <- function(graph, name) {
855856

856857
name <- as.character(name)
857858
if (!name %in% graph_attr_names(graph)) {
858-
stop("No such graph attribute: ", name)
859+
cli::cli_abort("No graph attribute {.arg {name}} found.")
859860
}
860861

861862
gattr <- .Call(R_igraph_mybracket2, graph, igraph_t_idx_attr, igraph_attr_idx_graph)
@@ -884,7 +885,7 @@ delete_vertex_attr <- function(graph, name) {
884885

885886
name <- as.character(name)
886887
if (!name %in% vertex_attr_names(graph)) {
887-
stop("No such vertex attribute: ", name)
888+
cli::cli_abort("No vertex attribute {.arg {name}} found.")
888889
}
889890

890891
vattr <- .Call(R_igraph_mybracket2, graph, igraph_t_idx_attr, igraph_attr_idx_vertex)
@@ -913,7 +914,7 @@ delete_edge_attr <- function(graph, name) {
913914

914915
name <- as.character(name)
915916
if (!name %in% edge_attr_names(graph)) {
916-
stop("No such edge attribute: ", name)
917+
cli::cli_abort("No edge attribute {.arg {name}} found.")
917918
}
918919

919920
eattr <- .Call(R_igraph_mybracket2, graph, igraph_t_idx_attr, igraph_attr_idx_edge)
@@ -1020,7 +1021,7 @@ igraph.i.attribute.combination <- function(comb) {
10201021
if (any(!sapply(comb, function(x) {
10211022
is.function(x) || (is.character(x) && length(x) == 1)
10221023
}))) {
1023-
stop("Attribute combination element must be a function or character scalar")
1024+
cli::cli_abort("Attribute combination element must be a function or character scalar.")
10241025
}
10251026
if (is.null(names(comb))) {
10261027
names(comb) <- rep("", length(comb))
@@ -1041,7 +1042,7 @@ igraph.i.attribute.combination <- function(comb) {
10411042
)
10421043
x <- pmatch(tolower(x), known[, 1])
10431044
if (is.na(x)) {
1044-
stop("Unknown/unambigous attribute combination specification")
1045+
cli::cli_abort("Unknown/unambigous attribute combination specification.")
10451046
}
10461047
known[, 2][x]
10471048
}
@@ -1185,17 +1186,15 @@ NULL
11851186
}
11861187

11871188
assert_named_list <- function(value) {
1188-
error_msg <- "{.arg value} must be a named list with unique names"
1189-
11901189
if (!is.list(value)) {
1191-
rlang::abort(error_msg)
1190+
cli::cli_abort("{.arg value} must be a named list with unique names")
11921191
}
11931192

11941193
if (length(value) == 0) {
11951194
return()
11961195
}
11971196

11981197
if (!rlang::is_named(value) || anyDuplicated(names(value)) > 0) {
1199-
rlang::abort(error_msg)
1198+
cli::cli_abort("{.arg value} must be a named list with unique names")
12001199
}
12011200
}

tests/testthat/_snaps/attributes.md

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# error messages work
2+
3+
Code
4+
set_vertex_attr(g, "test", value = c(1, 2))
5+
Condition
6+
Error in `i_set_vertex_attr()`:
7+
! Length of new attribute value must be 1 or 5, the number of target vertices, not 2.
8+
9+
---
10+
11+
Code
12+
set_edge_attr(g, "test", value = c(1, 2))
13+
Condition
14+
Error in `i_set_edge_attr()`:
15+
! Length of new attribute value must be 1 or 10, the number of target edges, not 2.
16+
17+
---
18+
19+
Code
20+
delete_graph_attr(g, "a")
21+
Condition
22+
Error in `delete_graph_attr()`:
23+
! No graph attribute `a` found.
24+
25+
---
26+
27+
Code
28+
delete_vertex_attr(g, "a")
29+
Condition
30+
Error in `delete_vertex_attr()`:
31+
! No vertex attribute `a` found.
32+
33+
---
34+
35+
Code
36+
delete_edge_attr(g, "a")
37+
Condition
38+
Error in `delete_edge_attr()`:
39+
! No edge attribute `a` found.
40+
41+
---
42+
43+
Code
44+
assert_named_list("a")
45+
Condition
46+
Error in `assert_named_list()`:
47+
! `value` must be a named list with unique names
48+
49+
---
50+
51+
Code
52+
assert_named_list(list("a", "b"))
53+
Condition
54+
Error in `assert_named_list()`:
55+
! `value` must be a named list with unique names
56+

0 commit comments

Comments
 (0)