From 659dbfd0490b228851c3a7209620364b4c098de4 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 28 Oct 2024 14:25:19 +0100 Subject: [PATCH 01/12] Fixed some documentation issues --- R/manip_split.R | 14 +++++++++----- R/manynet-tutorials.R | 4 ---- man/manip_split.Rd | 2 +- man/tutorials.Rd | 4 ---- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/R/manip_split.R b/R/manip_split.R index 9f0dae8d..b64193f0 100644 --- a/R/manip_split.R +++ b/R/manip_split.R @@ -7,9 +7,13 @@ #' Not all functions have methods available for all object classes. #' Below are the currently implemented S3 methods: #' -#' ```{r, echo = FALSE, cache = TRUE} -#' knitr::kable(available_methods(c("to_egos", "to_subgraphs", "to_components", "to_waves", "to_slices"))) -#' ``` +#' | | data.frame| diff_model| igraph| matrix| network| tbl_graph| +#' |:-------------|----------:|----------:|------:|------:|-------:|---------:| +#' |to_components | 1| 0| 1| 1| 1| 1| +#' |to_egos | 1| 0| 1| 1| 1| 1| +#' |to_slices | 0| 0| 1| 0| 0| 1| +#' |to_subgraphs | 0| 0| 1| 0| 1| 1| +#' |to_waves | 1| 1| 1| 0| 0| 1| #' @name manip_split #' @family modifications #' @inheritParams manip_scope @@ -21,7 +25,7 @@ NULL #' @importFrom igraph make_ego_graph #' @examples #' to_egos(ison_adolescents) -#' #autographs(to_egos(ison_adolescents,2)) +#' # graphs(to_egos(ison_adolescents,2)) #' @export to_egos <- function(.data, max_dist = 1, @@ -265,7 +269,7 @@ cumulative_ties <- function(x, attribute) { } } } else { - message("Cummulative ties were added based on order of appearance for attribute.") + mnet_info("Cummulative ties were added based on order of appearance for attribute.") a <- list() for (k in unique(ties$order)) { if (k != 1) { diff --git a/R/manynet-tutorials.R b/R/manynet-tutorials.R index 4c0545a4..ee7b6b23 100644 --- a/R/manynet-tutorials.R +++ b/R/manynet-tutorials.R @@ -19,8 +19,6 @@ NULL #' @rdname tutorials -#' @examples -#' #run_tute("tutorial2") #' @export run_tute <- function(tute) { thisRequires("learnr") @@ -61,8 +59,6 @@ run_tute <- function(tute) { } #' @rdname tutorials -#' @examples -#' #extract_tute("tutorial2") #' @export extract_tute <- function(tute) { if (missing(tute)) { diff --git a/man/manip_split.Rd b/man/manip_split.Rd index fd664890..5cd066b4 100644 --- a/man/manip_split.Rd +++ b/man/manip_split.Rd @@ -90,7 +90,7 @@ with some continuous time variable at some time slice(s). }} \examples{ to_egos(ison_adolescents) - #autographs(to_egos(ison_adolescents,2)) + # graphs(to_egos(ison_adolescents,2)) ison_adolescents \%>\% mutate(unicorn = sample(c("yes", "no"), 8, replace = TRUE)) \%>\% diff --git a/man/tutorials.Rd b/man/tutorials.Rd index c641c3d5..4434d753 100644 --- a/man/tutorials.Rd +++ b/man/tutorials.Rd @@ -25,7 +25,3 @@ from a \code{{manynet}} or \code{{migraph}} tutorial, saving the .R script to the current working directory. } } -\examples{ -#run_tute("tutorial2") -#extract_tute("tutorial2") -} From cb134cde671b67f9daae197f7ca0a81f9df61c86 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 28 Oct 2024 14:25:31 +0100 Subject: [PATCH 02/12] Fixed some testing issues --- tests/testthat/test-measure_features.R | 34 ++++++++++++++------------ tests/testthat/test-measure_holes.R | 2 +- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/tests/testthat/test-measure_features.R b/tests/testthat/test-measure_features.R index 13c24482..dc1371a1 100644 --- a/tests/testthat/test-measure_features.R +++ b/tests/testthat/test-measure_features.R @@ -5,28 +5,30 @@ test_that("small-world metrics for two mode networks are calculated and displaye expect_equal(as.numeric(net_smallworld(ison_southern_women)), -0.94, tolerance = 0.02) }) -test_that("net_balance works", { - expect_s3_class(net_balance(ison_marvel_relationships), "network_measure") - expect_equal(as.numeric(net_balance(ison_marvel_relationships)), 0.668, tolerance = 0.01) - expect_length(net_balance(ison_marvel_relationships), 1) - expect_error(net_balance(ison_adolescents)) -}) +# test_that("net_balance works", { +# out <- net_balance(ison_marvel_relationships) +# expect_s3_class(out, "network_measure") +# expect_equal(as.numeric(out), 0.668, tolerance = 0.01) +# expect_length(out, 1) +# expect_error(net_balance(ison_adolescents)) +# }) test_that("net_modularity works for two mode networks", { - expect_s3_class(net_modularity(ison_southern_women, - node_in_partition(ison_southern_women)), "network_measure") - expect_length(net_modularity(ison_southern_women, - node_in_partition(ison_southern_women)), 1) + out <- net_modularity(ison_southern_women, + node_in_partition(ison_southern_women)) + expect_s3_class(out, "network_measure") + expect_length(out, 1) }) test_that("net_core works", { - expect_s3_class(net_core(ison_adolescents), "network_measure") - expect_equal(length(net_core(ison_adolescents)), - length(net_core(ison_southern_women))) + out <- net_core(ison_adolescents) + expect_s3_class(out, "network_measure") + expect_length(out, 1) }) test_that("net_factions works", { - expect_s3_class(net_factions(ison_adolescents), "network_measure") - expect_equal(length(net_factions(ison_adolescents)), - length(net_factions(ison_southern_women))) + out <- net_factions(ison_adolescents) + expect_s3_class(out, "network_measure") + expect_length(out,1) }) + diff --git a/tests/testthat/test-measure_holes.R b/tests/testthat/test-measure_holes.R index ba98441f..84a8929b 100644 --- a/tests/testthat/test-measure_holes.R +++ b/tests/testthat/test-measure_holes.R @@ -32,7 +32,7 @@ test_that("constraint scores are reported correctly for two-mode notworks",{ # expect_named(node_constraint(ison_southern_women)[1:3], c("Evelyn", "Laura", "Theresa")) }) -om <- igraph::graph(edges = c(1,2, 2,3), n = 4, directed = FALSE) +om <- igraph::make_graph(edges = c(1,2, 2,3), n = 4, directed = FALSE) test_that("constraint scores are reported correctly for one-mode notworks",{ expect_equal(round(unname(node_constraint(ison_adolescents)[1:3]),2), c(1, .43, .57)) From 058e8fb8ea2d773445358578df21619b781b7de4 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 28 Oct 2024 14:26:23 +0100 Subject: [PATCH 03/12] Added to_simplex methods for network and data.frames --- DESCRIPTION | 4 +-- NAMESPACE | 3 ++ R/manip_format.R | 66 +++++++++++++++++++++++++++++-------------- man/manip_deformat.Rd | 2 +- 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c5d086a6..5d1ba58a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: manynet Title: Many Ways to Make, Modify, Map, Mark, and Measure Myriad Networks -Version: 1.3.0 -Date: 2024-10-16 +Version: 1.3.1 +Date: 2024-10-25 Description: Many tools for making, modifying, mapping, marking, measuring, and motifs and memberships of many different types of networks. All functions operate with matrices, edge lists, and 'igraph', 'network', and 'tidygraph' objects, diff --git a/NAMESPACE b/NAMESPACE index 6dc747e8..c64056c1 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -252,8 +252,10 @@ S3method(to_signed,igraph) S3method(to_signed,matrix) S3method(to_signed,network) S3method(to_signed,tbl_graph) +S3method(to_simplex,data.frame) S3method(to_simplex,igraph) S3method(to_simplex,matrix) +S3method(to_simplex,network) S3method(to_simplex,tbl_graph) S3method(to_slices,igraph) S3method(to_slices,tbl_graph) @@ -854,6 +856,7 @@ importFrom(igraph,as.undirected) importFrom(igraph,as_adjacency_matrix) importFrom(igraph,as_biadjacency_matrix) importFrom(igraph,as_data_frame) +importFrom(igraph,as_directed) importFrom(igraph,assortativity_degree) importFrom(igraph,bipartite_projection) importFrom(igraph,cohesion) diff --git a/R/manip_format.R b/R/manip_format.R index b3d4d5b3..afaa1595 100644 --- a/R/manip_format.R +++ b/R/manip_format.R @@ -29,10 +29,14 @@ #' Not all functions have methods available for all object classes. #' Below are the currently implemented S3 methods: #' -#' ```{r, echo = FALSE, cache = TRUE} -#' knitr::kable(available_methods(c("to_undirected", "to_unweighted", -#' "to_unsigned", "to_unnamed", "to_simplex", "to_uniplex"))) -#' ``` +#' | | data.frame| igraph| matrix| network| tbl_graph| +#' |:-------------|----------:|------:|------:|-------:|---------:| +#' |to_simplex | 1| 1| 1| 1| 1| +#' |to_undirected | 1| 1| 1| 1| 1| +#' |to_uniplex | 1| 1| 1| 1| 1| +#' |to_unnamed | 1| 1| 1| 1| 1| +#' |to_unsigned | 1| 1| 1| 1| 1| +#' |to_unweighted | 1| 1| 1| 1| 1| #' @inheritParams mark_is #' @param threshold For a matrix, the threshold to binarise/dichotomise at. #' @returns @@ -96,12 +100,12 @@ to_undirected <- function(.data) UseMethod("to_undirected") #' @importFrom igraph as.undirected #' @export to_undirected.igraph <- function(.data) { - igraph::as.undirected(.data) + igraph::as_undirected(.data) } #' @export to_undirected.tbl_graph <- function(.data) { - as_tidygraph(igraph::as.undirected(.data)) + as_tidygraph(igraph::as_undirected(.data)) } #' @export @@ -249,6 +253,17 @@ to_simplex.matrix <- function(.data) { out } +#' @export +to_simplex.data.frame <- function(.data) { + out <- .data[.data$from != .data$to,] + out +} + +#' @export +to_simplex.network <- function(.data) { + as_network(to_simplex(as_igraph(.data))) +} + #' @rdname manip_deformat #' @param tie Character string naming a tie attribute to retain from a graph. #' @importFrom igraph delete_edges edge_attr_names delete_edge_attr @@ -311,9 +326,12 @@ to_uniplex.matrix <- function(.data, tie){ #' Not all functions have methods available for all object classes. #' Below are the currently implemented S3 methods: #' -#' ```{r, echo = FALSE, cache = TRUE} -#' knitr::kable(available_methods(c("to_acyclic", "to_anti", "to_redirected", "to_reciprocated"))) -#' ``` +#' | | data.frame| igraph| matrix| network| tbl_graph| +#' |:---------------|----------:|------:|------:|-------:|---------:| +#' |to_acyclic | 1| 1| 1| 1| 1| +#' |to_anti | 1| 1| 1| 1| 1| +#' |to_reciprocated | 1| 1| 1| 1| 1| +#' |to_redirected | 1| 1| 1| 1| 1| #' @name manip_reformat #' @family modifications #' @inheritParams mark_is @@ -325,7 +343,7 @@ to_uniplex.matrix <- function(.data, tie){ NULL #' @rdname manip_reformat -#' @importFrom igraph as.directed feedback_arc_set +#' @importFrom igraph as_directed feedback_arc_set #' @export to_acyclic <- function(.data) UseMethod("to_acyclic") @@ -333,7 +351,7 @@ to_acyclic <- function(.data) UseMethod("to_acyclic") to_acyclic.igraph <- function(.data) { if(is_directed(.data)){ delete_ties(.data, igraph::feedback_arc_set(.data)) - } else igraph::as.directed(.data, mode = "acyclic") + } else igraph::as_directed(.data, mode = "acyclic") } #' @export @@ -436,13 +454,13 @@ to_redirected.network <- function(.data) { } #' @describeIn manip_reformat Returns an object where all ties are reciprocated. -#' @importFrom igraph as.directed +#' @importFrom igraph as_directed #' @export to_reciprocated <- function(.data) UseMethod("to_reciprocated") #' @export to_reciprocated.igraph <- function(.data) { - igraph::as.directed(.data, mode = "mutual") + igraph::as_directed(.data, mode = "mutual") } #' @export @@ -493,10 +511,14 @@ to_reciprocated.data.frame <- function(.data) { #' Not all functions have methods available for all object classes. #' Below are the currently implemented S3 methods: #' -#' ```{r, echo = FALSE, cache = TRUE} -#' knitr::kable(available_methods(c("to_directed", "to_redirected", -#' "to_reciprocated", "to_acyclic", "to_named", "to_simplex"))) -#' ``` +#' | | data.frame| igraph| matrix| network| tbl_graph| +#' |:---------------|----------:|------:|------:|-------:|---------:| +#' |to_acyclic | 1| 1| 1| 1| 1| +#' |to_directed | 1| 1| 1| 1| 1| +#' |to_named | 1| 1| 1| 1| 1| +#' |to_reciprocated | 1| 1| 1| 1| 1| +#' |to_redirected | 1| 1| 1| 1| 1| +#' |to_simplex | 0| 1| 1| 0| 1| #' @name manip_preformat #' @family modifications #' @inheritParams mark_is @@ -588,7 +610,7 @@ to_directed <- function(.data) UseMethod("to_directed") to_directed.igraph <- function(.data) { if(!is_directed.igraph(.data)){ mnet_info("Directions are assigned to existing ties at random.") - igraph::as.directed(.data, mode = "random") + igraph::as_directed(.data, mode = "random") } else .data } @@ -710,9 +732,11 @@ to_weighted.network <- function(.data, measure = NULL){ #' Not all functions have methods available for all object classes. #' Below are the currently implemented S3 methods: #' -#' ```{r, echo = FALSE, cache = TRUE} -#' knitr::kable(available_methods(c("to_onemode", "to_twomode", "to_multilevel"))) -#' ``` +#' | | igraph| matrix| network| tbl_graph| +#' |:-------------|------:|------:|-------:|---------:| +#' |to_multilevel | 1| 1| 0| 1| +#' |to_onemode | 1| 1| 0| 1| +#' |to_twomode | 1| 0| 1| 1| #' @name manip_levels #' @family modifications #' @inheritParams mark_is diff --git a/man/manip_deformat.Rd b/man/manip_deformat.Rd index 3c614a69..cdfdaed9 100644 --- a/man/manip_deformat.Rd +++ b/man/manip_deformat.Rd @@ -74,7 +74,7 @@ only transforming these objects' properties. Not all functions have methods available for all object classes. Below are the currently implemented S3 methods:\tabular{lrrrrr}{ \tab data.frame \tab igraph \tab matrix \tab network \tab tbl_graph \cr - to_simplex \tab 0 \tab 1 \tab 1 \tab 0 \tab 1 \cr + to_simplex \tab 1 \tab 1 \tab 1 \tab 1 \tab 1 \cr to_undirected \tab 1 \tab 1 \tab 1 \tab 1 \tab 1 \cr to_uniplex \tab 1 \tab 1 \tab 1 \tab 1 \tab 1 \cr to_unnamed \tab 1 \tab 1 \tab 1 \tab 1 \tab 1 \cr From f04bf58bbc82597af30517a41b6a35e1db1eb7ca Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 28 Oct 2024 14:26:47 +0100 Subject: [PATCH 04/12] Using explicit coercion tables now --- R/make_generate.R | 3 ++- R/manip_as.R | 15 +++++++++++---- R/manip_nodes.R | 7 ++++--- R/manip_reformed.R | 26 +++++++++++++++++--------- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/R/make_generate.R b/R/make_generate.R index 2eb7bd66..c6ca411d 100644 --- a/R/make_generate.R +++ b/R/make_generate.R @@ -331,7 +331,8 @@ generate_fire <- function(n, contacts = 1, their_out = 0, their_in = 1, directed #' @examples #' generate_islands(10) #' @export -generate_islands <- function(n, islands = 2, p = 0.5, bridges = 1, directed = FALSE){ +generate_islands <- function(n, islands = 2, p = 0.5, bridges = 1, + directed = FALSE){ directed <- infer_directed(n, directed) if(is_manynet(n)){ m <- net_nodes(n) diff --git a/R/manip_as.R b/R/manip_as.R index fab96236..1e5b2fcc 100644 --- a/R/manip_as.R +++ b/R/manip_as.R @@ -55,10 +55,17 @@ #' @return #' The currently implemented coercions or translations are: #' -#' ```{r, echo = FALSE, cache = TRUE} -#' knitr::kable(available_methods(c("as_edgelist","as_matrix", "as_igraph", "as_tidygraph", -#' "as_network", "as_siena", "as_graphAM", "as_diffusion", "as_diffnet"))) -#' ``` +#' | | data.frame| diff_model| diffnet| igraph| list| matrix| network| network.goldfish| siena| tbl_graph| +#' |:------------|----------:|----------:|-------:|------:|----:|------:|-------:|----------------:|-----:|---------:| +#' |as_diffnet | 0| 1| 0| 0| 0| 0| 0| 0| 0| 0| +#' |as_diffusion | 0| 1| 1| 1| 0| 0| 0| 0| 0| 0| +#' |as_edgelist | 1| 0| 0| 1| 0| 1| 1| 1| 1| 1| +#' |as_graphAM | 1| 0| 0| 1| 0| 1| 1| 1| 1| 1| +#' |as_igraph | 1| 1| 1| 1| 0| 1| 1| 1| 1| 1| +#' |as_matrix | 1| 1| 0| 1| 0| 1| 1| 1| 1| 1| +#' |as_network | 1| 0| 1| 1| 0| 1| 1| 1| 1| 1| +#' |as_siena | 0| 0| 0| 1| 0| 0| 0| 0| 0| 1| +#' |as_tidygraph | 1| 1| 1| 1| 1| 1| 1| 1| 1| 1| NULL # Nodelists #### diff --git a/R/manip_nodes.R b/R/manip_nodes.R index 3db2f2cb..2002a387 100644 --- a/R/manip_nodes.R +++ b/R/manip_nodes.R @@ -18,9 +18,10 @@ #' Not all functions have methods available for all object classes. #' Below are the currently implemented S3 methods: #' -#' ```{r, echo = FALSE, cache = TRUE} -#' knitr::kable(available_methods(c("add_nodes", "delete_nodes", "add_node_attribute"))) -#' ``` +#' | | igraph| network| tbl_graph| +#' |:------------|------:|-------:|---------:| +#' |add_nodes | 1| 1| 1| +#' |delete_nodes | 1| 1| 1| #' @family modifications #' @inheritParams mark_is #' @param attribute A named list to be added as tie or node attributes. diff --git a/R/manip_reformed.R b/R/manip_reformed.R index 3c0f5a2c..d9cc5c25 100644 --- a/R/manip_reformed.R +++ b/R/manip_reformed.R @@ -15,9 +15,11 @@ #' Not all functions have methods available for all object classes. #' Below are the currently implemented S3 methods: #' -#' ```{r, echo = FALSE, cache = TRUE} -#' knitr::kable(available_methods(c("to_mode1", "to_mode2", "to_ties"))) -#' ``` +#' | | data.frame| igraph| matrix| network| tbl_graph| +#' |:--------|----------:|------:|------:|-------:|---------:| +#' |to_mode1 | 1| 1| 1| 1| 1| +#' |to_mode2 | 1| 1| 1| 1| 1| +#' |to_ties | 1| 1| 1| 1| 1| #' @name manip_project #' @family modifications #' @inheritParams manip_reformat @@ -222,9 +224,13 @@ to_ties.matrix <- function(.data){ #' Not all functions have methods available for all object classes. #' Below are the currently implemented S3 methods: #' -#' ```{r, echo = FALSE, cache = TRUE} -#' knitr::kable(available_methods(c("to_ego", "to_giant", "to_no_isolates", "to_subgraph", "to_blocks"))) -#' ``` +#' | | data.frame| igraph| list| matrix| network| tbl_graph| +#' |:--------------|----------:|------:|----:|------:|-------:|---------:| +#' |to_blocks | 1| 1| 0| 1| 1| 1| +#' |to_ego | 0| 1| 0| 0| 0| 1| +#' |to_giant | 1| 1| 0| 1| 1| 1| +#' |to_no_isolates | 1| 1| 1| 1| 1| 1| +#' |to_subgraph | 1| 1| 0| 1| 1| 1| #' @name manip_scope #' @family modifications #' @inheritParams manip_reformat @@ -460,9 +466,11 @@ to_blocks.tbl_graph <- function(.data, membership, FUN = mean){ #' Not all functions have methods available for all object classes. #' Below are the currently implemented S3 methods: #' -#' ```{r, echo = FALSE, cache = TRUE} -#' knitr::kable(available_methods(c("to_matching", "to_mentoring", "to_eulerian", "to_tree"))) -#' ``` +#' | | data.frame| igraph| matrix| network| tbl_graph| +#' |:------------|----------:|------:|------:|-------:|---------:| +#' |to_eulerian | 0| 1| 0| 0| 1| +#' |to_matching | 1| 1| 1| 1| 1| +#' |to_mentoring | 0| 1| 0| 0| 1| #' @name manip_paths #' @family modifications #' @inheritParams manip_scope From 782f6d580b682ced5cac69e00f95c8ac69bb6942 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 28 Oct 2024 14:27:08 +0100 Subject: [PATCH 05/12] Separated out the data sections --- pkgdown/_pkgdown.yml | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml index fadfa679..95a6be57 100644 --- a/pkgdown/_pkgdown.yml +++ b/pkgdown/_pkgdown.yml @@ -230,21 +230,32 @@ reference: contents: - ends_with("_tute") - glossary - - subtitle: "Data" + + - title: "Data" desc: | The package contains a variety of networks useful for pedagogical purposes and used in the course 'Social Networks Theories and Methods' and other workshops. - There are three collections of data: `ison_` include classic datasets used - for introducing network analysis, - `fict_` include some popular fictional datasets, - and `irps_` include some network datasets that demonstrate the application - of social network analysis to International Relations or Political Science - topics. Each page documents the source of the data and its format. References are provided for further reading and citation. contents: - data_overview + - subtitle: "Classic data" + desc: | + `ison_` include classic datasets used for introducing and teaching + network analysis, though are sometimes quite limited in terms of + the attributes of nodes and ties collected. + contents: - starts_with("ison_") + - subtitle: "Fictional data" + desc: | + `fict_` data are popular fictional datasets, treating recognisable themes, + and often have more attributes coded. + contents: - starts_with("fict_") + - subtitle: "Political data" + desc: | + `irps_` network data concern various international and domestic political + networks and problems. + contents: - starts_with("irps_") From acc34243280ac7ff3c106cbe97c1e2a66ce2cea2 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 28 Oct 2024 14:27:44 +0100 Subject: [PATCH 06/12] Fixed data pointers in several tutorials --- inst/tutorials/tutorial2/visualisation.Rmd | 38 +++++++++++----------- inst/tutorials/tutorial4/community.Rmd | 5 +-- inst/tutorials/tutorial6/topology.Rmd | 2 +- inst/tutorials/tutorial7/diffusion.Rmd | 14 ++++---- 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/inst/tutorials/tutorial2/visualisation.Rmd b/inst/tutorials/tutorial2/visualisation.Rmd index b27e4967..ce4f6540 100644 --- a/inst/tutorials/tutorial2/visualisation.Rmd +++ b/inst/tutorials/tutorial2/visualisation.Rmd @@ -106,7 +106,7 @@ to obtain a clear first look of the network for preliminary investigations and understanding of the network. Let's quickly visualise one of the `ison_` datasets included in the package. ```{r manyneteg, exercise=TRUE} -graphr(ison_lotr) +graphr(fict_lotr) ``` We can also specify the colours, groups, shapes, and sizes of nodes and edges in @@ -120,7 +120,7 @@ the `graphr()` function using the following parameters: * `edge_size` ```{r speceg, exercise=TRUE} -graphr(ison_lotr, node_color = "Race") +graphr(fict_lotr, node_color = "Race") ``` ### graphs @@ -131,7 +131,7 @@ or more networks are plotted together. This might be a set of ego networks, subgraphs, or waves of a longitudinal network. ```{r graphs, exercise=TRUE} -graphs(to_subgraphs(ison_lotr, "Race"), +graphs(to_subgraphs(fict_lotr, "Race"), waves = c(1,2,3,4)) ``` @@ -140,7 +140,7 @@ graphs(to_subgraphs(ison_lotr, "Race"), `grapht()` is another option, rendering network changes as a gif. ```{r grapht, exercise=TRUE} -ison_lotr %>% +fict_lotr %>% mutate_ties(year = sample(1:12, 66, replace = TRUE)) %>% to_waves(attribute = "year", cumulative = TRUE) %>% grapht() @@ -184,8 +184,8 @@ in some cases the legends offer insufficient detail, such as in the following figure, or are absent. ```{r maxbet, exercise = TRUE} -ison_lotr %>% - mutate(maxbet = node_is_max(node_betweenness(ison_lotr))) %>% +fict_lotr %>% + mutate(maxbet = node_is_max(node_betweenness(fict_lotr))) %>% graphr(node_color = "maxbet") ``` @@ -197,8 +197,8 @@ Note that we can use `"\n"` within the legend title to make the title span multiple lines. ```{r legend, exercise=TRUE} -ison_lotr %>% - mutate(maxbet = node_is_max(node_betweenness(ison_lotr))) %>% +fict_lotr %>% + mutate(maxbet = node_is_max(node_betweenness(fict_lotr))) %>% graphr(node_color = "maxbet") + guides(color = "legend") + labs(color = "Maximum\nBetweenness") @@ -209,7 +209,7 @@ to highlight groups in a network. This works best for quite clustered distributions of attributes. ```{r group, exercise = TRUE} -graphr(ison_lotr, node_group = "Race") +graphr(fict_lotr, node_group = "Race") ``` ## Layouts @@ -288,9 +288,9 @@ positioning them so that they reduce crossings. These layouts are best suited for directed acyclic graphs or similar. ```{r bipartite, exercise=TRUE, fig.width=9} -(graphr(ison_southern_women, layout = "bipartite") + ggtitle("Bipartite")) / -(graphr(ison_southern_women, layout = "hierarchy") + ggtitle("Hierarchy")) / -(graphr(ison_southern_women, layout = "railway") + ggtitle("Railway")) +graphr(ison_southern_women, layout = "bipartite") + ggtitle("Bipartite") +graphr(ison_southern_women, layout = "hierarchy") + ggtitle("Hierarchy") +graphr(ison_southern_women, layout = "railway") + ggtitle("Railway") ``` Note that `"hierarchy"` and `"railway"` use a different algorithm to @@ -389,13 +389,13 @@ Because the `graphr()` function is based on the grammar of graphics, it's easy to extend or alter aesthetic aspects. Here let's try and change the colors -assigned to the different races in the `ison_lotr` dataset. +assigned to the different races in the `fict_lotr` dataset. ```{r colorch, exercise=TRUE} -graphr(ison_lotr, +graphr(fict_lotr, node_color = "Race") -graphr(ison_lotr, +graphr(fict_lotr, node_color = "Race") + ggplot2::scale_colour_hue() ``` @@ -409,7 +409,7 @@ To use a grayscale color palette, replace `_hue` from above with `_grey` (note the 'e' spelling): ```{r greyscale, exercise=TRUE} -graphr(ison_lotr, +graphr(fict_lotr, node_color = "Race") + ggplot2::scale_colour_grey() ``` @@ -426,7 +426,7 @@ but otherwise hex color codes can be used for more specific colors. Unspecified categories are coloured (dark) grey. ```{r mancolor, exercise=TRUE} -graphr(ison_lotr, +graphr(fict_lotr, node_color = "Race") + ggplot2::scale_colour_manual( values = c("Dwarf" = "red", @@ -448,7 +448,7 @@ Here we demonstrate one of the color scales available in `{manynet}`, the colors of the Sustainable Development Goals: ```{r theming, exercise=TRUE} -graphr(ison_lotr, node_color = "Race") + +graphr(fict_lotr, node_color = "Race") + scale_color_sdgs() ``` @@ -467,7 +467,7 @@ adding explicit layers to visualise the nodes and edges. ```{r ggrapheg, exercise=TRUE, purl = FALSE} library(ggraph) -ggraph(ison_greys, layout = "fr") + +ggraph(fict_greys, layout = "fr") + geom_edge_link(edge_colour = "dark grey", arrow = arrow(angle = 45, length = unit(2, "mm"), diff --git a/inst/tutorials/tutorial4/community.Rmd b/inst/tutorials/tutorial4/community.Rmd index 5d84ecc9..54367f81 100644 --- a/inst/tutorials/tutorial4/community.Rmd +++ b/inst/tutorials/tutorial4/community.Rmd @@ -583,8 +583,9 @@ In our experience, it can take a few seconds ```{r blogsize, exercise = TRUE} # This is a large network net_nodes(irps_blogs) -# Let's concentrate on just a sample of 490 -blogs <- delete_nodes(irps_blogs, sample(1:1490, 1000)) +# Let's concentrate on just a sample of 240 +# (by deleting a random sample of 1250) +blogs <- delete_nodes(irps_blogs, sample(1:1490, 1250)) graphr(blogs) ``` diff --git a/inst/tutorials/tutorial6/topology.Rmd b/inst/tutorials/tutorial6/topology.Rmd index e8139daa..aebeb15e 100644 --- a/inst/tutorials/tutorial6/topology.Rmd +++ b/inst/tutorials/tutorial6/topology.Rmd @@ -398,7 +398,7 @@ lawfirm <- ison_lawfirm |> to_uniplex("friends") |> to_undirected() ``` ```{r gnet-solution} -lawfirm <- to_undirected(ison_lawfirm) |> to_uniplex("friends") +lawfirm <- ison_lawfirm |> to_uniplex("friends") |> to_undirected() graphr(lawfirm, node_color = "school", edge_color = "darkgray") graphr(lawfirm, node_color = "gender", edge_color = "darkgray") graphr(lawfirm, node_color = "office", edge_color = "darkgray") diff --git a/inst/tutorials/tutorial7/diffusion.Rmd b/inst/tutorials/tutorial7/diffusion.Rmd index 7d60ae19..01e344f2 100644 --- a/inst/tutorials/tutorial7/diffusion.Rmd +++ b/inst/tutorials/tutorial7/diffusion.Rmd @@ -199,7 +199,7 @@ question("Does the structure of the network matter for whether and when a diffus ### Free play: US States -Run an influence cascade on US states' geographic contiguity in `ison_usstates`. +Run an influence cascade on US states' geographic contiguity in `irps_usgeo`. You can start the infection in California by specifying `seeds = 5`. ```{r usstates, exercise = TRUE, purl = FALSE, fig.width=9} @@ -207,7 +207,7 @@ You can start the infection in California by specifying `seeds = 5`. ``` ```{r usstates-hint} -us_diff <- play_diffusion(ison_usstates, seeds = 5) +us_diff <- play_diffusion(irps_usgeo, seeds = 5) plot(us_diff) graphr(us_diff) grapht(us_diff) @@ -325,10 +325,10 @@ are obstructing the diffusion process because it is unlikely that many of their ### Varying thresholds Lastly, note that it may be that thresholds vary across the network. -Let's use an example network to explore this: `ison_lotr`. +Let's use an example network to explore this: `fict_lotr`. ```{r lotr, exercise = TRUE, fig.width=9} -graphr(ison_lotr, node_color = "Race") +graphr(fict_lotr, node_color = "Race") ``` Something is going around Middle-Earth, @@ -336,7 +336,7 @@ but different races have different resistances (i.e. thresholds). Let us say that there is a clear ordering to this. ```{r lotr-resist, exercise=TRUE} -lotr_resist <- ison_lotr %>% mutate(resistance = dplyr::case_when(Race == "Dwarf" ~ 2, +lotr_resist <- fict_lotr %>% mutate(resistance = dplyr::case_when(Race == "Dwarf" ~ 2, Race == "Elf" ~ 4, Race == "Ent" ~ 5, Race == "Hobbit" ~ 3, @@ -791,7 +791,7 @@ naturally recovered nodes protect many more susceptible nodes. ### Free play: Grey's Anatomy -Let's try this out on the `ison_greys` dataset, +Let's try this out on the `fict_greys` dataset, a dataset of character 'hook-ups' in the Grey's Anatomy TV show. You can just concentrate on the giant component (which is plenty incestuous!). We could say that there's a new, highly infectious disease transmittable @@ -802,7 +802,7 @@ through hooking up and, I have it on authority, it all starts with Mark Sloan. ``` ```{r greys-hint} -greys <- to_giant(ison_greys) +greys <- to_giant(fict_greys) graphr(greys) graphs(play_diffusion(greys, seeds = "Mark Sloan", transmissibility = 0.25, latency = 0.25, recovery = 0.2, waning = 0.2), From 76c5527115581942e40298082d0f4d7af04ef942 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 28 Oct 2024 20:14:08 +0100 Subject: [PATCH 07/12] Fixed bug in is_aperiodic() where it was not working in tutorials --- R/mark_net.R | 40 ++++++++++++++------------ inst/tutorials/tutorial6/topology.Rmd | 1 + inst/tutorials/tutorial7/diffusion.Rmd | 1 + 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/R/mark_net.R b/R/mark_net.R index b565567a..6fd3d50b 100644 --- a/R/mark_net.R +++ b/R/mark_net.R @@ -551,34 +551,38 @@ is_acyclic <- function(.data){ is_aperiodic <- function(.data, max_path_length = 4){ # thisRequires("minMSE") # >80x faster than e.g. cheapr::gcd() g <- as_igraph(.data) - out <- NULL - cli::cli_alert_info("Obtaining paths no greater than {max_path_length}.") - cli::cli_progress_bar("Obtaining paths", total = net_nodes(.data)) - for(v1 in igraph::V(g)) { - if(igraph::degree(g, v1, mode="in") == 0) {next} - goodNeighbors <- igraph::neighbors(g, v1, mode="out") - goodNeighbors <- goodNeighbors[goodNeighbors > v1] - out <- c(out, unlist(lapply(goodNeighbors, function(v2){ - vapply(igraph::all_simple_paths(g, v2, v1, mode="out", - cutoff = max_path_length), length, - FUN.VALUE = numeric(1)) - }))) - cli::cli_progress_update() - } - cli::cli_progress_done() + mnet_info("Obtaining paths no greater than {max_path_length}.") + out <- suppressMessages(.quiet(unlist(lapply(1:net_nodes(g), function(v1){ + if(igraph::degree(g, v1, mode="in") == 0) NULL else { + goodNeighbors <- igraph::neighbors(g, igraph::V(g)[v1], mode="out") + goodNeighbors <- goodNeighbors[goodNeighbors > igraph::V(g)[v1]] + unlist(lapply(goodNeighbors, function(v2){ + vapply(igraph::all_simple_paths(g, v2, igraph::V(g)[v1], mode="out", + cutoff = max_path_length), length, + FUN.VALUE = numeric(1)) + })) + } + })))) + mnet_info("Finding greatest common divisor of all paths.") out <- unique(sort(out)) while(out[1]!=1 && length(out)>1){ cd <- .gcd(out[1], out[2]) if(length(out)==2) out <- cd else out <- c(cd, out[2:length(out)]) } - out[1]==1 + return(as.logical(out[1]==1)) +} + +.quiet <- function(x) { + sink(tempfile()) + on.exit(sink()) + invisible(force(x)) } .gcd <- function(x, y){ ifelse(y, Recall(y, x %% y), x) -} - +} + # Helper functions infer_net_reciprocity <- function(.data, method = "default") { out <- igraph::reciprocity(as_igraph(.data), mode = method) diff --git a/inst/tutorials/tutorial6/topology.Rmd b/inst/tutorials/tutorial6/topology.Rmd index aebeb15e..10dadd2e 100644 --- a/inst/tutorials/tutorial6/topology.Rmd +++ b/inst/tutorials/tutorial6/topology.Rmd @@ -16,6 +16,7 @@ library(learnr) library(manynet) library(patchwork) knitr::opts_chunk$set(echo = FALSE) +clear_glossary() learnr::random_phrases_add(language = "fr", praise = c("C'est génial!", "Beau travail", diff --git a/inst/tutorials/tutorial7/diffusion.Rmd b/inst/tutorials/tutorial7/diffusion.Rmd index 01e344f2..8c335db7 100644 --- a/inst/tutorials/tutorial7/diffusion.Rmd +++ b/inst/tutorials/tutorial7/diffusion.Rmd @@ -16,6 +16,7 @@ library(learnr) library(manynet) library(patchwork) library(ggplot2) +clear_glossary() knitr::opts_chunk$set(echo = FALSE) ``` From 5c40d7204feda5bf8210c29a8497d605c3f5dc0c Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 28 Oct 2024 20:14:35 +0100 Subject: [PATCH 08/12] Added over_membership() for calculating measures by membership vector --- NAMESPACE | 1 + R/measure_over.R | 16 ++++++++++++++++ man/measure_over.Rd | 16 ++++++++++++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index c64056c1..760a6799 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -653,6 +653,7 @@ export(node_triad_census) export(node_vitality) export(node_walktrap) export(node_weak_components) +export(over_membership) export(over_time) export(over_waves) export(pkg_data) diff --git a/R/measure_over.R b/R/measure_over.R index 01c197cb..eedebfa8 100644 --- a/R/measure_over.R +++ b/R/measure_over.R @@ -1,6 +1,8 @@ #' Helper functions for measuring over splits of networks #' #' @description +#' - `over_membership()` runs a function, e.g. a measure, +#' over different group memberships #' - `over_waves()` runs a function, e.g. a measure, #' over waves of a panel network #' - `over_time()` runs a function, e.g. a measure, @@ -25,6 +27,20 @@ #' @name measure_over NULL +#' @rdname measure_over +#' @export +over_membership <- function(.data, FUN, ..., membership, + strategy = "sequential", + verbose = FALSE){ + thisRequires("future") + thisRequires("furrr") + if(missing(.data)) {expect_nodes(); .data <- .G()} + oplan <- future::plan(strategy) + on.exit(future::plan(oplan), add = TRUE) + furrr::future_map_dbl(unique(membership), function(j) FUN(to_subgraph(.data, membership==j), ...), + .progress = verbose, .options = furrr::furrr_options(seed = T)) +} + #' @rdname measure_over #' @export over_waves <- function(.data, FUN, ..., attribute = "wave", diff --git a/man/measure_over.Rd b/man/measure_over.Rd index f38df504..7d5b10d3 100644 --- a/man/measure_over.Rd +++ b/man/measure_over.Rd @@ -2,10 +2,20 @@ % Please edit documentation in R/measure_over.R \name{measure_over} \alias{measure_over} +\alias{over_membership} \alias{over_waves} \alias{over_time} \title{Helper functions for measuring over splits of networks} \usage{ +over_membership( + .data, + FUN, + ..., + membership, + strategy = "sequential", + verbose = FALSE +) + over_waves( .data, FUN, @@ -39,8 +49,6 @@ over_time( \item{...}{Further arguments to be passed on to FUN.} -\item{attribute}{A string naming the attribute to be split upon.} - \item{strategy}{If \code{{furrr}} is installed, then multiple cores can be used to accelerate the function. By default \code{"sequential"}, @@ -53,11 +61,15 @@ See \href{https://furrr.futureverse.org}{\code{{furrr}}} for more.} By default FALSE. See \href{https://progressr.futureverse.org}{\code{{progressr}}} for more.} +\item{attribute}{A string naming the attribute to be split upon.} + \item{slice}{Optionally, a vector of specific slices. Otherwise all observed slices will be returned.} } \description{ \itemize{ +\item \code{over_membership()} runs a function, e.g. a measure, +over different group memberships \item \code{over_waves()} runs a function, e.g. a measure, over waves of a panel network \item \code{over_time()} runs a function, e.g. a measure, From 4b47dd427b770899a1f3ff1014ee2ce43a770b87 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 28 Oct 2024 20:14:49 +0100 Subject: [PATCH 09/12] Clearing the glossary at the start of tutorials --- inst/tutorials/tutorial2/visualisation.Rmd | 1 + inst/tutorials/tutorial5/position.Rmd | 1 + 2 files changed, 2 insertions(+) diff --git a/inst/tutorials/tutorial2/visualisation.Rmd b/inst/tutorials/tutorial2/visualisation.Rmd index ce4f6540..90e68ae6 100644 --- a/inst/tutorials/tutorial2/visualisation.Rmd +++ b/inst/tutorials/tutorial2/visualisation.Rmd @@ -16,6 +16,7 @@ library(learnr) library(manynet) library(migraph) library(patchwork) +clear_glossary() knitr::opts_chunk$set(echo = FALSE) ``` diff --git a/inst/tutorials/tutorial5/position.Rmd b/inst/tutorials/tutorial5/position.Rmd index c4f8e53a..49166102 100644 --- a/inst/tutorials/tutorial5/position.Rmd +++ b/inst/tutorials/tutorial5/position.Rmd @@ -15,6 +15,7 @@ library(learnr) library(manynet) library(patchwork) knitr::opts_chunk$set(echo = FALSE) +clear_glossary() friends <- to_uniplex(ison_algebra, "friends") social <- to_uniplex(ison_algebra, "social") tasks <- to_uniplex(ison_algebra, "tasks") From b6149973a6fb689d92548c8bb2aae1ec2e87a154 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Tue, 29 Oct 2024 19:17:39 +0100 Subject: [PATCH 10/12] Added glossary items to diffusion tutorial --- R/manynet-tutorials.R | 6 + inst/tutorials/tutorial7/diffusion.Rmd | 17 +- inst/tutorials/tutorial7/diffusion.html | 619 +++++++++++++----------- 3 files changed, 358 insertions(+), 284 deletions(-) diff --git a/R/manynet-tutorials.R b/R/manynet-tutorials.R index ee7b6b23..b21c7539 100644 --- a/R/manynet-tutorials.R +++ b/R/manynet-tutorials.R @@ -212,17 +212,22 @@ clear_glossary <- function(){ glossies <- list( acyclic = "An acyclic network is a network without any cycles.", + aperiodic = "An aperiodic network is a network where the greatest common divisor of the lengths of its cycles is one.", adhesion = "The minimum number of ties to remove to increase the number of components.", blockmodel = "A blockmodel reduces a network to a smaller comprehensible structure of the roles positions take with respect to one another.", bridge = "A bridge is a tie whose deletion increases the number of components.", cohesion = "The minimum number of nodes to remove to increase the number of components.", component = "A component is a connected subgraph not part of a larger connected subgraph.", + connected = "A connected network is one with a single (strong) component.", cutpoint = "A cutpoint or articulation point is a node whose deletion increases the number of components.", degree = "A node's degree is the number of connections it has.", giant = "The giant component is the component that includes the most nodes in the network.", graphlet = "A graphlet is a small, connected, induced, non-isomorphic subgraphs.", + hit = "A herd immunity threshold is the proportion of the population that would need to be immune for a disease to cease being endemic.", induced = "An induced subgraph comprises all ties in a subset of the nodes in a network.", + intervention = "A network intervention is a process to accelerate behavioural change or improve performance in a network.", lattice = "A network that can be drawn as a regular tiling.", + LTM = "A linear threshold model is a diffusion model where nodes are resistant to activation up to some threshold.", motif = "A subgraph that is exceptional or significant compared to a null model.", neighborhood = "A node's neighborhood is the set of other nodes to which that node is connected.", network = "A network comprises a set of nodes/vertices and a set of ties/edges among them.", @@ -231,6 +236,7 @@ glossies <- list( reduced = "A reduced graph is a representation of the ties within and between blocks in the network.", subgraph = "A subgraph comprises a subset of the nodes and ties in a network.", transitivity = "Triadic closure is where if the connections A-B and A-C exist among three nodes, there is a tendency for B-C also to be formed.", + threshold = "A threshold is a limit over which behaviour is expected to vary.", undirected = "An undirected network is one in which tie direction is undefined." ) diff --git a/inst/tutorials/tutorial7/diffusion.Rmd b/inst/tutorials/tutorial7/diffusion.Rmd index 8c335db7..b0170c54 100644 --- a/inst/tutorials/tutorial7/diffusion.Rmd +++ b/inst/tutorials/tutorial7/diffusion.Rmd @@ -221,8 +221,9 @@ What's happening here? Can you interpret this? So far, we've been using a simple cascading diffusion model where each node needs only to be in contact with one infectious individual to be infected. -But what if nodes have higher _thresholds_, or only some nodes have higher thresholds? -This is known as a _linear threshold_ model, +But what if nodes have higher `r gloss("thresholds", "threshold")`, +or only some nodes have higher thresholds? +This is known as a `r gloss("linear threshold", "LTM")` model, where if infection/influence on a node through some (potentially weighted) network exceeds some threshold, then they will adopt/become infected. @@ -365,7 +366,7 @@ Can you rewrite the code above so that fractional thresholds are used? Let's say that you have developed an exciting new policy and you are keen to maximise how quickly and thoroughly it is adopted. -We are interested here in _network intervention_. +We are interested here in `r gloss("network intervention", "intervention")`. ### Choosing where to seed @@ -761,7 +762,7 @@ But then... ### How many people do we need to vaccinate? We can identify how many people need to be vaccinated through -the Herd Immunity Threshold or HIT. +the `gloss("Herd Immunity Threshold", "hit")` or HIT. HIT indicates the threshold at which the reduction of susceptible members of the network means that infections will no longer keep increasing, allowing herd immunity to be achieved. @@ -863,9 +864,9 @@ among network academics. Perhaps we wish to get them to change their local networks/behavior, but they have different beliefs about whether this will make a difference. To see whether this network will converge to consensus, -check whether the network is _connected_ and _aperiodic_: +check whether the network is `r gloss("connected")` and `r gloss("aperiodic")`: -+ `is_connected()` marks whether network is weakly connected if the network is *undirected* or strongly connected if directed. ++ `is_connected()` marks whether network is weakly connected if the network is `r gloss("undirected")` or strongly connected if directed. + `is_aperiodic()` marks whether network is aperiodic, meaning there is no integer k > 1 that divides the length of every cycle of the graph. ```{r aperiod, exercise = TRUE, purl = FALSE} @@ -981,4 +982,8 @@ plot(netlearn2) ``` +## Glossary +Here are some of the terms that we have covered in this module: + +`r print_glossary()` diff --git a/inst/tutorials/tutorial7/diffusion.html b/inst/tutorials/tutorial7/diffusion.html index 96ea8f3e..cfc44860 100644 --- a/inst/tutorials/tutorial7/diffusion.html +++ b/inst/tutorials/tutorial7/diffusion.html @@ -312,7 +312,7 @@

