rigraph
rigraph copied to clipboard
union.igraph dispatch doesn't work for lists.
I'm not exactly sure if this is fixable, but I've discovered that the function union from igraph errors when passed a list of igraph objects. I think what's happening is R does not recognize the list as belonging to igraph, so it dispatches the union.default
on the list, resulting in an error. Here's the traceback (since reprex doesn't currently have that capability):
6: as.vector(y)
5: unique(c(as.vector(x), as.vector(y)))
4: base::union(...)
3: union.default(list(net1, net2))
2: igraph::union(list(net1, net2))
1: str(igraph::union(list(net1, net2)))
And here's the reprex
cat("Reproducible example with package reprex version", as.character(packageVersion("reprex")))
#> Reproducible example with package reprex version 0.1.1
library("igraph")
#>
#> Attaching package: 'igraph'
#> The following objects are masked from 'package:stats':
#>
#> decompose, spectrum
#> The following object is masked from 'package:base':
#>
#> union
net1 <- graph_from_literal(D - A:B:F:G, A - C - F - A, B - E - G - B, A - B,
F - G, H - F:G, H - I - J)
net2 <- graph_from_literal(D - A:F:Y, B - A - X - F - H - Z, F - Y)
# works
str(net1 %u% net2)
#> IGRAPH UN-- 13 21 --
#> + attr: name (v/c)
#> + edges (vertex names):
#> [1] I--J H--Z H--I G--H G--E F--X F--Y F--H F--C F--G B--E B--G A--X A--C
#> [15] A--F A--B D--Y D--G D--F D--B D--A
# Fails when is a list
str(igraph::union(list(net1, net2)))
#> Error in as.vector(y): argument "y" is missing, with no default
traceback()
#> No traceback available
# Works when first argument is an igraph object
str(igraph::union(net1, list(net2)))
#> IGRAPH UN-- 13 21 --
#> + attr: name (v/c)
#> + edges (vertex names):
#> [1] I--J H--Z H--I G--H G--E F--X F--Y F--H F--C F--G B--E B--G A--X A--C
#> [15] A--F A--B D--Y D--G D--F D--B D--A
Session info
devtools::session_info()
#> Session info --------------------------------------------------------------
#> setting value
#> version R version 3.3.3 (2017-03-06)
#> system x86_64, darwin13.4.0
#> ui X11
#> language (EN)
#> collate en_US.UTF-8
#> tz America/Chicago
#> date 2017-03-31
#> Packages ------------------------------------------------------------------
#> package * version date source
#> backports 1.0.5 2017-01-18 CRAN (R 3.3.2)
#> devtools 1.12.0 2016-06-24 CRAN (R 3.3.0)
#> digest 0.6.12 2017-01-27 CRAN (R 3.3.2)
#> evaluate 0.10 2016-10-11 cran (@0.10)
#> formatR 1.4 2016-05-09 CRAN (R 3.3.0)
#> htmltools 0.3.5 2016-03-21 CRAN (R 3.2.4)
#> igraph * 1.0.1 2015-06-26 CRAN (R 3.2.0)
#> knitr 1.15.16 2017-03-29 Github (yihui/knitr@9f6a1c2)
#> magrittr 1.5 2014-11-22 CRAN (R 3.2.0)
#> memoise 1.0.0 2016-01-29 CRAN (R 3.2.3)
#> Rcpp 0.12.9 2017-01-14 CRAN (R 3.3.2)
#> rmarkdown 1.4.0.9000 2017-03-29 Github (rstudio/rmarkdown@7ca7fd7)
#> rprojroot 1.2 2017-01-16 CRAN (R 3.3.2)
#> stringi 1.1.2 2016-10-01 CRAN (R 3.3.0)
#> stringr 1.2.0 2017-02-18 cran (@1.2.0)
#> withr 1.0.2 2016-06-20 cran (@1.0.2)
#> yaml 2.1.14 2016-11-12 cran (@2.1.14)
I have run into this as well. Current workaround is to do do.call(union, list.of.graphs)
. I don't know how one could ever get this function to work as intended with a list of graphs without making a specific igraphlist
class.
I'm not sure this is a problem with the function, 'union' is only designed to join 2 graphs not deal with lists. mkoohafkan's solution or my alternative both do the job Reduce(union, list.of.graphs )
Thanks, the example do.call(union, list.of.graphs)
worked for me!
You also may want to specify igraph::union due to potential naming conflicts with dplyr::union.
'union' is only designed to join 2 graphs not deal with lists.
That seems incorrect to me. The documentation ( https://igraph.org/r/doc/union.igraph.html ) specifically states "Graph objects or lists of graph objects", doesn't it?
'union' is only designed to join 2 graphs not deal with lists
This is not true, the below example works just fine:
net1 <- graph_from_literal(D - A:B:F:G, A - C - F - A, B - E - G - B, A - B,
F - G, H - F:G, H - I - J)
net2 <- graph_from_literal(D - A:F:Y, B - A - X - F - H - Z, F - Y)
net3 <- graph_from_literal(B - Y - X)
do.call(igraph::union, list(net1, net2, net3))
library("igraph")
#>
#> Attaching package: 'igraph'
#> The following objects are masked from 'package:stats':
#>
#> decompose, spectrum
#> The following object is masked from 'package:base':
#>
#> union
net1 <- graph_from_literal(
D - A:B:F:G, A - C - F - A, B - E - G - B, A - B,
F - G, H - F:G, H - I - J
)
net2 <- graph_from_literal(D - A:F:Y, B - A - X - F - H - Z, F - Y)
net1 %u% net2
#> IGRAPH e5c9323 UN-- 13 21 --
#> + attr: name (v/c)
#> + edges from e5c9323 (vertex names):
#> [1] I--J H--Z H--I G--H G--E F--X F--Y F--H F--C F--G B--E B--G A--X A--C A--F
#> [16] A--B D--Y D--G D--F D--B D--A
igraph::union(list(net1, net2))
#> Error in as.vector(y): argument "y" is missing, with no default
do.call(igraph::union, list(net1, net2))
#> IGRAPH d978a03 UN-- 13 21 --
#> + attr: name (v/c)
#> + edges from d978a03 (vertex names):
#> [1] I--J H--Z H--I G--H G--E F--X F--Y F--H F--C F--G B--E B--G A--X A--C A--F
#> [16] A--B D--Y D--G D--F D--B D--A
# no dynamic dots thing
igraph::union(!!!list(net1, net2))
#> Error in !list(net1, net2): invalid argument type
Created on 2024-02-26 with reprex v2.1.0
I'm not sure the current behavior of igraph::union(list(net1, net2))
not working is bad, but should we make igraph::union(!!!list(net1, net2))
work, is it at all possible.
We can always use rlang::inject()
:
options(conflicts.policy = list(warn = FALSE))
library("igraph")
net1 <- graph_from_literal(
D - A:B:F:G, A - C - F - A, B - E - G - B, A - B,
F - G, H - F:G, H - I - J
)
net2 <- graph_from_literal(D - A:F:Y, B - A - X - F - H - Z, F - Y)
# no dynamic dots thing
igraph::union(!!!list(net1, net2))
#> Error in !list(net1, net2): invalid argument type
# we always can work around with rlang::inject()
rlang::inject(igraph::union(!!!list(net1, net2)))
#> IGRAPH 18dad17 UN-- 13 21 --
#> + attr: name (v/c)
#> + edges from 18dad17 (vertex names):
#> [1] I--J H--Z H--I G--H G--E F--X F--Y F--H F--C F--G B--E B--G A--X A--C A--F
#> [16] A--B D--Y D--G D--F D--B D--A
Created on 2024-03-12 with reprex v2.1.0
On the other hand:
union(1, 2, 3)
#> Error in union(1, 2, 3): unused argument (3)
options(conflicts.policy = list(warn = FALSE))
library(dplyr)
union(tibble(a = 1), tibble(a = 2), tibble(a = 3))
#> Error in `union()`:
#> ! `...` must be empty.
#> ✖ Problematic argument:
#> • ..1 = tibble(a = 3)
#> ℹ Did you forget to name an argument?
Created on 2024-03-12 with reprex v2.1.0
Propose to drop support for the 3rd, 4th, ... argument, with a lifecycle warning?
Consistency vs. innovation. A hard choice. 🤷