intergraph
intergraph copied to clipboard
bipartite
Moving https://github.com/statnet/network/issues/21#issuecomment-693513311 over here...
@mbojan, friendly FYI: converting bipartite objects should now be simpler to implement.
southern_women_affil_mat <- structure(
c(1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0,
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1,
1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0),
.Dim = c(14L, 18L),
.Dimnames = list(
sprintf("e%d", 1:14),
c("Evelyn", "Laura", "Theresa", "Brenda", "Charlotte", "Frances", "Eleanor", "Pearl",
"Ruth", "Verne", "Myrna", "Katherine", "Sylvia", "Nora", "Helen", "Dorothy",
"Olivia", "Flora")
)
)
ig <- igraph::graph_from_incidence_matrix(southern_women_affil_mat)
ig_coords <- igraph::layout_with_graphopt(ig, niter = 5000)
igraph::vertex_attr(ig, "x") <- ig_coords[, 1L]
igraph::vertex_attr(ig, "y") <- ig_coords[, 2L]
igraph::vertex_attr(ig, "color") <- ifelse(igraph::vertex_attr(ig, "type"),
"salmon", "lightblue")
ig
#> IGRAPH daed723 UN-B 32 89 --
#> + attr: type (v/l), name (v/c), x (v/n), y (v/n), color (v/c)
#> + edges from daed723 (vertex names):
#> [1] e1--Evelyn e1--Laura e1--Brenda e2--Evelyn e2--Laura
#> [6] e2--Theresa e3--Evelyn e3--Laura e3--Theresa e3--Brenda
#> [11] e3--Charlotte e3--Frances e4--Evelyn e4--Theresa e4--Brenda
#> [16] e4--Charlotte e5--Evelyn e5--Laura e5--Theresa e5--Brenda
#> [21] e5--Charlotte e5--Frances e5--Eleanor e5--Ruth e6--Evelyn
#> [26] e6--Laura e6--Theresa e6--Brenda e6--Frances e6--Eleanor
#> [31] e6--Pearl e6--Nora e7--Laura e7--Theresa e7--Brenda
#> [36] e7--Charlotte e7--Eleanor e7--Ruth e7--Verne e7--Sylvia
#> + ... omitted several edges
intergraph::asNetwork(ig)
#> Network attributes:
#> vertices = 32
#> directed = FALSE
#> hyper = FALSE
#> loops = FALSE
#> multiple = FALSE
#> bipartite = FALSE
#> total edges= 89
#> missing edges= 0
#> non-missing edges= 89
#>
#> Vertex attribute names:
#> color type vertex.names x y
#>
#> No edge attributes
asNetwork2 <- function(ig) {
proto_net <- igraph::as_data_frame(ig, what = "both")
if (!igraph::is_named(ig)) {
proto_net$vertices$name <- as.double(seq_len(igraph::vcount(ig)))
}
col_order <- c("name", setdiff(names(proto_net$vertices), "name"))
proto_net$vertices <- proto_net$vertices[col_order]
network::as.network(
x = proto_net$edges,
directed = igraph::is_directed(ig),
vertices = proto_net$vertices,
hyper = FALSE,
loops = any(igraph::which_loop(ig)),
multiple = igraph::any_multiple(ig),
bipartite = igraph::is_bipartite(ig),
bipartite_col = "type"
)
}
nw <- asNetwork2(ig)
#> Warning: `vertices` were not provided in the order required for bipartite networks. Reordering.
#>
#> This is the first and last time you will be warned during this session.
nw
#> Network attributes:
#> vertices = 32
#> directed = FALSE
#> hyper = FALSE
#> loops = FALSE
#> multiple = FALSE
#> bipartite = 14
#> total edges= 89
#> missing edges= 0
#> non-missing edges= 89
#>
#> Vertex attribute names:
#> color type vertex.names x y
#>
#> No edge attributes
network::is.bipartite(nw)
#> [1] TRUE
nw_coords <- cbind(
network::get.vertex.attribute(nw, "x"),
network::get.vertex.attribute(nw, "y")
)
plot(ig, vertex.label.cex = 0.65, vertex.size = 15, main = "igraph")

plot(nw,
vertex.col = network::get.vertex.attribute(nw, "color"),
label = network::network.vertex.names(nw),
coord = nw_coords,
vertex.cex = 4,
label.cex = 0.6, label.pos = 5,
edge.col = "lightgray",
pad = 0,
main = "network")

ig2 <- igraph::graph_from_data_frame(
d = network::as.data.frame.network(nw, unit = "edges"),
directed = network::is.directed(nw),
vertices = network::as.data.frame.network(nw, unit = "vertices")
)
ig2
#> IGRAPH 7f421d7 UN-B 32 89 --
#> + attr: name (v/c), type (v/l), x (v/n), y (v/n), color (v/c)
#> + edges from 7f421d7 (vertex names):
#> [1] Evelyn --e1 Laura --e1 Brenda --e1 Evelyn --e2 Laura --e2
#> [6] Theresa --e2 Evelyn --e3 Laura --e3 Theresa --e3 Brenda --e3
#> [11] Charlotte--e3 Frances --e3 Evelyn --e4 Theresa --e4 Brenda --e4
#> [16] Charlotte--e4 Evelyn --e5 Laura --e5 Theresa --e5 Brenda --e5
#> [21] Charlotte--e5 Frances --e5 Eleanor --e5 Ruth --e5 Evelyn --e6
#> [26] Laura --e6 Theresa --e6 Brenda --e6 Frances --e6 Eleanor --e6
#> [31] Pearl --e6 Nora --e6 Laura --e7 Theresa --e7 Brenda --e7
#> [36] Charlotte--e7 Eleanor --e7 Ruth --e7 Verne --e7 Sylvia --e7
#> + ... omitted several edges
igraph::is_bipartite(ig2)
#> [1] TRUE
plot(ig2, vertex.label.cex = 0.65, vertex.size = 15, main = "round-trip igraph")

The package need some review but I'd love some input/PR on this once I get to that.
I'm happy to help. I can't promise I'll get to a PR too soon, but I'll make sure I can provide any feedback or input I can.
Thanks @knapply
Suggestion: wait until the next version of {network} is actually released before using as.data.frame.network() here as It seems things could shift dramatically over there.
Indeed. I keep my finger on the pulse. Thanks.