Varying network structure

Free play: US States

Run an influence cascade on US states’ geographic contiguity in -ison_usstates. You can start the infection in California by +irps_usgeo. You can start the infection in California by specifying seeds = 5.

Free play: US States
-
us_diff <- play_diffusion(ison_usstates, seeds = 5)
+
us_diff <- play_diffusion(irps_usgeo, seeds = 5)
 plot(us_diff)
 graphr(us_diff)
 grapht(us_diff)
@@ -335,11 +335,14 @@ 

Free play: US States

Linear threshold models

So far, we’ve been using a simple cascading diffusion model where each node needs only to be in contact with one infectious individual to -be infected. But what if nodes have higher thresholds, or only -some nodes have higher thresholds? This is known as a linear -threshold model, where if infection/influence on a node through -some (potentially weighted) network exceeds some threshold, then they -will adopt/become infected.

+be infected. But what if nodes have higher + +thresholds , or only some nodes have higher thresholds? +This is known as a + +linear threshold model, where if infection/influence on a +node through some (potentially weighted) network exceeds some threshold, +then they will adopt/become infected.

Threshold rising

Let’s use the ring network again this time to illustrate the impact @@ -449,11 +452,11 @@

Complex thresholds

Varying thresholds

Lastly, note that it may be that thresholds vary across the network. Let’s use an example network to explore this: -ison_lotr.

