When setting an attribute that already exists (using V()<- or set_vertex_attr() and presumably also with edge attributes), igraph (1.2.6) will convert the new value to match the class of any existing value. For example:
library(igraph)
#>
#> Attaching package: 'igraph'
#> The following objects are masked from 'package:stats':
#>
#> decompose, spectrum
#> The following object is masked from 'package:base':
#>
#> union
# does some processing and stores the result in a new integer attribute 'kind'
set_kind <- function(gr) {
# gr <- delete_vertex_attr(gr, "kind") # workaround
set_vertex_attr(gr, "kind", value = vcount(gr))
}
# (1) processing a clean graph works as expected
g <- make_full_graph(n=1)
g <- set_kind(g)
class(V(g)$kind)
#> [1] "numeric"
# (2) this graph happens to have an existing attribute 'kind' with a different class;
# the result now has the wrong class
g <- make_full_graph(n=1) %>% set_vertex_attr("kind", value = "big")
g <- set_kind(g)
class(V(g)$kind)
#> [1] "character"
Created on 2021-06-10 by the reprex package (v2.0.0)
Basically I would expect the parts marked (1) and (2) to do the same thing, but the result actually depends on whatever value the attribute had before. This makes V() <- inconsistent with the normal R semantics of the <- operator which allow you to replace a variable with a value of a different class just fine.
To make the processing code robust against arbitrary input graphs, it's necessary to explicitly clear every attribute before setting it, but this becomes cumbersome.
When setting an attribute that already exists (using
V()<-orset_vertex_attr()and presumably also with edge attributes), igraph (1.2.6) will convert the new value to match the class of any existing value. For example:Created on 2021-06-10 by the reprex package (v2.0.0)
Basically I would expect the parts marked (1) and (2) to do the same thing, but the result actually depends on whatever value the attribute had before. This makes
V() <-inconsistent with the normal R semantics of the<-operator which allow you to replace a variable with a value of a different class just fine.To make the processing code robust against arbitrary input graphs, it's necessary to explicitly clear every attribute before setting it, but this becomes cumbersome.