Skip to contents

Set operations across two graph objects, regardless of their concrete representation (igraph/tbl_graph, or a visNetwork htmlwidget such as funviewR::plot_dependency_graph() returns). Both graphs are normalized via as_database, combined with the database_setops verbs (dplyr::intersect()/ dplyr::setdiff()/dplyr::union() on the cbe_database class), and rebuilt into an igraph with database_to_igraph.

Usage

graph_intersect(x, y, directed = TRUE)

graph_subtract(x, y, directed = TRUE)

graph_union(x, y, directed = TRUE)

Arguments

x, y

Graph objects: igraph/tbl_graph objects, or visNetwork htmlwidgets.

directed

Logical, whether the rebuilt graph is directed (default TRUE).

Value

An igraph object. Call as_database on the result to get the underlying node/edge tibbles.

Details

These stay dedicated functions rather than intersect.igraph()/ union.igraph()/setdiff.igraph() methods because igraph already registers its own union.igraph() on the same generic – S3 method tables are global, so defining one here would silently collide with igraph's. Going through as_database first sidesteps that entirely: dispatch happens on the cbe_database class this package owns, not on igraph.

graph_intersect() keeps nodes/edges present in both x and y, taking attribute values from x only. graph_subtract() keeps nodes/edges present in x but not in y (edges are additionally constrained to only reference surviving nodes, so the result is always well-formed). graph_union() combines both graphs' nodes and edges, coalescing attribute values so neither side's data is lost on overlap – the same union-and-coalesce behavior as join_pipelines, generalized to any graph type via as_database rather than tbl_graph specifically.

All three are set operations – which nodes/edges exist where – not a value-level comparison of attributes on nodes/edges that happen to match. For that, run compare_df on the two as_database results directly (or on the two graphs themselves).

Examples

g1 <- igraph::graph_from_data_frame(
  data.frame(from = c("a", "b"), to = c("b", "c")),
  vertices = data.frame(name = c("a", "b", "c"))
)
g2 <- igraph::graph_from_data_frame(
  data.frame(from = "a", to = "b"),
  vertices = data.frame(name = c("a", "b"))
)
graph_intersect(g1, g2)
#> IGRAPH fdba346 DN-- 2 1 -- 
#> + attr: name (v/c)
#> + edge from fdba346 (vertex names):
#> [1] a->b
graph_subtract(g1, g2)
#> IGRAPH f92ecfa DN-- 1 0 -- 
#> + attr: name (v/c)
#> + edges from f92ecfa (vertex names):
graph_union(g1, g2)
#> IGRAPH c7f5b7c DN-- 3 2 -- 
#> + attr: name (v/c)
#> + edges from c7f5b7c (vertex names):
#> [1] a->b b->c