+fict_lotr.

-
graphr(ison_lotr, node_color = "Race")
+
graphr(fict_lotr, node_color = "Race")

Something is going around Middle-Earth, but different races have @@ -462,7 +465,7 @@

Varying thresholds

-
lotr_resist <- ison_lotr %>% mutate(resistance = dplyr::case_when(Race == "Dwarf" ~ 2,
+
lotr_resist <- fict_lotr %>% mutate(resistance = dplyr::case_when(Race == "Dwarf" ~ 2,
                                                    Race == "Elf" ~ 4,
                                                    Race == "Ent" ~ 5,
                                                    Race == "Hobbit" ~ 3,
@@ -493,7 +496,9 @@ 

Free play: Lord of the Rings

Intervention

Let’s say that you have developed an exciting new policy and you are keen to maximise how quickly and thoroughly it is adopted. We are -interested here in network intervention.

+interested here in + +network intervention .

Choosing where to seed

Since the ring network we constructed is cyclical, then no matter @@ -920,12 +925,12 @@

Make it stop

class="section level3">

How many people do we need to vaccinate?

We can identify how many people need to be vaccinated through the -Herd Immunity Threshold or HIT. HIT indicates the threshold at which the -reduction of susceptible members of the network means that infections -will no longer keep increasing, allowing herd immunity to be achieved. -net_immunity() gives us the proportion of the population -that would need to be recovered or vaccinated for the network to have -herd immunity.

+gloss("Herd Immunity Threshold", "hit") or HIT. HIT +indicates the threshold at which the reduction of susceptible members of +the network means that infections will no longer keep increasing, +allowing herd immunity to be achieved. net_immunity() gives +us the proportion of the population that would need to be recovered or +vaccinated for the network to have herd immunity.

@@ -954,7 +959,7 @@

How many people do we need to vaccinate?

Free play: Grey’s Anatomy

-

Let’s try this out on the ison_greys dataset, a dataset +

Let’s try this out on the fict_greys dataset, a dataset of character ‘hook-ups’ in the Grey’s Anatomy TV show. You can just concentrate on the giant component (which is plenty incestuous!). We could say that there’s a new, highly infectious disease transmittable @@ -968,7 +973,7 @@

Free play: Grey’s Anatomy

-
greys <- to_giant(ison_greys)
+
greys <- to_giant(fict_greys)
 graphr(greys)
 graphs(play_diffusion(greys, seeds = "Mark Sloan", transmissibility = 0.25,
                       latency = 0.25, recovery = 0.2, waning = 0.2), 
@@ -1005,11 +1010,15 @@ 

Expectations of convergence and consensus

change their local networks/behavior, but they have different beliefs about whether this will make a difference. To see whether this network will converge to consensus, check whether the network is -connected and aperiodic:

+ +connected and + +aperiodic :

  • is_connected() marks whether network is weakly -connected if the network is undirected or strongly connected if -directed.
  • +connected if the network is + +undirected or strongly connected if directed.
  • is_aperiodic() marks whether network is aperiodic, meaning there is no integer k > 1 that divides the length of every cycle of the graph.
  • @@ -1118,12 +1127,59 @@

    Free play: Networkers

    (netlearn2 <- play_learning(ison_networkers, beliefs2)) plot(netlearn2)
+
+
+
+

Glossary

+

Here are some of the terms that we have covered in this module:

+
+
+Aperiodic +
+
+An aperiodic network is a network where the greatest common divisor of +the lengths of its cycles is one. +
+
+Connected +
+
+A connected network is one with a single (strong) component. +
+
+Intervention +
+
+A network intervention is a process to accelerate behavioural change or +improve performance in a network. +
+
+Ltm +
+
+A linear threshold model is a diffusion model where nodes are resistant +to activation up to some threshold. +
+
+Threshold +
+
+A threshold is a limit over which behaviour is expected to vary. +
+
+Undirected +
+
+An undirected network is one in which tie direction is undefined. +
+

@@ -1158,16 +1214,17 @@

Free play: Networkers

@@ -1548,19 +1605,19 @@

Free play: Networkers

@@ -1662,11 +1720,12 @@

Free play: Networkers

@@ -1722,11 +1781,12 @@

Free play: Networkers

@@ -1786,19 +1846,19 @@

Free play: Networkers

@@ -2019,11 +2080,12 @@

Free play: Networkers

@@ -2124,8 +2187,8 @@

Free play: Networkers

@@ -2193,19 +2256,19 @@

Free play: Networkers

@@ -2318,8 +2381,8 @@

Free play: Networkers

@@ -2597,8 +2660,8 @@

Free play: Networkers

@@ -2670,8 +2733,8 @@

Free play: Networkers

@@ -2783,17 +2846,17 @@

Free play: Networkers

@@ -2821,8 +2884,8 @@

Free play: Networkers

@@ -3010,20 +3073,20 @@

Free play: Networkers

@@ -3051,11 +3114,12 @@

Free play: Networkers

@@ -3134,19 +3198,19 @@

Free play: Networkers

-
From a6853665b12203981696af9c71a52a291a86e38b Mon Sep 17 00:00:00 2001 From: James Hollway Date: Tue, 29 Oct 2024 19:17:55 +0100 Subject: [PATCH 11/12] #patch bump --- DESCRIPTION | 2 +- NEWS.md | 24 ++++++++++++++++++++++++ cran-comments.md | 3 ++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5d1ba58a..1f914694 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: manynet Title: Many Ways to Make, Modify, Map, Mark, and Measure Myriad Networks Version: 1.3.1 -Date: 2024-10-25 +Date: 2024-10-29 Description: Many tools for making, modifying, mapping, marking, measuring, and motifs and memberships of many different types of networks. All functions operate with matrices, edge lists, and 'igraph', 'network', and 'tidygraph' objects, diff --git a/NEWS.md b/NEWS.md index 5acb9e7a..a578f0da 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,27 @@ +# manynet 1.3.1 + +## Package + +- Fixed miscellaneous documentation issues, re roxygen +- Separated out the data sections in pkgdown + +## Modifying + +- Added `to_simplex.data.frame()` and `to_simplex.network()` + +## Marking + +- Fixed bug in `is_aperiodic()` where it would not work in tutorial chunks + +## Measuring + +- Added `over_membership()` for obtaining summary statistics by a membership vector + +## Practicing + +- Fixed data pointers in several tutorials +- Added glossary items to diffusion tutorial + # manynet 1.3.0 ## Package diff --git a/cran-comments.md b/cran-comments.md index a6c532ca..552540be 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -10,4 +10,5 @@ 0 errors | 0 warnings | 0 notes * Attempted to fix non ASCII strings warning -* Changes to avoid reverse dependency issues for igraph \ No newline at end of file +* Changes to avoid reverse dependency issues for igraph +* Changes to avoid long runtimes for one example on some systems \ No newline at end of file From 33cdf67f2816d4d800924c8df6879496c2ae822d Mon Sep 17 00:00:00 2001 From: James Hollway Date: Tue, 29 Oct 2024 19:21:14 +0100 Subject: [PATCH 12/12] Fixed doc bug on over_membership --- R/measure_over.R | 1 + man/measure_over.Rd | 2 ++ 2 files changed, 3 insertions(+) diff --git a/R/measure_over.R b/R/measure_over.R index eedebfa8..c7bde62e 100644 --- a/R/measure_over.R +++ b/R/measure_over.R @@ -28,6 +28,7 @@ NULL #' @rdname measure_over +#' @param membership A categorical membership vector. #' @export over_membership <- function(.data, FUN, ..., membership, strategy = "sequential", diff --git a/man/measure_over.Rd b/man/measure_over.Rd index 7d5b10d3..7f2aa2b5 100644 --- a/man/measure_over.Rd +++ b/man/measure_over.Rd @@ -49,6 +49,8 @@ over_time( \item{...}{Further arguments to be passed on to FUN.} +\item{membership}{A categorical membership vector.} + \item{strategy}{If \code{{furrr}} is installed, then multiple cores can be used to accelerate the function. By default \code{"sequential"},