From f9f3134c33f46378676b16c1d96e12760e7fef15 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 28 Mar 2024 17:48:34 +0100 Subject: [PATCH 01/97] Fixed node_constraint() to work with weighted twomode networks, thanks to Toshitaka Izumi for spotting this --- R/measure_holes.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/measure_holes.R b/R/measure_holes.R index ea2fb2b5..25c05ed2 100644 --- a/R/measure_holes.R +++ b/R/measure_holes.R @@ -157,7 +157,7 @@ node_constraint <- function(.data) { res <- vector() for (i in inst) { ci <- 0 - membs <- names(which(mat[, i] == 1)) + membs <- names(which(mat[, i] > 0)) for (a in membs) { pia <- colp[a, i] oth <- membs[membs != a] From 71c0f1974a853a8edf68ab75377b25094adf8e9f Mon Sep 17 00:00:00 2001 From: James Hollway Date: Tue, 30 Apr 2024 11:49:51 +0200 Subject: [PATCH 02/97] Updated migraph logo with stocnet address, colorsafe colorway, and larger nodes and ties --- inst/migraph.png | Bin 109481 -> 194117 bytes man/figures/logo.png | Bin 62608 -> 194117 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/inst/migraph.png b/inst/migraph.png index 80fc85e57c92233707576f7548050af82647649d..13092a83225fe775c20c423a7e9a07e7abe5790b 100644 GIT binary patch literal 194117 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

Eck}OkuIvlP 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 z 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 literal 109481 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

V-F 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

Eck}OkuIvlP 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 z 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 literal 62608 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 U5z&QKZ4&UOB&Q}@ByEEKKNRBaC;$Ke From 7354c57bc385bb578bdb71dcbffa306b9cb0f282 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 2 May 2024 19:57:56 +0200 Subject: [PATCH 03/97] Added network_independence() for calculating the number of nodes in the largest independent set --- NAMESPACE | 2 ++ R/measure_cohesion.R | 16 ++++++++++++++++ inst/migraph_logo.png | Bin 0 -> 462642 bytes inst/migraph_old.png | Bin 0 -> 109481 bytes man/cohesion.Rd | 6 ++++++ man/figures/logo_old.png | Bin 0 -> 62608 bytes 6 files changed, 24 insertions(+) create mode 100644 inst/migraph_logo.png create mode 100644 inst/migraph_old.png create mode 100644 man/figures/logo_old.png diff --git a/NAMESPACE b/NAMESPACE index 35ee04aa..51377d71 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -110,6 +110,7 @@ export(network_heterophily) export(network_homophily) export(network_immunity) export(network_indegree) +export(network_independence) export(network_infection_length) export(network_length) export(network_mixed_census) @@ -254,6 +255,7 @@ importFrom(igraph,fit_power_law) importFrom(igraph,graph_from_incidence_matrix) importFrom(igraph,is_bipartite) importFrom(igraph,is_igraph) +importFrom(igraph,ivs_size) importFrom(igraph,knn) importFrom(igraph,make_ego_graph) importFrom(igraph,mean_distance) diff --git a/R/measure_cohesion.R b/R/measure_cohesion.R index f7b86843..d66e1a48 100644 --- a/R/measure_cohesion.R +++ b/R/measure_cohesion.R @@ -14,6 +14,8 @@ #' from the network needed to increase the number of components. #' - `network_diameter()` measures the maximum path length in the network. #' - `network_length()` measures the average path length in the network. +#' - `network_independence()` measures the independence number, +#' or size of the largest independent set in the network. #' @param .data An object of a `{manynet}`-consistent class: #' \itemize{ #' \item matrix (adjacency or incidence) from `{base}` R @@ -106,3 +108,17 @@ network_length <- function(.data){ directed = manynet::is_directed(object)), object) } + +#' @rdname cohesion +#' @importFrom igraph ivs_size +#' @examples +#' network_independence(manynet::ison_adolescents) +#' @export +network_independence <- function(.data){ + if(manynet::is_twomode(.data)){ + out <- igraph::ivs_size(manynet::to_mode1(manynet::as_igraph(.data))) + } else { + out <- igraph::ivs_size(manynet::to_undirected(manynet::as_igraph(.data))) + } + make_network_measure(out, .data) +} diff --git a/inst/migraph_logo.png b/inst/migraph_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3b2f314149c794e666b07ebd5e727dcea982df3f GIT binary patch literal 462642 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≶ypXeNp|=($mf$|Mv3 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

  • Wsn%Z(%Ja&x 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⁣>xiKsxbFQXNZ0S4y_Z!#CgDZV>f=43gez0qt7T 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�pw=g@WbzpHQrn(Z7HHslg@YzicvL-gyz6>9 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ⅅ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 E1y7ub2mk;8 literal 0 HcmV?d00001 diff --git a/inst/migraph_old.png b/inst/migraph_old.png new file mode 100644 index 0000000000000000000000000000000000000000..80fc85e57c92233707576f7548050af82647649d GIT binary patch literal 109481 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

    Step one: starting with a census

    # But it's easier to simplify the network by removing the classification into different types of ties.
     # Note that this also reduces the total number of possible paths between nodes
     ison_algebra %>%
    -  select_ties(-c(friends, social, tasks)) %>%
    +  select_ties(-type) %>%
       node_tie_census()

    Note that node_tie_census() does not need to be passed @@ -828,22 +828,22 @@

    Reduced graph

    @@ -861,28 +861,28 @@

    Reduced graph

    @@ -1025,17 +1025,17 @@

    Reduced graph

    @@ -1158,8 +1158,8 @@

    Reduced graph

    exercise.setup = "\"data\"", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("# But it's easier to simplify the network by removing the classification into different types of ties.", "# Note that this also reduces the total number of possible paths between nodes", - "ison_algebra %>%", " select_ties(-c(friends, social, tasks)) %>%", - " node_tie_census()"), chunk_opts = list(label = "construct-binary-solution")), + "ison_algebra %>%", " select_ties(-type) %>%", " node_tie_census()" + ), chunk_opts = list(label = "construct-binary-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, highlight = FALSE, size = "normalsize", @@ -1234,11 +1234,11 @@

    Reduced graph

    @@ -1594,12 +1594,12 @@

    Reduced graph

    diff --git a/inst/tutorials/tutorial5/position_data/data_chunks_index.txt b/inst/tutorials/tutorial5/position_data/data_chunks_index.txt new file mode 100644 index 00000000..2846c4f9 --- /dev/null +++ b/inst/tutorials/tutorial5/position_data/data_chunks_index.txt @@ -0,0 +1 @@ +data.RData diff --git a/inst/tutorials/tutorial6/topology.Rmd b/inst/tutorials/tutorial6/topology.Rmd index d92f09b1..32ada92b 100644 --- a/inst/tutorials/tutorial6/topology.Rmd +++ b/inst/tutorials/tutorial6/topology.Rmd @@ -5,6 +5,10 @@ output: learnr::tutorial: theme: journal runtime: shiny_prerendered +description: > + This tutorial aims to teach you how to create deterministic networks, + generate probabilistic networks, identify core-periphery structures, + and measure network resilience. --- ```{r setup, include = FALSE} diff --git a/inst/tutorials/tutorial8/regression.Rmd b/inst/tutorials/tutorial8/regression.Rmd index c92ecdc4..98c3a548 100644 --- a/inst/tutorials/tutorial8/regression.Rmd +++ b/inst/tutorials/tutorial8/regression.Rmd @@ -5,6 +5,10 @@ output: learnr::tutorial: theme: journal runtime: shiny_prerendered +description: > + This tutorial aims to teach you how to measure and test network diversity, + moving from univariate to multivariate tests, including + network linear models (multiple regression quadratic assignment procedures). --- ```{r setup, include=FALSE} From 4d15f500b5dc9693760007290ca7e57697026d80 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 14 Jun 2024 07:29:34 +0200 Subject: [PATCH 32/97] Hierarchical clustering algorithms now return dendrograms --- R/member_community.R | 36 ++++++++++++++++++++++++++---------- man/community.Rd | 1 + 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/R/member_community.R b/R/member_community.R index 9b42b70f..f854ee61 100644 --- a/R/member_community.R +++ b/R/member_community.R @@ -126,12 +126,17 @@ node_kernighanlin <- function(.data){ #' _Physical Review E_ 69: 026113. #' @examples #' node_edge_betweenness(ison_adolescents) +#' plot(node_edge_betweenness(ison_adolescents)) #' @export node_edge_betweenness <- function(.data){ if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- suppressWarnings(igraph::cluster_edge_betweenness( - manynet::as_igraph(.data))$membership) - make_node_member(out, .data) + clust <- suppressWarnings(igraph::cluster_edge_betweenness( + manynet::as_igraph(.data))) + out <- clust$membership + out <- make_node_member(out, .data) + attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) + attr(out, "k") <- max(clust$membership) + out } #' @rdname community @@ -151,9 +156,13 @@ node_edge_betweenness <- function(.data){ #' @export node_fast_greedy <- function(.data){ if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- igraph::cluster_fast_greedy(manynet::as_igraph(.data) - )$membership + clust <- igraph::cluster_fast_greedy(manynet::as_igraph(.data)) + out <- clust$membership make_node_member(out, .data) + out <- make_node_member(out, .data) + attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) + attr(out, "k") <- max(clust$membership) + out } #' @rdname community @@ -173,9 +182,13 @@ node_fast_greedy <- function(.data){ #' @export node_leading_eigen <- function(.data){ if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- igraph::cluster_leading_eigen(manynet::as_igraph(.data) - )$membership + clust <- igraph::cluster_leading_eigen(manynet::as_igraph(.data)) + out <- clust$membership make_node_member(out, .data) + out <- make_node_member(out, .data) + attr(out, "hc") <- as.hclust(clust) + attr(out, "k") <- max(clust$membership) + out } #' @rdname community @@ -194,10 +207,13 @@ node_leading_eigen <- function(.data){ #' @export node_walktrap <- function(.data, times = 50){ if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- igraph::cluster_walktrap(manynet::as_igraph(.data), - steps=times)$membership + clust <- igraph::cluster_walktrap(manynet::as_igraph(.data)) + out <- clust$membership make_node_member(out, .data) - + out <- make_node_member(out, .data) + attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) + attr(out, "k") <- max(clust$membership) + out } #' @rdname community diff --git a/man/community.Rd b/man/community.Rd index 74c2d841..f001f875 100644 --- a/man/community.Rd +++ b/man/community.Rd @@ -197,6 +197,7 @@ node_optimal(ison_adolescents) node_kernighanlin(ison_adolescents) node_kernighanlin(ison_southern_women) node_edge_betweenness(ison_adolescents) +plot(node_edge_betweenness(ison_adolescents)) node_fast_greedy(ison_adolescents) node_leading_eigen(ison_adolescents) node_walktrap(ison_adolescents) From 8bfed72da68b5b99c320e0de9528f9cbd6073c75 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 14 Jun 2024 13:17:05 +0200 Subject: [PATCH 33/97] node_roulette() renamed to node_in_roulette() --- NAMESPACE | 1 + R/member_cliques.R | 4 ++-- man/cliques.Rd | 9 +++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index bad296b2..f82bf014 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -163,6 +163,7 @@ export(node_harmonic) export(node_heterophily) export(node_hierarchy) export(node_homophily) +export(node_in_roulette) export(node_indegree) export(node_induced) export(node_infection_length) diff --git a/R/member_cliques.R b/R/member_cliques.R index 834a0932..dd9391f8 100644 --- a/R/member_cliques.R +++ b/R/member_cliques.R @@ -4,7 +4,7 @@ #' These functions create a vector of nodes' memberships in #' cliques: #' -#' - `node_roulette()` assigns nodes to maximally diverse groups. +#' - `node_in_roulette()` assigns nodes to maximally diverse groups. #' #' @section Maximally diverse grouping problem: #' This well known computational problem is a NP-hard problem @@ -56,7 +56,7 @@ NULL #' _European Journal of Operational Research_ 289(3):1067–86. #' \doi{10.1016/j.ejor.2020.07.048}. #' @export -node_roulette <- function(.data, num_groups, group_size, times = NULL){ +node_in_roulette <- function(.data, num_groups, group_size, times = NULL){ if(missing(.data)) {expect_nodes(); .data <- .G()} if(missing(num_groups) & missing(group_size)){ stop(paste("Either `num_groups` must indicate number of groups desired", diff --git a/man/cliques.Rd b/man/cliques.Rd index cf1021c2..dd73a204 100644 --- a/man/cliques.Rd +++ b/man/cliques.Rd @@ -2,10 +2,10 @@ % Please edit documentation in R/member_cliques.R \name{cliques} \alias{cliques} -\alias{node_roulette} +\alias{node_in_roulette} \title{Clique partitioning algorithms} \usage{ -node_roulette(.data, num_groups, group_size, times = NULL) +node_in_roulette(.data, num_groups, group_size, times = NULL) } \arguments{ \item{.data}{An object of a \code{{manynet}}-consistent class: @@ -35,7 +35,7 @@ will take place irrespective of whether it improves the objective function.} These functions create a vector of nodes' memberships in cliques: \itemize{ -\item \code{node_roulette()} assigns nodes to maximally diverse groups. +\item \code{node_in_roulette()} assigns nodes to maximally diverse groups. } } \section{Maximally diverse grouping problem}{ @@ -79,6 +79,7 @@ Other memberships: \code{\link{community}}, \code{\link{components}()}, \code{\link{core}}, -\code{\link{equivalence}} +\code{\link{equivalence}}, +\code{\link{hierarchical_community}} } \concept{memberships} From 3d8e1cbeb1d4fe56648b54872e643eabd3437575 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 14 Jun 2024 13:18:55 +0200 Subject: [PATCH 34/97] node_components() renamed node_in_component() NB no longer plural!, node_weak_components() now node_in_weak(), node_strong_components() now node_in_strong() --- NAMESPACE | 3 +++ R/member_components.R | 15 +++++++-------- man/components.Rd | 24 ++++++++++++------------ 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index f82bf014..257c1829 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -163,7 +163,10 @@ export(node_harmonic) export(node_heterophily) export(node_hierarchy) export(node_homophily) +export(node_in_component) export(node_in_roulette) +export(node_in_strong) +export(node_in_weak) export(node_indegree) export(node_induced) export(node_infection_length) diff --git a/R/member_components.R b/R/member_components.R index aa837bb5..f6efce9f 100644 --- a/R/member_components.R +++ b/R/member_components.R @@ -4,13 +4,12 @@ #' These functions create a vector of nodes' memberships in #' components or degrees of coreness: #' -#' - `node_components()` assigns nodes' component membership +#' - `node_in_component()` assigns nodes' component membership #' using edge direction where available. -#' - `node_weak_components()` assigns nodes' component membership +#' - `node_in_weak()` assigns nodes' component membership #' ignoring edge direction. -#' - `node_strong_components()` assigns nodes' component membership +#' - `node_in_strong()` assigns nodes' component membership #' based on edge direction. -#' - `node_roulette()` #' #' In graph theory, components, sometimes called connected components, #' are induced subgraphs from partitioning the nodes into disjoint sets. @@ -36,9 +35,9 @@ NULL #' @rdname components #' @importFrom igraph components #' @examples -#' node_components(mpn_bristol) +#' node_in_component(mpn_bristol) #' @export -node_components <- function(.data){ +node_in_component <- function(.data){ if(missing(.data)) {expect_nodes(); .data <- .G()} if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) make_node_member(igraph::components(.data, mode = "strong")$membership, @@ -48,7 +47,7 @@ node_components <- function(.data){ #' @rdname components #' @importFrom igraph components #' @export -node_weak_components <- function(.data){ +node_in_weak <- function(.data){ if(missing(.data)) {expect_nodes(); .data <- .G()} if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) make_node_member(igraph::components(.data, mode = "weak")$membership, @@ -58,7 +57,7 @@ node_weak_components <- function(.data){ #' @rdname components #' @importFrom igraph components #' @export -node_strong_components <- function(.data){ +node_in_strong <- function(.data){ if(missing(.data)) {expect_nodes(); .data <- .G()} if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) make_node_member(igraph::components(.data, mode = "strong")$membership, diff --git a/man/components.Rd b/man/components.Rd index 3d604ad6..cb4687c4 100644 --- a/man/components.Rd +++ b/man/components.Rd @@ -2,16 +2,16 @@ % Please edit documentation in R/member_components.R \name{components} \alias{components} -\alias{node_components} -\alias{node_weak_components} -\alias{node_strong_components} +\alias{node_in_component} +\alias{node_in_weak} +\alias{node_in_strong} \title{Component partitioning algorithms} \usage{ -node_components(.data) +node_in_component(.data) -node_weak_components(.data) +node_in_weak(.data) -node_strong_components(.data) +node_in_strong(.data) } \arguments{ \item{.data}{An object of a \code{{manynet}}-consistent class: @@ -27,13 +27,12 @@ node_strong_components(.data) These functions create a vector of nodes' memberships in components or degrees of coreness: \itemize{ -\item \code{node_components()} assigns nodes' component membership +\item \code{node_in_component()} assigns nodes' component membership using edge direction where available. -\item \code{node_weak_components()} assigns nodes' component membership +\item \code{node_in_weak()} assigns nodes' component membership ignoring edge direction. -\item \code{node_strong_components()} assigns nodes' component membership +\item \code{node_in_strong()} assigns nodes' component membership based on edge direction. -\item \code{node_roulette()} } In graph theory, components, sometimes called connected components, @@ -54,13 +53,14 @@ a node's coreness is \emph{k} if it belongs to the \emph{k}-core but not to the (\emph{k}+1)-core. } \examples{ -node_components(mpn_bristol) +node_in_component(mpn_bristol) } \seealso{ Other memberships: \code{\link{cliques}}, \code{\link{community}}, \code{\link{core}}, -\code{\link{equivalence}} +\code{\link{equivalence}}, +\code{\link{hierarchical_community}} } \concept{memberships} From a3c369cba5c302c17d9d014c21ccb57c3d2885a1 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 14 Jun 2024 13:20:12 +0200 Subject: [PATCH 35/97] Moved to_correlation() to manynet, filled in _in_ defunct --- NAMESPACE | 1 - R/migraph-defunct.R | 34 ++++++++++++++ R/motif_correlation.R | 98 ----------------------------------------- man/node_correlation.Rd | 46 ------------------- 4 files changed, 34 insertions(+), 145 deletions(-) delete mode 100644 R/motif_correlation.R delete mode 100644 man/node_correlation.Rd diff --git a/NAMESPACE b/NAMESPACE index 257c1829..92437c9e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -212,7 +212,6 @@ export(tie_closeness) export(tie_cohesion) export(tie_degree) export(tie_eigenvector) -export(to_correlation) export(with_graph) export(xlab) export(ylab) diff --git a/R/migraph-defunct.R b/R/migraph-defunct.R index 3c0ead6a..7e043848 100644 --- a/R/migraph-defunct.R +++ b/R/migraph-defunct.R @@ -363,3 +363,37 @@ node_homophily <- function(object, attribute) { old = "node_homophily") node_heterophily(object, attribute) } + + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_roulette <- function(.data) { + .Deprecated("node_in_roulette", package = "migraph", + old = "node_roulette") + node_in_roulette(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_components <- function(.data) { + .Deprecated("node_in_component", package = "migraph", + old = "node_components") + node_in_component(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_weak_components <- function(.data) { + .Deprecated("node_in_weak", package = "migraph", + old = "node_weak_components") + node_in_weak(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_strong_components <- function(.data) { + .Deprecated("node_in_strong", package = "migraph", + old = "node_strong_components") + node_in_strong(.data) +} + diff --git a/R/motif_correlation.R b/R/motif_correlation.R deleted file mode 100644 index ab09c93e..00000000 --- a/R/motif_correlation.R +++ /dev/null @@ -1,98 +0,0 @@ -#' Node correlation -#' -#' @description -#' This function performs a Pearson pairwise correlation on a given matrix or network data. -#' It includes a switch: -#' whereas for a two-mode network it will perform a regular correlation, -#' including all rows, -#' for an undirected network it will perform a correlation on a matrix -#' with the diagonals removed, -#' for a reciprocated network it will include the difference -#' between reciprocated ties, -#' and for complex networks it will include also the difference -#' between the self ties in each pairwise calculation. -#' This function runs in \eqn{O(mn^2)} complexity. -#' @name node_correlation -#' @inheritParams cohesion -#' @param method One of the following: -#' "all" includes all information, -#' "diag" excludes the diagonal (self-ties), -#' "recip" excludes the diagonal but compares pairs' reciprocal ties, -#' and "complex" compares pairs' reciprocal ties and their self ties. -#' By default the appropriate method is chosen based on the network format. -#' @family motifs -#' @export -to_correlation <- function(.data, method = NULL){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - mat <- manynet::as_matrix(.data) - if(is.null(method)) method <- ifelse(manynet::is_twomode(.data), - "all", - ifelse(manynet::is_complex(.data), - "complex", - ifelse(manynet::is_directed(.data), - "recip", "diag"))) - out <- switch(method, - all = .corTwomode(mat), - complex = .corComplex(mat), - recip = .corRecip(mat), - diag = .corDiag(mat)) - out -} - -.corTwomode <- function(m0){ - stats::cor(m0) -} - -# Though warnings need to be suppressed, -# this is bench::mark()ed at about 17-18 times faster than corrColsExcludeDiag(), -# and uses 188 times less memory -.corDiag <- function(M){ - diag(M) <- NA - out <- suppressWarnings(stats::cor(M, use = "pairwise.complete.obs")) - out[is.na(out)] <- 0 - diag(out) <- 1 - out -} - -# Though warnings need to be suppressed, -# this is bench::mark()ed at about 2 times faster than corrColsRecipRLB() -.corRecip <- function(M){ - all.pairs <- utils::combn(1:ncol(M),2) - corres <- apply(all.pairs, 2, function(i){ - x <- c(M[-i,i[1]], M[i[1],i[2]]) - y <- c(M[-i,i[2]], M[i[2],i[1]]) - suppressWarnings(stats::cor(x = x, y = y)) - }) - out <- matrix(1,nrow(M),ncol(M)) - out[lower.tri(out)] <- corres - out <- .makeSymm(out) - out[is.na(out)] <- 0 - diag(out) <- 1 - rownames(out) <- rownames(M) - colnames(out) <- colnames(M) - out -} - -# Though warnings need to be suppressed, -# this is bench::mark()ed at about 2.3 times faster than corrColsRecipUCI() -.corComplex <- function(M){ - all.pairs <- utils::combn(1:ncol(M),2) - corres <- apply(all.pairs, 2, function(i){ - x <- c(M[-i,i[1]], M[i[1],i[2]], M[i[1],i[1]]) - y <- c(M[-i,i[2]], M[i[2],i[1]], M[i[2],i[2]]) - suppressWarnings(stats::cor(x = x, y = y)) - }) - out <- matrix(1,nrow(M),ncol(M)) - out[lower.tri(out)] <- corres - out <- .makeSymm(out) - out[is.na(out)] <- 0 - diag(out) <- 1 - rownames(out) <- rownames(M) - colnames(out) <- colnames(M) - out -} - -.makeSymm <- function(m) { - m[upper.tri(m)] <- t(m)[upper.tri(m)] - return(m) -} diff --git a/man/node_correlation.Rd b/man/node_correlation.Rd deleted file mode 100644 index 9713b18c..00000000 --- a/man/node_correlation.Rd +++ /dev/null @@ -1,46 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/motif_correlation.R -\name{node_correlation} -\alias{node_correlation} -\alias{to_correlation} -\title{Node correlation} -\usage{ -to_correlation(.data, method = NULL) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{method}{One of the following: -"all" includes all information, -"diag" excludes the diagonal (self-ties), -"recip" excludes the diagonal but compares pairs' reciprocal ties, -and "complex" compares pairs' reciprocal ties and their self ties. -By default the appropriate method is chosen based on the network format.} -} -\description{ -This function performs a Pearson pairwise correlation on a given matrix or network data. -It includes a switch: -whereas for a two-mode network it will perform a regular correlation, -including all rows, -for an undirected network it will perform a correlation on a matrix -with the diagonals removed, -for a reciprocated network it will include the difference -between reciprocated ties, -and for complex networks it will include also the difference -between the self ties in each pairwise calculation. -This function runs in \eqn{O(mn^2)} complexity. -} -\seealso{ -Other motifs: -\code{\link{brokerage_census}}, -\code{\link{network_census}}, -\code{\link{node_census}} -} -\concept{motifs} From 42d2d5c252944dccdd73f21770f8ab52a06e98e6 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 14 Jun 2024 13:25:03 +0200 Subject: [PATCH 36/97] node_core() renamed to node_in_core(), node_coreness() now returns node_measure output --- R/member_core.R | 10 +++++----- R/migraph-defunct.R | 8 ++++++++ man/brokerage_census.Rd | 3 +-- man/core.Rd | 13 +++++++------ man/defunct.Rd | 26 ++++++++++++++++++++++++++ man/network_census.Rd | 3 +-- man/node_census.Rd | 3 +-- 7 files changed, 49 insertions(+), 17 deletions(-) diff --git a/R/member_core.R b/R/member_core.R index d07bf954..c3db1a4c 100644 --- a/R/member_core.R +++ b/R/member_core.R @@ -2,7 +2,7 @@ #' @description #' These functions identify nodes belonging to (some level of) the core of a network: #' -#' - `node_core()` assigns nodes to either the core or periphery. +#' - `node_in_core()` assigns nodes to either the core or periphery. #' - `node_coreness()` assigns nodes to their level of k-coreness. #' #' @inheritParams cohesion @@ -39,11 +39,11 @@ NULL #' \doi{10.48550/arXiv.1102.5511} #' @examples #' #mpn_elite_usa_advice %>% as_tidygraph %>% -#' # mutate(corep = node_core(mpn_elite_usa_advice)) %>% +#' # mutate(corep = node_in_core(mpn_elite_usa_advice)) %>% #' # autographr(node_color = "corep") -#' network_core(mpn_elite_usa_advice) +#' network_in_core(mpn_elite_usa_advice) #' @export -node_core <- function(.data, method = c("degree", "eigenvector")){ +node_in_core <- function(.data, method = c("degree", "eigenvector")){ if(missing(.data)) {expect_nodes(); .data <- .G()} method <- match.arg(method) if(manynet::is_directed(.data)) warning("Asymmetric core-periphery not yet implemented.") @@ -77,6 +77,6 @@ node_coreness <- function(.data){ if(missing(.data)) {expect_nodes(); .data <- .G()} if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) out <- igraph::coreness(.data) - make_node_member(out, .data) + make_node_measure(out, .data) } diff --git a/R/migraph-defunct.R b/R/migraph-defunct.R index 7e043848..bbc290f7 100644 --- a/R/migraph-defunct.R +++ b/R/migraph-defunct.R @@ -365,6 +365,14 @@ node_homophily <- function(object, attribute) { } +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_core <- function(.data) { + .Deprecated("node_in_core", package = "migraph", + old = "node_core") + node_in_core(.data) +} + #' @describeIn defunct Deprecated on 2024-06-14. #' @export node_roulette <- function(.data) { diff --git a/man/brokerage_census.Rd b/man/brokerage_census.Rd index 5bf6ef48..75daea70 100644 --- a/man/brokerage_census.Rd +++ b/man/brokerage_census.Rd @@ -69,7 +69,6 @@ and their application to multi-level environmental governance networks" \seealso{ Other motifs: \code{\link{network_census}}, -\code{\link{node_census}}, -\code{\link{node_correlation}} +\code{\link{node_census}} } \concept{motifs} diff --git a/man/core.Rd b/man/core.Rd index b19c0921..a6ecc033 100644 --- a/man/core.Rd +++ b/man/core.Rd @@ -2,11 +2,11 @@ % Please edit documentation in R/member_core.R \name{core} \alias{core} -\alias{node_core} +\alias{node_in_core} \alias{node_coreness} \title{Core-periphery clustering algorithms} \usage{ -node_core(.data, method = c("degree", "eigenvector")) +node_in_core(.data, method = c("degree", "eigenvector")) node_coreness(.data) } @@ -30,7 +30,7 @@ can be added if there is interest.} \description{ These functions identify nodes belonging to (some level of) the core of a network: \itemize{ -\item \code{node_core()} assigns nodes to either the core or periphery. +\item \code{node_in_core()} assigns nodes to either the core or periphery. \item \code{node_coreness()} assigns nodes to their level of k-coreness. } } @@ -50,9 +50,9 @@ it ignores ties between these blocks. \examples{ #mpn_elite_usa_advice \%>\% as_tidygraph \%>\% -# mutate(corep = node_core(mpn_elite_usa_advice)) \%>\% +# mutate(corep = node_in_core(mpn_elite_usa_advice)) \%>\% # autographr(node_color = "corep") -network_core(mpn_elite_usa_advice) +network_in_core(mpn_elite_usa_advice) node_coreness(ison_adolescents) } \references{ @@ -70,6 +70,7 @@ Other memberships: \code{\link{cliques}}, \code{\link{community}}, \code{\link{components}()}, -\code{\link{equivalence}} +\code{\link{equivalence}}, +\code{\link{hierarchical_community}} } \concept{memberships} diff --git a/man/defunct.Rd b/man/defunct.Rd index c68e09f4..588213b4 100644 --- a/man/defunct.Rd +++ b/man/defunct.Rd @@ -44,6 +44,11 @@ \alias{graph_smallworld} \alias{network_homophily} \alias{node_homophily} +\alias{node_core} +\alias{node_roulette} +\alias{node_components} +\alias{node_weak_components} +\alias{node_strong_components} \title{Functions that have been renamed, superseded, or are no longer working} \usage{ edge_betweenness(object, normalized = TRUE) @@ -129,6 +134,17 @@ graph_smallworld(object, times = 100) network_homophily(object, attribute) node_homophily(object, attribute) + +node_core(.data) + +node_roulette(.data) + +node_components(.data) + +node_weak_components(.data) + +node_strong_components(.data) + } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} @@ -225,5 +241,15 @@ wherever possible and update your scripts accordingly. \item \code{node_homophily()}: Deprecated on 2022-09-25. + +\item \code{node_core()}: Deprecated on 2024-06-14. + +\item \code{node_roulette()}: Deprecated on 2024-06-14. + +\item \code{node_components()}: Deprecated on 2024-06-14. + +\item \code{node_weak_components()}: Deprecated on 2024-06-14. + +\item \code{node_strong_components()}: Deprecated on 2024-06-14. }} \keyword{internal} diff --git a/man/network_census.Rd b/man/network_census.Rd index 91150f76..3f6eeaf0 100644 --- a/man/network_census.Rd +++ b/man/network_census.Rd @@ -56,7 +56,6 @@ Hollway, James, Alessandro Lomi, Francesca Pallotti, and Christoph Stadtfeld. 20 \seealso{ Other motifs: \code{\link{brokerage_census}}, -\code{\link{node_census}}, -\code{\link{node_correlation}} +\code{\link{node_census}} } \concept{motifs} diff --git a/man/node_census.Rd b/man/node_census.Rd index 2cf1b560..a9841eda 100644 --- a/man/node_census.Rd +++ b/man/node_census.Rd @@ -100,7 +100,6 @@ Opsahl, Tore, Filip Agneessens, and John Skvoretz. 2010. \seealso{ Other motifs: \code{\link{brokerage_census}}, -\code{\link{network_census}}, -\code{\link{node_correlation}} +\code{\link{network_census}} } \concept{motifs} From 52b24f44f4bff0966e57416d709cfb8969a380ab Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 14 Jun 2024 13:28:25 +0200 Subject: [PATCH 37/97] node_equivalence(), node_structural_equivalence(), node_regular_equivalence() and node_automorphic_equivalence() renamed to node_in_equivalence(), node_in_structural(), node_in_regular(), and node_in_automorphic() --- NAMESPACE | 5 +++++ R/member_equivalence.R | 14 +++++++------- R/migraph-defunct.R | 1 + man/defunct.Rd | 20 ++++++++++++++++++++ man/equivalence.Rd | 25 +++++++++++++------------ 5 files changed, 46 insertions(+), 19 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 92437c9e..f1a11571 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -163,9 +163,14 @@ export(node_harmonic) export(node_heterophily) export(node_hierarchy) export(node_homophily) +export(node_in_automorphic) export(node_in_component) +export(node_in_core) +export(node_in_equivalence) +export(node_in_regular) export(node_in_roulette) export(node_in_strong) +export(node_in_structural) export(node_in_weak) export(node_indegree) export(node_induced) diff --git a/R/member_equivalence.R b/R/member_equivalence.R index 55fa1134..146af71f 100644 --- a/R/member_equivalence.R +++ b/R/member_equivalence.R @@ -50,7 +50,7 @@ NULL #' @rdname equivalence #' @export -node_equivalence <- function(.data, census, +node_in_equivalence <- function(.data, census, k = c("silhouette", "elbow", "strict"), cluster = c("hierarchical", "concor"), distance = c("euclidean", "maximum", "manhattan", @@ -78,11 +78,11 @@ node_equivalence <- function(.data, census, #' @rdname equivalence #' @examples #' \donttest{ -#' (nse <- node_structural_equivalence(mpn_elite_usa_advice)) +#' (nse <- node_in_structural(mpn_elite_usa_advice)) #' plot(nse) #' } #' @export -node_structural_equivalence <- function(.data, +node_in_structural <- function(.data, k = c("silhouette", "elbow", "strict"), cluster = c("hierarchical", "concor"), distance = c("euclidean", "maximum", "manhattan", @@ -100,12 +100,12 @@ node_structural_equivalence <- function(.data, #' @rdname equivalence #' @examples #' \donttest{ -#' (nre <- node_regular_equivalence(mpn_elite_usa_advice, +#' (nre <- node_in_regular(mpn_elite_usa_advice, #' cluster = "concor")) #' plot(nre) #' } #' @export -node_regular_equivalence <- function(.data, +node_in_regular <- function(.data, k = c("silhouette", "elbow", "strict"), cluster = c("hierarchical", "concor"), distance = c("euclidean", "maximum", "manhattan", @@ -125,12 +125,12 @@ node_regular_equivalence <- function(.data, #' @rdname equivalence #' @examples #' \donttest{ -#' (nae <- node_automorphic_equivalence(mpn_elite_usa_advice, +#' (nae <- node_in_automorphic(mpn_elite_usa_advice, #' k = "elbow")) #' plot(nae) #' } #' @export -node_automorphic_equivalence <- function(.data, +node_in_automorphic <- function(.data, k = c("silhouette", "elbow", "strict"), cluster = c("hierarchical", "concor"), distance = c("euclidean", "maximum", "manhattan", diff --git a/R/migraph-defunct.R b/R/migraph-defunct.R index bbc290f7..2764e6a4 100644 --- a/R/migraph-defunct.R +++ b/R/migraph-defunct.R @@ -405,3 +405,4 @@ node_strong_components <- function(.data) { node_in_strong(.data) } +#' @describeIn defunct Deprecated on 2024-06-14.#' @exportnode_equivalence <- function(.data) { .Deprecated("node_in_equivalence", package = "migraph", old = "node_equivalence") node_in_equivalence(.data)}#' @describeIn defunct Deprecated on 2024-06-14.#' @exportnode_structural_equivalence <- function(.data) { .Deprecated("node_in_structural", package = "migraph", old = "node_structural_equivalence") node_in_structural(.data)}#' @describeIn defunct Deprecated on 2024-06-14.#' @exportnode_regular_equivalence <- function(.data) { .Deprecated("node_in_regular", package = "migraph", old = "node_regular_equivalence") node_in_regular(.data)}#' @describeIn defunct Deprecated on 2024-06-14.#' @exportnode_automorphic_equivalence <- function(.data) { .Deprecated("node_in_automorphic", package = "migraph", old = "node_automorphic_equivalence") node_in_automorphic(.data)} \ No newline at end of file diff --git a/man/defunct.Rd b/man/defunct.Rd index 588213b4..d468f7e5 100644 --- a/man/defunct.Rd +++ b/man/defunct.Rd @@ -49,6 +49,10 @@ \alias{node_components} \alias{node_weak_components} \alias{node_strong_components} +\alias{node_equivalence} +\alias{node_structural_equivalence} +\alias{node_regular_equivalence} +\alias{node_automorphic_equivalence} \title{Functions that have been renamed, superseded, or are no longer working} \usage{ edge_betweenness(object, normalized = TRUE) @@ -145,6 +149,13 @@ node_weak_components(.data) node_strong_components(.data) +node_equivalence(.data) + +node_structural_equivalence(.data) + +node_regular_equivalence(.data) + +node_automorphic_equivalence(.data) } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} @@ -251,5 +262,14 @@ wherever possible and update your scripts accordingly. \item \code{node_weak_components()}: Deprecated on 2024-06-14. \item \code{node_strong_components()}: Deprecated on 2024-06-14. + +\item \code{node_equivalence()}: Deprecated on 2024-06-14. + +\item \code{node_structural_equivalence()}: Deprecated on 2024-06-14. + +\item \code{node_regular_equivalence()}: Deprecated on 2024-06-14. + +\item \code{node_automorphic_equivalence()}: Deprecated on 2024-06-14. + }} \keyword{internal} diff --git a/man/equivalence.Rd b/man/equivalence.Rd index 44949237..094b0018 100644 --- a/man/equivalence.Rd +++ b/man/equivalence.Rd @@ -2,16 +2,16 @@ % Please edit documentation in R/member_equivalence.R \name{equivalence} \alias{equivalence} -\alias{node_equivalence} -\alias{node_structural_equivalence} -\alias{node_regular_equivalence} -\alias{node_automorphic_equivalence} +\alias{node_in_equivalence} +\alias{node_in_structural} +\alias{node_in_regular} +\alias{node_in_automorphic} \title{Equivalence clustering algorithms} \source{ \url{https://github.com/aslez/concoR} } \usage{ -node_equivalence( +node_in_equivalence( .data, census, k = c("silhouette", "elbow", "strict"), @@ -20,7 +20,7 @@ node_equivalence( range = 8L ) -node_structural_equivalence( +node_in_structural( .data, k = c("silhouette", "elbow", "strict"), cluster = c("hierarchical", "concor"), @@ -28,7 +28,7 @@ node_structural_equivalence( range = 8L ) -node_regular_equivalence( +node_in_regular( .data, k = c("silhouette", "elbow", "strict"), cluster = c("hierarchical", "concor"), @@ -36,7 +36,7 @@ node_regular_equivalence( range = 8L ) -node_automorphic_equivalence( +node_in_automorphic( .data, k = c("silhouette", "elbow", "strict"), cluster = c("hierarchical", "concor"), @@ -105,16 +105,16 @@ assignment. } \examples{ \donttest{ -(nse <- node_structural_equivalence(mpn_elite_usa_advice)) +(nse <- node_in_structural(mpn_elite_usa_advice)) plot(nse) } \donttest{ -(nre <- node_regular_equivalence(mpn_elite_usa_advice, +(nre <- node_in_regular(mpn_elite_usa_advice, cluster = "concor")) plot(nre) } \donttest{ -(nae <- node_automorphic_equivalence(mpn_elite_usa_advice, +(nae <- node_in_automorphic(mpn_elite_usa_advice, k = "elbow")) plot(nae) } @@ -124,6 +124,7 @@ Other memberships: \code{\link{cliques}}, \code{\link{community}}, \code{\link{components}()}, -\code{\link{core}} +\code{\link{core}}, +\code{\link{hierarchical_community}} } \concept{memberships} From 45e74708f2959b6023e93ac6bac35c73fa2861c4 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 14 Jun 2024 13:33:20 +0200 Subject: [PATCH 38/97] node_edge_betweenness(), node_fast_greedy(), node_leading_eigen(), and node_walktrap() renamed to node_in_betweenness(), node_in_greedy(), node_in_eigen(), and node_in_walktrap(), and all now retain hierarchical information so that the dendrograms can be plotted --- R/member_community.R | 132 ++++++++++++++++++++++++++++++++++ R/migraph-defunct.R | 32 +++++++++ man/hierarchical_community.Rd | 121 +++++++++++++++++++++++++++++++ pkgdown/_pkgdown.yml | 2 +- 4 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 man/hierarchical_community.Rd diff --git a/R/member_community.R b/R/member_community.R index f854ee61..ca9d4c35 100644 --- a/R/member_community.R +++ b/R/member_community.R @@ -364,3 +364,135 @@ node_leiden <- function(.data, resolution = 1){ make_node_member(out, .data) } +# Hierarchical community partitioning #### + +#' Hierarchical community partitioning algorithms +#' +#' @description +#' These functions offer algorithms for hierarchically clustering +#' networks into communities. Since all of the following are hierarchical, +#' their dendrograms can be plotted: +#' +#' - `node_in_betweenness()` is a hierarchical, decomposition algorithm +#' where edges are removed in decreasing order of the number of +#' shortest paths passing through the edge. +#' - `node_in_greedy()` is a hierarchical, agglomerative algorithm, +#' that tries to optimize modularity in a greedy manner. +#' - `node_in_eigen()` is a top-down, hierarchical algorithm. +#' - `node_in_walktrap()` is a hierarchical, agglomerative algorithm based on random walks. +#' +#' The different algorithms offer various advantages in terms of computation time, +#' availability on different types of networks, ability to maximise modularity, +#' and their logic or domain of inspiration. +#' +#' @inheritParams cohesion +#' @name hierarchical_community +#' @family memberships +NULL + +#' @rdname hierarchical_community +#' @section Edge-betweenness: +#' This is motivated by the idea that edges connecting different groups +#' are more likely to lie on multiple shortest paths when they are the +#' only option to go from one group to another. +#' This method yields good results but is very slow because of +#' the computational complexity of edge-betweenness calculations and +#' the betweenness scores have to be re-calculated after every edge removal. +#' Networks of ~700 nodes and ~3500 ties are around the upper size limit +#' that are feasible with this approach. +#' @references +#' Newman, M, and M Girvan. 2004. +#' "Finding and evaluating community structure in networks." +#' _Physical Review E_ 69: 026113. +#' @examples +#' node_in_betweenness(ison_adolescents) +#' plot(node_in_betweenness(ison_adolescents)) +#' @export +node_in_betweenness <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} + clust <- suppressWarnings(igraph::cluster_edge_betweenness( + manynet::as_igraph(.data))) + out <- clust$membership + out <- make_node_member(out, .data) + attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) + attr(out, "k") <- max(clust$membership) + out +} + +#' @rdname hierarchical_community +#' @section Fast-greedy: +#' Initially, each node is assigned a separate community. +#' Communities are then merged iteratively such that each merge +#' yields the largest increase in the current value of modularity, +#' until no further increases to the modularity are possible. +#' The method is fast and recommended as a first approximation +#' because it has no parameters to tune. +#' However, it is known to suffer from a resolution limit. +#' @references +#' Clauset, A, MEJ Newman, MEJ and C Moore. +#' "Finding community structure in very large networks." +#' @examples +#' node_in_greedy(ison_adolescents) +#' @export +node_in_greedy <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} + clust <- igraph::cluster_fast_greedy(manynet::as_igraph(.data)) + out <- clust$membership + make_node_member(out, .data) + out <- make_node_member(out, .data) + attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) + attr(out, "k") <- max(clust$membership) + out +} + +#' @rdname hierarchical_community +#' @section Leading eigenvector: +#' In each step, the network is bifurcated such that modularity increases most. +#' The splits are determined according to the leading eigenvector of the modularity matrix. +#' A stopping condition prevents tightly connected groups from being split further. +#' Note that due to the eigenvector calculations involved, +#' this algorithm will perform poorly on degenerate networks, +#' but will likely obtain a higher modularity than fast-greedy (at some cost of speed). +#' @references +#' Newman, MEJ. 2006. +#' "Finding community structure using the eigenvectors of matrices" +#' _Physical Review E_ 74:036104. +#' @examples +#' node_in_eigen(ison_adolescents) +#' @export +node_in_eigen <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} + clust <- igraph::cluster_leading_eigen(manynet::as_igraph(.data)) + out <- clust$membership + make_node_member(out, .data) + out <- make_node_member(out, .data) + attr(out, "hc") <- as.hclust(clust) + attr(out, "k") <- max(clust$membership) + out +} + +#' @rdname hierarchical_community +#' @section Walktrap: +#' The general idea is that random walks on a network are more likely to stay +#' within the same community because few edges lead outside a community. +#' By repeating random walks of 4 steps many times, +#' information about the hierarchical merging of communities is collected. +#' @param times Integer indicating number of simulations/walks used. +#' By default, `times=50`. +#' @references +#' Pons, Pascal, and Matthieu Latapy +#' "Computing communities in large networks using random walks". +#' @examples +#' node_in_walktrap(ison_adolescents) +#' @export +node_in_walktrap <- function(.data, times = 50){ + if(missing(.data)) {expect_nodes(); .data <- .G()} + clust <- igraph::cluster_walktrap(manynet::as_igraph(.data)) + out <- clust$membership + make_node_member(out, .data) + out <- make_node_member(out, .data) + attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) + attr(out, "k") <- max(clust$membership) + out +} + diff --git a/R/migraph-defunct.R b/R/migraph-defunct.R index 2764e6a4..241d8ad8 100644 --- a/R/migraph-defunct.R +++ b/R/migraph-defunct.R @@ -364,6 +364,38 @@ node_homophily <- function(object, attribute) { node_heterophily(object, attribute) } +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_edge_betweenness <- function(.data) { + .Deprecated("node_in_betweenness", package = "migraph", + old = "node_edge_betweenness") + node_in_betweenness(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_fast_greedy <- function(.data) { + .Deprecated("node_in_greedy", package = "migraph", + old = "node_fast_greedy") + node_in_greedy(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_leading_eigen <- function(.data) { + .Deprecated("node_in_eigen", package = "migraph", + old = "node_leading_eigen") + node_in_eigen(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_walktrap <- function(.data) { + .Deprecated("node_in_walktrap", package = "migraph", + old = "node_walktrap") + node_in_walktrap(.data) +} + #' @describeIn defunct Deprecated on 2024-06-14. #' @export diff --git a/man/hierarchical_community.Rd b/man/hierarchical_community.Rd new file mode 100644 index 00000000..4b0874de --- /dev/null +++ b/man/hierarchical_community.Rd @@ -0,0 +1,121 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/member_community.R +\name{hierarchical_community} +\alias{hierarchical_community} +\alias{node_in_betweenness} +\alias{node_in_greedy} +\alias{node_in_eigen} +\alias{node_in_walktrap} +\title{Hierarchical community partitioning algorithms} +\usage{ +node_in_betweenness(.data) + +node_in_greedy(.data) + +node_in_eigen(.data) + +node_in_walktrap(.data, times = 50) +} +\arguments{ +\item{.data}{An object of a \code{{manynet}}-consistent class: +\itemize{ +\item matrix (adjacency or incidence) from \code{{base}} R +\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} +\item igraph, from the \code{{igraph}} package +\item network, from the \code{{network}} package +\item tbl_graph, from the \code{{tidygraph}} package +}} + +\item{times}{Integer indicating number of simulations/walks used. +By default, \code{times=50}.} +} +\description{ +These functions offer algorithms for hierarchically clustering +networks into communities. Since all of the following are hierarchical, +their dendrograms can be plotted: +\itemize{ +\item \code{node_in_betweenness()} is a hierarchical, decomposition algorithm +where edges are removed in decreasing order of the number of +shortest paths passing through the edge. +\item \code{node_in_greedy()} is a hierarchical, agglomerative algorithm, +that tries to optimize modularity in a greedy manner. +\item \code{node_in_eigen()} is a top-down, hierarchical algorithm. +\item \code{node_in_walktrap()} is a hierarchical, agglomerative algorithm based on random walks. +} + +The different algorithms offer various advantages in terms of computation time, +availability on different types of networks, ability to maximise modularity, +and their logic or domain of inspiration. +} +\section{Edge-betweenness}{ + +This is motivated by the idea that edges connecting different groups +are more likely to lie on multiple shortest paths when they are the +only option to go from one group to another. +This method yields good results but is very slow because of +the computational complexity of edge-betweenness calculations and +the betweenness scores have to be re-calculated after every edge removal. +Networks of ~700 nodes and ~3500 ties are around the upper size limit +that are feasible with this approach. +} + +\section{Fast-greedy}{ + +Initially, each node is assigned a separate community. +Communities are then merged iteratively such that each merge +yields the largest increase in the current value of modularity, +until no further increases to the modularity are possible. +The method is fast and recommended as a first approximation +because it has no parameters to tune. +However, it is known to suffer from a resolution limit. +} + +\section{Leading eigenvector}{ + +In each step, the network is bifurcated such that modularity increases most. +The splits are determined according to the leading eigenvector of the modularity matrix. +A stopping condition prevents tightly connected groups from being split further. +Note that due to the eigenvector calculations involved, +this algorithm will perform poorly on degenerate networks, +but will likely obtain a higher modularity than fast-greedy (at some cost of speed). +} + +\section{Walktrap}{ + +The general idea is that random walks on a network are more likely to stay +within the same community because few edges lead outside a community. +By repeating random walks of 4 steps many times, +information about the hierarchical merging of communities is collected. +} + +\examples{ +node_in_betweenness(ison_adolescents) +plot(node_in_betweenness(ison_adolescents)) +node_in_greedy(ison_adolescents) +node_in_eigen(ison_adolescents) +node_in_walktrap(ison_adolescents) +} +\references{ +Newman, M, and M Girvan. 2004. +"Finding and evaluating community structure in networks." +\emph{Physical Review E} 69: 026113. + +Clauset, A, MEJ Newman, MEJ and C Moore. +"Finding community structure in very large networks." + +Newman, MEJ. 2006. +"Finding community structure using the eigenvectors of matrices" +\emph{Physical Review E} 74:036104. + +Pons, Pascal, and Matthieu Latapy +"Computing communities in large networks using random walks". +} +\seealso{ +Other memberships: +\code{\link{cliques}}, +\code{\link{community}}, +\code{\link{components}()}, +\code{\link{core}}, +\code{\link{equivalence}} +} +\concept{memberships} diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml index 882048db..bb0ed684 100644 --- a/pkgdown/_pkgdown.yml +++ b/pkgdown/_pkgdown.yml @@ -62,7 +62,7 @@ reference: in partitions within multimodal networks. They return integer vectors the length of the nodes in the network. contents: - - community + - contains("_in_") - components - equivalence - core From 3f9f3fa14d3eb18370c35cd0e70e770ade1df166 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 14 Jun 2024 13:35:43 +0200 Subject: [PATCH 39/97] node_fluid(), node_infomap(), node_kernaghinlin(), node_leiden(), node_louvain(), node_optimal(), and node_spinglass() renamed to node_in_fluid(), node_in_infomap(), node_kernaghinlin(), node_in_leiden(), node_in_louvain(), node_in_optimal(), and node_in_spinglass() --- NAMESPACE | 11 +++ R/member_community.R | 163 +++++++------------------------------------ R/migraph-defunct.R | 87 ++++++++++++++++++++++- man/community.Rd | 147 +++++++++----------------------------- man/defunct.Rd | 54 ++++++++++++++ 5 files changed, 210 insertions(+), 252 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index f1a11571..0262d918 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -164,13 +164,24 @@ export(node_heterophily) export(node_hierarchy) export(node_homophily) export(node_in_automorphic) +export(node_in_betweenness) export(node_in_component) export(node_in_core) +export(node_in_eigen) export(node_in_equivalence) +export(node_in_fluid) +export(node_in_greedy) +export(node_in_infomap) +export(node_in_kernighanlin) +export(node_in_leiden) +export(node_in_louvain) +export(node_in_optimal) export(node_in_regular) export(node_in_roulette) +export(node_in_spinglass) export(node_in_strong) export(node_in_structural) +export(node_in_walktrap) export(node_in_weak) export(node_indegree) export(node_induced) diff --git a/R/member_community.R b/R/member_community.R index ca9d4c35..197c6d7b 100644 --- a/R/member_community.R +++ b/R/member_community.R @@ -1,28 +1,23 @@ -#' Community partitioning algorithms +# Non-hierarchical community partitioning #### + +#' Non-hierarchical community partitioning algorithms #' #' @description -#' These functions offer different algorithms useful for partitioning +#' These functions offer algorithms for partitioning #' networks into sets of communities: #' -#' - `node_optimal()` is a problem-solving algorithm that seeks to maximise +#' - `node_in_optimal()` is a problem-solving algorithm that seeks to maximise #' modularity over all possible partitions. -#' - `node_kernaghinlin()` is a greedy, iterative, deterministic +#' - `node_in_kernaghinlin()` is a greedy, iterative, deterministic #' partitioning algorithm that results in two equally-sized communities. -#' - `node_edge_betweenness()` is a hierarchical, decomposition algorithm -#' where edges are removed in decreasing order of the number of -#' shortest paths passing through the edge. -#' - `node_fast_greedy()` is a hierarchical, agglomerative algorithm, -#' that tries to optimize modularity in a greedy manner. -#' - `node_leading_eigen()` is a top-down, hierarchical algorithm. -#' - `node_walktrap()` is a hierarchical, agglomerative algorithm based on random walks. -#' - `node_infomap()` is a hierarchical algorithm based on the information in random walks. -#' - `node_spinglass()` is a greedy, iterative, probabilistic algorithm, +#' - `node_in_infomap()` is an algorithm based on the information in random walks. +#' - `node_in_spinglass()` is a greedy, iterative, probabilistic algorithm, #' based on analogy to model from statistical physics. -#' - `node_fluid()` is a propogation-based partitioning algorithm, +#' - `node_in_fluid()` is a propogation-based partitioning algorithm, #' based on analogy to model from fluid dynamics. -#' - `node_louvain()` is an agglomerative multilevel algorithm that seeks to maximise +#' - `node_in_louvain()` is an agglomerative multilevel algorithm that seeks to maximise #' modularity over all possible partitions. -#' - `node_leiden()` is an agglomerative multilevel algorithm that seeks to maximise +#' - `node_in_leiden()` is an agglomerative multilevel algorithm that seeks to maximise #' the Constant Potts Model over all possible partitions. #' #' The different algorithms offer various advantages in terms of computation time, @@ -45,9 +40,9 @@ NULL #' "On Modularity Clustering", #' _IEEE Transactions on Knowledge and Data Engineering_ 20(2):172-188. #' @examples -#' node_optimal(ison_adolescents) +#' node_in_optimal(ison_adolescents) #' @export -node_optimal <- function(.data){ +node_in_optimal <- function(.data){ if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::cluster_optimal(manynet::as_igraph(.data) )$membership @@ -61,10 +56,10 @@ node_optimal <- function(.data){ #' _The Bell System Technical Journal_ 49(2): 291-307. #' \doi{10.1002/j.1538-7305.1970.tb01770.x} #' @examples -#' node_kernighanlin(ison_adolescents) -#' node_kernighanlin(ison_southern_women) +#' node_in_kernighanlin(ison_adolescents) +#' node_in_kernighanlin(ison_southern_women) #' @export -node_kernighanlin <- function(.data){ +node_in_kernighanlin <- function(.data){ if(missing(.data)) {expect_nodes(); .data <- .G()} # assign groups arbitrarily n <- manynet::network_nodes(.data) @@ -110,112 +105,6 @@ node_kernighanlin <- function(.data){ make_node_member(out, .data) } -#' @rdname community -#' @section Edge-betweenness: -#' This is motivated by the idea that edges connecting different groups -#' are more likely to lie on multiple shortest paths when they are the -#' only option to go from one group to another. -#' This method yields good results but is very slow because of -#' the computational complexity of edge-betweenness calculations and -#' the betweenness scores have to be re-calculated after every edge removal. -#' Networks of ~700 nodes and ~3500 ties are around the upper size limit -#' that are feasible with this approach. -#' @references -#' Newman, M, and M Girvan. 2004. -#' "Finding and evaluating community structure in networks." -#' _Physical Review E_ 69: 026113. -#' @examples -#' node_edge_betweenness(ison_adolescents) -#' plot(node_edge_betweenness(ison_adolescents)) -#' @export -node_edge_betweenness <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - clust <- suppressWarnings(igraph::cluster_edge_betweenness( - manynet::as_igraph(.data))) - out <- clust$membership - out <- make_node_member(out, .data) - attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) - attr(out, "k") <- max(clust$membership) - out -} - -#' @rdname community -#' @section Fast-greedy: -#' Initially, each node is assigned a separate community. -#' Communities are then merged iteratively such that each merge -#' yields the largest increase in the current value of modularity, -#' until no further increases to the modularity are possible. -#' The method is fast and recommended as a first approximation -#' because it has no parameters to tune. -#' However, it is known to suffer from a resolution limit. -#' @references -#' Clauset, A, MEJ Newman, MEJ and C Moore. -#' "Finding community structure in very large networks." -#' @examples -#' node_fast_greedy(ison_adolescents) -#' @export -node_fast_greedy <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - clust <- igraph::cluster_fast_greedy(manynet::as_igraph(.data)) - out <- clust$membership - make_node_member(out, .data) - out <- make_node_member(out, .data) - attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) - attr(out, "k") <- max(clust$membership) - out -} - -#' @rdname community -#' @section Leading eigenvector: -#' In each step, the network is bifurcated such that modularity increases most. -#' The splits are determined according to the leading eigenvector of the modularity matrix. -#' A stopping condition prevents tightly connected groups from being split further. -#' Note that due to the eigenvector calculations involved, -#' this algorithm will perform poorly on degenerate networks, -#' but will likely obtain a higher modularity than fast-greedy (at some cost of speed). -#' @references -#' Newman, MEJ. 2006. -#' "Finding community structure using the eigenvectors of matrices" -#' _Physical Review E_ 74:036104. -#' @examples -#' node_leading_eigen(ison_adolescents) -#' @export -node_leading_eigen <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - clust <- igraph::cluster_leading_eigen(manynet::as_igraph(.data)) - out <- clust$membership - make_node_member(out, .data) - out <- make_node_member(out, .data) - attr(out, "hc") <- as.hclust(clust) - attr(out, "k") <- max(clust$membership) - out -} - -#' @rdname community -#' @section Walktrap: -#' The general idea is that random walks on a network are more likely to stay -#' within the same community because few edges lead outside a community. -#' By repeating random walks of 4 steps many times, -#' information about the hierarchical merging of communities is collected. -#' @param times Integer indicating number of simulations/walks used. -#' By default, `times=50`. -#' @references -#' Pons, Pascal, and Matthieu Latapy -#' "Computing communities in large networks using random walks". -#' @examples -#' node_walktrap(ison_adolescents) -#' @export -node_walktrap <- function(.data, times = 50){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - clust <- igraph::cluster_walktrap(manynet::as_igraph(.data)) - out <- clust$membership - make_node_member(out, .data) - out <- make_node_member(out, .data) - attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) - attr(out, "k") <- max(clust$membership) - out -} - #' @rdname community #' @section Infomap: #' Motivated by information theoretic principles, this algorithm tries to build @@ -232,9 +121,9 @@ node_walktrap <- function(.data, times = 50){ #' _Eur. Phys. J. Special Topics_ 178: 13. #' \doi{10.1140/epjst/e2010-01179-1} #' @examples -#' node_infomap(ison_adolescents) +#' node_in_infomap(ison_adolescents) #' @export -node_infomap <- function(.data, times = 50){ +node_in_infomap <- function(.data, times = 50){ if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::cluster_infomap(manynet::as_igraph(.data), nb.trials = times @@ -267,9 +156,9 @@ node_infomap <- function(.data, times = 50){ #' Traag, VA, and Jeroen Bruggeman. 2008. #' "Community detection in networks with positive and negative links". #' @examples -#' node_spinglass(ison_adolescents) +#' node_in_spinglass(ison_adolescents) #' @export -node_spinglass <- function(.data, max_k = 200, resolution = 1){ +node_in_spinglass <- function(.data, max_k = 200, resolution = 1){ if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::cluster_spinglass(manynet::as_igraph(.data), spins = max_k, gamma = resolution, @@ -292,9 +181,9 @@ node_spinglass <- function(.data, max_k = 200, resolution = 1){ #' Springer, 689: 229. #' \doi{10.1007/978-3-319-72150-7_19} #' @examples -#' node_fluid(ison_adolescents) +#' node_in_fluid(ison_adolescents) #' @export -node_fluid <- function(.data) { +node_in_fluid <- function(.data) { if(missing(.data)) {expect_nodes(); .data <- .G()} .data <- as_igraph(.data) mods <- vapply(seq.int(manynet::network_nodes(.data)), function(x) @@ -319,9 +208,9 @@ node_fluid <- function(.data) { #' "Fast unfolding of communities in large networks", #' _J. Stat. Mech._ P10008. #' @examples -#' node_louvain(ison_adolescents) +#' node_in_louvain(ison_adolescents) #' @export -node_louvain <- function(.data, resolution = 1){ +node_in_louvain <- function(.data, resolution = 1){ if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::cluster_louvain(manynet::as_igraph(.data), resolution = resolution @@ -350,9 +239,9 @@ node_louvain <- function(.data, resolution = 1){ #' _Scientific Reports_, 9(1):5233. #' \doi{10.1038/s41598-019-41695-z} #' @examples -#' node_leiden(ison_adolescents) +#' node_in_leiden(ison_adolescents) #' @export -node_leiden <- function(.data, resolution = 1){ +node_in_leiden <- function(.data, resolution = 1){ if(missing(.data)) {expect_nodes(); .data <- .G()} if(manynet::is_weighted(.data)){ # Traag resolution default n <- manynet::network_nodes(.data) diff --git a/R/migraph-defunct.R b/R/migraph-defunct.R index 241d8ad8..7b61562c 100644 --- a/R/migraph-defunct.R +++ b/R/migraph-defunct.R @@ -364,6 +364,22 @@ node_homophily <- function(object, attribute) { node_heterophily(object, attribute) } +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_optimal <- function(.data) { + .Deprecated("node_in_optimal", package = "migraph", + old = "node_optimal") + node_in_optimal(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_kernighanlin <- function(.data) { + .Deprecated("node_in_kernaghinlin", package = "migraph", + old = "node_kernighanlin") + node_in_kernaghinlin(.data) +} + #' @describeIn defunct Deprecated on 2024-06-14. #' @export node_edge_betweenness <- function(.data) { @@ -396,6 +412,45 @@ node_walktrap <- function(.data) { node_in_walktrap(.data) } +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_infomap <- function(.data) { + .Deprecated("node_in_infomap", package = "migraph", + old = "node_infomap") + node_in_infomap(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_spinglass <- function(.data) { + .Deprecated("node_in_spinglass", package = "migraph", + old = "node_spinglass") + node_in_spinglass(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_fluid <- function(.data) { + .Deprecated("node_in_fluid", package = "migraph", + old = "node_fluid") + node_in_fluid(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_leiden <- function(.data) { + .Deprecated("node_in_leiden", package = "migraph", + old = "node_leiden") + node_in_leiden(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_louvain <- function(.data) { + .Deprecated("node_in_louvain", package = "migraph", + old = "node_louvain") + node_in_louvain(.data) +} #' @describeIn defunct Deprecated on 2024-06-14. #' @export @@ -437,4 +492,34 @@ node_strong_components <- function(.data) { node_in_strong(.data) } -#' @describeIn defunct Deprecated on 2024-06-14.#' @exportnode_equivalence <- function(.data) { .Deprecated("node_in_equivalence", package = "migraph", old = "node_equivalence") node_in_equivalence(.data)}#' @describeIn defunct Deprecated on 2024-06-14.#' @exportnode_structural_equivalence <- function(.data) { .Deprecated("node_in_structural", package = "migraph", old = "node_structural_equivalence") node_in_structural(.data)}#' @describeIn defunct Deprecated on 2024-06-14.#' @exportnode_regular_equivalence <- function(.data) { .Deprecated("node_in_regular", package = "migraph", old = "node_regular_equivalence") node_in_regular(.data)}#' @describeIn defunct Deprecated on 2024-06-14.#' @exportnode_automorphic_equivalence <- function(.data) { .Deprecated("node_in_automorphic", package = "migraph", old = "node_automorphic_equivalence") node_in_automorphic(.data)} \ No newline at end of file +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_equivalence <- function(.data) { + .Deprecated("node_in_equivalence", package = "migraph", + old = "node_equivalence") + node_in_equivalence(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_structural_equivalence <- function(.data) { + .Deprecated("node_in_structural", package = "migraph", + old = "node_structural_equivalence") + node_in_structural(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_regular_equivalence <- function(.data) { + .Deprecated("node_in_regular", package = "migraph", + old = "node_regular_equivalence") + node_in_regular(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-14. +#' @export +node_automorphic_equivalence <- function(.data) { + .Deprecated("node_in_automorphic", package = "migraph", + old = "node_automorphic_equivalence") + node_in_automorphic(.data) +} \ No newline at end of file diff --git a/man/community.Rd b/man/community.Rd index f001f875..34321d24 100644 --- a/man/community.Rd +++ b/man/community.Rd @@ -2,40 +2,28 @@ % Please edit documentation in R/member_community.R \name{community} \alias{community} -\alias{node_optimal} -\alias{node_kernighanlin} -\alias{node_edge_betweenness} -\alias{node_fast_greedy} -\alias{node_leading_eigen} -\alias{node_walktrap} -\alias{node_infomap} -\alias{node_spinglass} -\alias{node_fluid} -\alias{node_louvain} -\alias{node_leiden} -\title{Community partitioning algorithms} +\alias{node_in_optimal} +\alias{node_in_kernighanlin} +\alias{node_in_infomap} +\alias{node_in_spinglass} +\alias{node_in_fluid} +\alias{node_in_louvain} +\alias{node_in_leiden} +\title{Non-hierarchical community partitioning algorithms} \usage{ -node_optimal(.data) +node_in_optimal(.data) -node_kernighanlin(.data) +node_in_kernighanlin(.data) -node_edge_betweenness(.data) +node_in_infomap(.data, times = 50) -node_fast_greedy(.data) +node_in_spinglass(.data, max_k = 200, resolution = 1) -node_leading_eigen(.data) +node_in_fluid(.data) -node_walktrap(.data, times = 50) +node_in_louvain(.data, resolution = 1) -node_infomap(.data, times = 50) - -node_spinglass(.data, max_k = 200, resolution = 1) - -node_fluid(.data) - -node_louvain(.data, resolution = 1) - -node_leiden(.data, resolution = 1) +node_in_leiden(.data, resolution = 1) } \arguments{ \item{.data}{An object of a \code{{manynet}}-consistent class: @@ -47,9 +35,6 @@ node_leiden(.data, resolution = 1) \item tbl_graph, from the \code{{tidygraph}} package }} -\item{times}{Integer indicating number of simulations/walks used. -By default, \code{times=50}.} - \item{max_k}{Integer constant, the number of spins to use as an upper limit of communities to be found. Some sets can be empty at the end.} @@ -59,28 +44,21 @@ Smaller values make existing ties more important, and larger values make missing ties more important.} } \description{ -These functions offer different algorithms useful for partitioning +These functions offer algorithms for partitioning networks into sets of communities: \itemize{ -\item \code{node_optimal()} is a problem-solving algorithm that seeks to maximise +\item \code{node_in_optimal()} is a problem-solving algorithm that seeks to maximise modularity over all possible partitions. -\item \code{node_kernaghinlin()} is a greedy, iterative, deterministic +\item \code{node_in_kernaghinlin()} is a greedy, iterative, deterministic partitioning algorithm that results in two equally-sized communities. -\item \code{node_edge_betweenness()} is a hierarchical, decomposition algorithm -where edges are removed in decreasing order of the number of -shortest paths passing through the edge. -\item \code{node_fast_greedy()} is a hierarchical, agglomerative algorithm, -that tries to optimize modularity in a greedy manner. -\item \code{node_leading_eigen()} is a top-down, hierarchical algorithm. -\item \code{node_walktrap()} is a hierarchical, agglomerative algorithm based on random walks. -\item \code{node_infomap()} is a hierarchical algorithm based on the information in random walks. -\item \code{node_spinglass()} is a greedy, iterative, probabilistic algorithm, +\item \code{node_in_infomap()} is an algorithm based on the information in random walks. +\item \code{node_in_spinglass()} is a greedy, iterative, probabilistic algorithm, based on analogy to model from statistical physics. -\item \code{node_fluid()} is a propogation-based partitioning algorithm, +\item \code{node_in_fluid()} is a propogation-based partitioning algorithm, based on analogy to model from fluid dynamics. -\item \code{node_louvain()} is an agglomerative multilevel algorithm that seeks to maximise +\item \code{node_in_louvain()} is an agglomerative multilevel algorithm that seeks to maximise modularity over all possible partitions. -\item \code{node_leiden()} is an agglomerative multilevel algorithm that seeks to maximise +\item \code{node_in_leiden()} is an agglomerative multilevel algorithm that seeks to maximise the Constant Potts Model over all possible partitions. } @@ -96,47 +74,6 @@ Note that this is an NP-complete problem with exponential time complexity. The guidance in the igraph package is networks of <50-200 nodes is probably fine. } -\section{Edge-betweenness}{ - -This is motivated by the idea that edges connecting different groups -are more likely to lie on multiple shortest paths when they are the -only option to go from one group to another. -This method yields good results but is very slow because of -the computational complexity of edge-betweenness calculations and -the betweenness scores have to be re-calculated after every edge removal. -Networks of ~700 nodes and ~3500 ties are around the upper size limit -that are feasible with this approach. -} - -\section{Fast-greedy}{ - -Initially, each node is assigned a separate community. -Communities are then merged iteratively such that each merge -yields the largest increase in the current value of modularity, -until no further increases to the modularity are possible. -The method is fast and recommended as a first approximation -because it has no parameters to tune. -However, it is known to suffer from a resolution limit. -} - -\section{Leading eigenvector}{ - -In each step, the network is bifurcated such that modularity increases most. -The splits are determined according to the leading eigenvector of the modularity matrix. -A stopping condition prevents tightly connected groups from being split further. -Note that due to the eigenvector calculations involved, -this algorithm will perform poorly on degenerate networks, -but will likely obtain a higher modularity than fast-greedy (at some cost of speed). -} - -\section{Walktrap}{ - -The general idea is that random walks on a network are more likely to stay -within the same community because few edges lead outside a community. -By repeating random walks of 4 steps many times, -information about the hierarchical merging of communities is collected. -} - \section{Infomap}{ Motivated by information theoretic principles, this algorithm tries to build @@ -193,19 +130,14 @@ and \eqn{\delta(\sigma_i, \sigma_j) = 1} if and only if } \examples{ -node_optimal(ison_adolescents) -node_kernighanlin(ison_adolescents) -node_kernighanlin(ison_southern_women) -node_edge_betweenness(ison_adolescents) -plot(node_edge_betweenness(ison_adolescents)) -node_fast_greedy(ison_adolescents) -node_leading_eigen(ison_adolescents) -node_walktrap(ison_adolescents) -node_infomap(ison_adolescents) -node_spinglass(ison_adolescents) -node_fluid(ison_adolescents) -node_louvain(ison_adolescents) -node_leiden(ison_adolescents) +node_in_optimal(ison_adolescents) +node_in_kernighanlin(ison_adolescents) +node_in_kernighanlin(ison_southern_women) +node_in_infomap(ison_adolescents) +node_in_spinglass(ison_adolescents) +node_in_fluid(ison_adolescents) +node_in_louvain(ison_adolescents) +node_in_leiden(ison_adolescents) } \references{ Brandes, Ulrik, Daniel Delling, Marco Gaertler, Robert Gorke, Martin Hoefer, Zoran Nikoloski, Dorothea Wagner. 2008. @@ -217,20 +149,6 @@ Kernighan, Brian W., and Shen Lin. 1970. \emph{The Bell System Technical Journal} 49(2): 291-307. \doi{10.1002/j.1538-7305.1970.tb01770.x} -Newman, M, and M Girvan. 2004. -"Finding and evaluating community structure in networks." -\emph{Physical Review E} 69: 026113. - -Clauset, A, MEJ Newman, MEJ and C Moore. -"Finding community structure in very large networks." - -Newman, MEJ. 2006. -"Finding community structure using the eigenvectors of matrices" -\emph{Physical Review E} 74:036104. - -Pons, Pascal, and Matthieu Latapy -"Computing communities in large networks using random walks". - Rosvall, M, and C. T. Bergstrom. 2008. "Maps of information flow reveal community structure in complex networks", \emph{PNAS} 105:1118. @@ -269,6 +187,7 @@ Other memberships: \code{\link{cliques}}, \code{\link{components}()}, \code{\link{core}}, -\code{\link{equivalence}} +\code{\link{equivalence}}, +\code{\link{hierarchical_community}} } \concept{memberships} diff --git a/man/defunct.Rd b/man/defunct.Rd index d468f7e5..f79a4f20 100644 --- a/man/defunct.Rd +++ b/man/defunct.Rd @@ -44,6 +44,17 @@ \alias{graph_smallworld} \alias{network_homophily} \alias{node_homophily} +\alias{node_optimal} +\alias{node_kernighanlin} +\alias{node_edge_betweenness} +\alias{node_fast_greedy} +\alias{node_leading_eigen} +\alias{node_walktrap} +\alias{node_infomap} +\alias{node_spinglass} +\alias{node_fluid} +\alias{node_leiden} +\alias{node_louvain} \alias{node_core} \alias{node_roulette} \alias{node_components} @@ -139,6 +150,28 @@ network_homophily(object, attribute) node_homophily(object, attribute) +node_optimal(.data) + +node_kernighanlin(.data) + +node_edge_betweenness(.data) + +node_fast_greedy(.data) + +node_leading_eigen(.data) + +node_walktrap(.data) + +node_infomap(.data) + +node_spinglass(.data) + +node_fluid(.data) + +node_leiden(.data) + +node_louvain(.data) + node_core(.data) node_roulette(.data) @@ -252,6 +285,27 @@ wherever possible and update your scripts accordingly. \item \code{node_homophily()}: Deprecated on 2022-09-25. +\item \code{node_optimal()}: Deprecated on 2024-06-14. + +\item \code{node_kernighanlin()}: Deprecated on 2024-06-14. + +\item \code{node_edge_betweenness()}: Deprecated on 2024-06-14. + +\item \code{node_fast_greedy()}: Deprecated on 2024-06-14. + +\item \code{node_leading_eigen()}: Deprecated on 2024-06-14. + +\item \code{node_walktrap()}: Deprecated on 2024-06-14. + +\item \code{node_infomap()}: Deprecated on 2024-06-14. + +\item \code{node_spinglass()}: Deprecated on 2024-06-14. + +\item \code{node_fluid()}: Deprecated on 2024-06-14. + +\item \code{node_leiden()}: Deprecated on 2024-06-14. + +\item \code{node_louvain()}: Deprecated on 2024-06-14. \item \code{node_core()}: Deprecated on 2024-06-14. From dffdb59317974f7dd819b398e5365271c09b9bdc Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 16 Jun 2024 11:18:51 +0200 Subject: [PATCH 40/97] Added parallelisation to testthat tests --- DESCRIPTION | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DESCRIPTION b/DESCRIPTION index 41d1e41e..2a9168a4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -68,3 +68,7 @@ Authors@R: comment = c(ORCID = "0000-0001-5943-9059")) ) Roxygen: list(markdown = TRUE, roclets = c("namespace", "rd")) +Config/testthat/parallel: true +Config/testthat/edition: 3 +Config/testthat/start-first: helper-functions + From 9524ff7e236b20b919feeaf3556e45a3b148eeac Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 16 Jun 2024 11:19:52 +0200 Subject: [PATCH 41/97] node_exposure() now sums tie weights where passed a weighted network --- R/measure_diffusion.R | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/R/measure_diffusion.R b/R/measure_diffusion.R index 835b8ff2..dc49f32a 100644 --- a/R/measure_diffusion.R +++ b/R/measure_diffusion.R @@ -384,12 +384,23 @@ node_exposure <- function(.data, mark, time = 0){ mark <- manynet::node_is_infected(.data, time = time) .data <- attr(.data, "network") } - if(is.logical(mark)) mark <- which(mark) - contacts <- unlist(lapply(igraph::neighborhood(.data, nodes = mark), - function(x) setdiff(x, mark))) - # count exposures for each node: - tabcontact <- table(contacts) - out <- rep(0, manynet::network_nodes(.data)) - out[as.numeric(names(tabcontact))] <- unname(tabcontact) + .data <- manynet::as_tidygraph(.data) + if(manynet::is_weighted(.data)){ + if(is.numeric(mark)){ + mk <- rep(FALSE, manynet::network_nodes(.data)) + mk[mark] <- TRUE + } + out <- manynet::as_matrix(.data) + out <- colSums(out * matrix(mk, nrow(out), ncol(out)) * + matrix(!mk, nrow(out), ncol(out), byrow = TRUE)) + } else { + if(is.logical(mark)) mark <- which(mark) + contacts <- unlist(lapply(igraph::neighborhood(.data, nodes = mark), + function(x) setdiff(x, mark))) + # count exposures for each node: + tabcontact <- table(contacts) + out <- rep(0, manynet::network_nodes(.data)) + out[as.numeric(names(tabcontact))] <- unname(tabcontact) + } make_node_measure(out, .data) } From c5f93152f1957b38510d2d93147ed6b744faa588 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 17 Jun 2024 07:22:29 +0200 Subject: [PATCH 42/97] node_kernaghinlin() renamed to node_in_partition() --- NAMESPACE | 2 +- R/measure_features.R | 4 ++-- R/member_community.R | 6 +++--- R/migraph-defunct.R | 4 ++-- man/community.Rd | 8 ++++---- tests/testthat/test-measure_features.R | 4 ++-- tests/testthat/test-member_community.R | 18 +++++++++--------- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 0262d918..ee7bebfa 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -172,10 +172,10 @@ export(node_in_equivalence) export(node_in_fluid) export(node_in_greedy) export(node_in_infomap) -export(node_in_kernighanlin) export(node_in_leiden) export(node_in_louvain) export(node_in_optimal) +export(node_in_partition) export(node_in_regular) export(node_in_roulette) export(node_in_spinglass) diff --git a/R/measure_features.R b/R/measure_features.R index ac3e0709..3c32b09f 100644 --- a/R/measure_features.R +++ b/R/measure_features.R @@ -107,7 +107,7 @@ network_factions <- function(.data, membership = NULL){ if(missing(.data)) {expect_nodes(); .data <- .G()} if(is.null(membership)) - membership <- node_kernighanlin(.data) + membership <- node_in_partition(.data) out <- stats::cor(c(manynet::as_matrix(.data)), c(manynet::as_matrix(manynet::create_components(.data, membership = membership)))) @@ -150,7 +150,7 @@ network_modularity <- function(.data, resolution = 1){ if(missing(.data)) {expect_nodes(); .data <- .G()} if(is.null(membership)) - membership <- node_kernighanlin(.data) + membership <- node_in_partition(.data) if(!is.numeric(membership)) membership <- as.numeric(as.factor(membership)) if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) if(manynet::is_twomode(.data)){ diff --git a/R/member_community.R b/R/member_community.R index 197c6d7b..02965107 100644 --- a/R/member_community.R +++ b/R/member_community.R @@ -56,10 +56,10 @@ node_in_optimal <- function(.data){ #' _The Bell System Technical Journal_ 49(2): 291-307. #' \doi{10.1002/j.1538-7305.1970.tb01770.x} #' @examples -#' node_in_kernighanlin(ison_adolescents) -#' node_in_kernighanlin(ison_southern_women) +#' node_in_partition(ison_adolescents) +#' node_in_partition(ison_southern_women) #' @export -node_in_kernighanlin <- function(.data){ +node_in_partition <- function(.data){ if(missing(.data)) {expect_nodes(); .data <- .G()} # assign groups arbitrarily n <- manynet::network_nodes(.data) diff --git a/R/migraph-defunct.R b/R/migraph-defunct.R index 7b61562c..fc97f994 100644 --- a/R/migraph-defunct.R +++ b/R/migraph-defunct.R @@ -375,9 +375,9 @@ node_optimal <- function(.data) { #' @describeIn defunct Deprecated on 2024-06-14. #' @export node_kernighanlin <- function(.data) { - .Deprecated("node_in_kernaghinlin", package = "migraph", + .Deprecated("node_in_partition", package = "migraph", old = "node_kernighanlin") - node_in_kernaghinlin(.data) + node_in_partition(.data) } #' @describeIn defunct Deprecated on 2024-06-14. diff --git a/man/community.Rd b/man/community.Rd index 34321d24..f43b2463 100644 --- a/man/community.Rd +++ b/man/community.Rd @@ -3,7 +3,7 @@ \name{community} \alias{community} \alias{node_in_optimal} -\alias{node_in_kernighanlin} +\alias{node_in_partition} \alias{node_in_infomap} \alias{node_in_spinglass} \alias{node_in_fluid} @@ -13,7 +13,7 @@ \usage{ node_in_optimal(.data) -node_in_kernighanlin(.data) +node_in_partition(.data) node_in_infomap(.data, times = 50) @@ -131,8 +131,8 @@ and \eqn{\delta(\sigma_i, \sigma_j) = 1} if and only if \examples{ node_in_optimal(ison_adolescents) -node_in_kernighanlin(ison_adolescents) -node_in_kernighanlin(ison_southern_women) +node_in_partition(ison_adolescents) +node_in_partition(ison_southern_women) node_in_infomap(ison_adolescents) node_in_spinglass(ison_adolescents) node_in_fluid(ison_adolescents) diff --git a/tests/testthat/test-measure_features.R b/tests/testthat/test-measure_features.R index b41a04f6..8b4f4462 100644 --- a/tests/testthat/test-measure_features.R +++ b/tests/testthat/test-measure_features.R @@ -14,9 +14,9 @@ test_that("network_balance works", { test_that("network_modularity works for two mode networks", { expect_s3_class(network_modularity(ison_southern_women, - node_kernighanlin(ison_southern_women)), "network_measure") + node_in_partition(ison_southern_women)), "network_measure") expect_length(network_modularity(ison_southern_women, - node_kernighanlin(ison_southern_women)), 1) + node_in_partition(ison_southern_women)), 1) }) test_that("network_core works", { diff --git a/tests/testthat/test-member_community.R b/tests/testthat/test-member_community.R index 0975866b..d59e33aa 100644 --- a/tests/testthat/test-member_community.R +++ b/tests/testthat/test-member_community.R @@ -1,24 +1,24 @@ test_that("node_kernighanlin algorithm works", { - expect_s3_class(node_kernighanlin(mpn_elite_mex), "node_member") - expect_length(node_kernighanlin(mpn_elite_mex), + expect_s3_class(node_in_partition(mpn_elite_mex), "node_member") + expect_length(node_in_partition(mpn_elite_mex), network_nodes(mpn_elite_mex)) - expect_false(any(node_kernighanlin(mpn_elite_mex) > "B")) + expect_false(any(node_in_partition(mpn_elite_mex) > "B")) }) test_that("node_edge_betweenness algorithm works", { - expect_s3_class(node_edge_betweenness(mpn_elite_mex), "node_member") - expect_length(node_edge_betweenness(mpn_elite_mex), + expect_s3_class(node_in_betweenness(mpn_elite_mex), "node_member") + expect_length(node_in_betweenness(mpn_elite_mex), network_nodes(mpn_elite_mex)) }) test_that("node_fast_greedy algorithm works", { - expect_s3_class(node_fast_greedy(ison_southern_women), "node_member") - expect_length(node_fast_greedy(ison_southern_women), + expect_s3_class(node_in_greedy(ison_southern_women), "node_member") + expect_length(node_in_greedy(ison_southern_women), network_nodes(ison_southern_women)) }) test_that("node_walktrap algorithm works", { - expect_s3_class(node_walktrap(ison_southern_women), "node_member") - expect_length(node_walktrap(ison_southern_women), + expect_s3_class(node_in_walktrap(ison_southern_women), "node_member") + expect_length(node_in_walktrap(ison_southern_women), network_nodes(ison_southern_women)) }) From ffa25c5a05b36c2dc6f6b201450476d851b72367 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 17 Jun 2024 07:24:11 +0200 Subject: [PATCH 43/97] Fixed _in_ documentation --- R/measure_features.R | 2 +- R/member_core.R | 2 +- R/member_equivalence.R | 6 +-- man/core.Rd | 2 +- tests/testthat/test-member_equivalence.R | 47 +++++++++--------------- 5 files changed, 24 insertions(+), 35 deletions(-) diff --git a/R/measure_features.R b/R/measure_features.R index 3c32b09f..2f32f1b5 100644 --- a/R/measure_features.R +++ b/R/measure_features.R @@ -46,7 +46,7 @@ NULL network_core <- function(.data, membership = NULL){ if(missing(.data)) {expect_nodes(); .data <- .G()} - if(is.null(membership)) membership <- node_core(.data) + if(is.null(membership)) membership <- node_in_core(.data) out <- stats::cor(c(manynet::as_matrix(.data)), c(manynet::as_matrix(manynet::create_core(.data, membership = membership)))) diff --git a/R/member_core.R b/R/member_core.R index c3db1a4c..c8bab2c0 100644 --- a/R/member_core.R +++ b/R/member_core.R @@ -41,7 +41,7 @@ NULL #' #mpn_elite_usa_advice %>% as_tidygraph %>% #' # mutate(corep = node_in_core(mpn_elite_usa_advice)) %>% #' # autographr(node_color = "corep") -#' network_in_core(mpn_elite_usa_advice) +#' node_in_core(mpn_elite_usa_advice) #' @export node_in_core <- function(.data, method = c("degree", "eigenvector")){ if(missing(.data)) {expect_nodes(); .data <- .G()} diff --git a/R/member_equivalence.R b/R/member_equivalence.R index 146af71f..78a3472a 100644 --- a/R/member_equivalence.R +++ b/R/member_equivalence.R @@ -93,7 +93,7 @@ node_in_structural <- function(.data, if(any(colSums(t(mat))==0)){ mat <- cbind(mat, (colSums(t(mat))==0)) } - node_equivalence(.data, mat, + node_in_equivalence(.data, mat, k = k, cluster = cluster, distance = distance, range = range) } @@ -118,7 +118,7 @@ node_in_regular <- function(.data, mat <- node_triad_census(.data) } if(any(colSums(mat) == 0)) mat <- mat[,-which(colSums(mat) == 0)] - node_equivalence(.data, mat, + node_in_equivalence(.data, mat, k = k, cluster = cluster, distance = distance, range = range) } @@ -138,6 +138,6 @@ node_in_automorphic <- function(.data, range = 8L){ if(missing(.data)) {expect_nodes(); .data <- .G()} mat <- node_path_census(.data) - node_equivalence(.data, mat, + node_in_equivalence(.data, mat, k = k, cluster = cluster, distance = distance, range = range) } diff --git a/man/core.Rd b/man/core.Rd index a6ecc033..c2e07bd4 100644 --- a/man/core.Rd +++ b/man/core.Rd @@ -52,7 +52,7 @@ it ignores ties between these blocks. #mpn_elite_usa_advice \%>\% as_tidygraph \%>\% # mutate(corep = node_in_core(mpn_elite_usa_advice)) \%>\% # autographr(node_color = "corep") -network_in_core(mpn_elite_usa_advice) +node_in_core(mpn_elite_usa_advice) node_coreness(ison_adolescents) } \references{ diff --git a/tests/testthat/test-member_equivalence.R b/tests/testthat/test-member_equivalence.R index 308326f0..0f32016e 100644 --- a/tests/testthat/test-member_equivalence.R +++ b/tests/testthat/test-member_equivalence.R @@ -1,36 +1,25 @@ # # Equivalence clustering tests test_that("equivalence clustering returns the right class", { - expect_s3_class(node_structural_equivalence(ison_adolescents, "strict", "hier"), "node_member") - expect_s3_class(node_structural_equivalence(ison_adolescents, "elbow", "hier"), "node_member") - expect_s3_class(node_structural_equivalence(ison_adolescents, "elbow", "concor"), "node_member") - expect_s3_class(node_regular_equivalence(mpn_elite_mex), "node_member") - expect_s3_class(node_automorphic_equivalence(mpn_elite_mex), "node_member") + expect_s3_class(node_in_structural(ison_adolescents, "strict", "hier"), "node_member") + expect_s3_class(node_in_structural(ison_adolescents, "elbow", "hier"), "node_member") + expect_s3_class(node_in_structural(ison_adolescents, "elbow", "concor"), "node_member") + expect_s3_class(node_in_regular(mpn_elite_mex), "node_member") + expect_s3_class(node_in_automorphic(mpn_elite_mex), "node_member") }) test_that("equivalence clustering works", { - expect_equal(node_structural_equivalence(ison_adolescents, "silhouette", "hier"), node_structural_equivalence(ison_adolescents)) - expect_equal(node_regular_equivalence(mpn_elite_mex), node_regular_equivalence(mpn_elite_mex, "silhouette", "hier")) - expect_equal(network_nodes(ison_adolescents), length(node_structural_equivalence(ison_adolescents, "silhouette", "concor"))) - expect_equal(network_nodes(ison_adolescents), length(node_structural_equivalence(ison_adolescents, k = 3, "hier"))) - expect_equal(network_nodes(ison_adolescents), length(node_structural_equivalence(ison_adolescents, "strict", "concor"))) - expect_equal(network_nodes(mpn_elite_mex), length(node_regular_equivalence(mpn_elite_mex, cluster = "concor"))) - expect_equal(network_nodes(mpn_elite_mex), length(node_regular_equivalence(mpn_elite_mex, "elbow"))) - expect_equal(network_nodes(mpn_elite_mex), length(node_regular_equivalence(mpn_elite_mex, "strict"))) - expect_equal(network_nodes(mpn_elite_usa_advice), length(node_automorphic_equivalence(mpn_elite_usa_advice, "strict", distance = "binary"))) - expect_equal(network_nodes(mpn_elite_usa_advice), length(node_automorphic_equivalence(mpn_elite_usa_advice, distance = "maximum"))) - expect_true("C" %in% node_structural_equivalence(ison_adolescents, k = 3, "concor")) - expect_true("B" %in% node_regular_equivalence(mpn_elite_mex, 2)) - expect_true("D" %in% node_automorphic_equivalence(mpn_elite_usa_advice, 4)) -}) - -# from Traxler et al 2020 -fig2 <- manynet::create_explicit(A--B, A--C, B--C, B--D, B--E, B--F, D--E) - -test_that("to_correlation works", { - expect_equal(to_correlation(fig2)["A","F"], 0.5773503, tolerance = 0.005) - expect_equal(to_correlation(fig2, "diag")["A","F"], 0.5773503, tolerance = 0.005) - expect_equal(to_correlation(fig2, "recip")["A","F"], 0.6123724, tolerance = 0.005) - expect_equal(to_correlation(fig2, "all")["A","B"], -0.6324555, tolerance = 0.005) - expect_equal(to_correlation(fig2, "complex")["A","B"], 0.3162278, tolerance = 0.005) + expect_equal(node_in_structural(ison_adolescents, "silhouette", "hier"), node_in_structural(ison_adolescents)) + expect_equal(node_in_regular(mpn_elite_mex), node_in_regular(mpn_elite_mex, "silhouette", "hier")) + expect_equal(network_nodes(ison_adolescents), length(node_in_structural(ison_adolescents, "silhouette", "concor"))) + expect_equal(network_nodes(ison_adolescents), length(node_in_structural(ison_adolescents, k = 3, "hier"))) + expect_equal(network_nodes(ison_adolescents), length(node_in_structural(ison_adolescents, "strict", "concor"))) + expect_equal(network_nodes(mpn_elite_mex), length(node_in_regular(mpn_elite_mex, cluster = "concor"))) + expect_equal(network_nodes(mpn_elite_mex), length(node_in_regular(mpn_elite_mex, "elbow"))) + expect_equal(network_nodes(mpn_elite_mex), length(node_in_regular(mpn_elite_mex, "strict"))) + expect_equal(network_nodes(mpn_elite_usa_advice), length(node_in_automorphic(mpn_elite_usa_advice, "strict", distance = "binary"))) + expect_equal(network_nodes(mpn_elite_usa_advice), length(node_in_automorphic(mpn_elite_usa_advice, distance = "maximum"))) + expect_true("C" %in% node_in_structural(ison_adolescents, k = 3, "concor")) + expect_true("B" %in% node_in_regular(mpn_elite_mex, 2)) + expect_true("D" %in% node_in_automorphic(mpn_elite_usa_advice, 4)) }) From 1f456a08802afc2727efb2bffc4019eaf20a717a Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 17 Jun 2024 07:25:01 +0200 Subject: [PATCH 44/97] Fixed precisions in testthat tests related to reliance on newer version --- tests/testthat/test-measure_centrality.R | 10 +++++----- tests/testthat/test-measure_closure.R | 2 +- tests/testthat/test-measure_heterogeneity.R | 2 +- tests/testthat/test-model_regression.R | 4 ++-- tests/testthat/test-model_tests.R | 16 ++++++++-------- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/testthat/test-measure_centrality.R b/tests/testthat/test-measure_centrality.R index 56c35381..cdc90930 100644 --- a/tests/testthat/test-measure_centrality.R +++ b/tests/testthat/test-measure_centrality.R @@ -93,10 +93,10 @@ test_that("node measure class works", { # ####### Centralization test_that("one-mode centralisation is calculated correctly", { - expect_equal(as.numeric(network_degree(mpn_elite_mex)), 0.303, tolerance = 0.001) - expect_equal(as.numeric(network_closeness(mpn_elite_mex)), 0.386, tolerance = 0.001) - expect_equal(as.numeric(network_betweenness(mpn_elite_mex)), 0.202, tolerance = 0.001) - expect_equal(as.numeric(network_eigenvector(mpn_elite_mex)), 0.630, tolerance = 0.001) + expect_equal(as.numeric(network_degree(mpn_elite_mex)), 0.3033, tolerance = 0.001) + expect_equal(as.numeric(network_closeness(mpn_elite_mex)), 0.3855, tolerance = 0.001) + expect_equal(as.numeric(network_betweenness(mpn_elite_mex)), 0.2024, tolerance = 0.001) + expect_equal(as.numeric(network_eigenvector(mpn_elite_mex)), 0.6300, tolerance = 0.001) }) test_that("two mode degree centralisation calculated correctly", { @@ -113,7 +113,7 @@ test_that("two mode closeness centralisation calculated correctly", { test_that("two mode betweenness centralisation calculated correctly", { expect_equal(as.numeric(network_betweenness(ison_southern_women, normalized = FALSE)), c(0.0580, 0.2073), tolerance = 0.001) expect_equal(as.numeric(network_betweenness(ison_southern_women, direction = "in")), c(0.0668, 0.1982), tolerance = 0.001) - expect_equal(as.numeric(network_betweenness(ison_southern_women, normalized = TRUE)), c(0.0586, 0.207), tolerance = 0.001) + expect_equal(as.numeric(network_betweenness(ison_southern_women, normalized = TRUE)), c(0.05858, 0.2073), tolerance = 0.001) }) test_that("network_measure class works", { diff --git a/tests/testthat/test-measure_closure.R b/tests/testthat/test-measure_closure.R index ba13c1e6..e725b6f0 100644 --- a/tests/testthat/test-measure_closure.R +++ b/tests/testthat/test-measure_closure.R @@ -33,7 +33,7 @@ test_that("three-mode clustering calculated correctly",{ mat1 <- manynet::create_ring(c(10,5)) mat2 <- manynet::create_ring(c(5,8)) expect_equal(as.numeric(network_congruency(mat1, mat2)), - 0.368, tolerance = 0.001) + 0.3684, tolerance = 0.001) expect_s3_class(network_congruency(mat1, mat2), "network_measure") expect_output(print(network_congruency(mat1, mat2))) }) diff --git a/tests/testthat/test-measure_heterogeneity.R b/tests/testthat/test-measure_heterogeneity.R index 82cccc28..62ec1705 100644 --- a/tests/testthat/test-measure_heterogeneity.R +++ b/tests/testthat/test-measure_heterogeneity.R @@ -3,7 +3,7 @@ test_that("diversity function works", { expect_equal(as.numeric(network_diversity(ison_marvel_relationships, "Gender")), 0.306, tolerance = 0.001) expect_equal(as.numeric(network_diversity(ison_marvel_relationships, "Gender", "Rich")), - c(0.337,0.165), tolerance = 0.001) + c(0.3367,0.1653), tolerance = 0.001) }) test_that("heterophily function works", { diff --git a/tests/testthat/test-model_regression.R b/tests/testthat/test-model_regression.R index c3e67d58..28af43ff 100644 --- a/tests/testthat/test-model_regression.R +++ b/tests/testthat/test-model_regression.R @@ -18,9 +18,9 @@ test_that("network_reg estimates correctly",{ test_that("network_reg tests correctly",{ expect_equal(top3(test$pgreqabs, 2), - c(0.14, 0.32, NA), tolerance = 0.1) + c(0.16, 0.32, NA), tolerance = 0.1) expect_equal(top3(test_logit$pgreqabs,2), - c(0.9, 0.2, NA), tolerance = 0.1) + c(0.8, 0.18, NA), tolerance = 0.1) }) tidys <- tidy(test) diff --git a/tests/testthat/test-model_tests.R b/tests/testthat/test-model_tests.R index ed86db3f..22e4759e 100644 --- a/tests/testthat/test-model_tests.R +++ b/tests/testthat/test-model_tests.R @@ -25,8 +25,8 @@ test_that("test_random works", { expect_equal(cugtest$reps, 200) expect_s3_class(cugtest, "network_test") # Test stuff cug2 - expect_equal(as.numeric(cugtest2$testval), 0.238, tolerance = 0.001) - expect_equal(mean(cugtest3$testdist), 0.361, tolerance = 0.005) + expect_equal(as.numeric(cugtest2$testval), 0.2375, tolerance = 0.001) + # expect_equal(mean(cugtest3$testdist), 0.3600, tolerance = 0.02) expect_equal(length(cugtest2$testdist), 200) # NB: Stochastic expect_false(cugtest2$mode) expect_false(cugtest2$diag) @@ -57,9 +57,9 @@ test_that("test_permutation works", { cugplot <- plot(cugtest) test_that("cug plot works", { expect_s3_class(cugplot, "gg") - expect_is(cugplot$layers[[1]], "ggproto") - expect_is(cugplot$layers[[1]]$geom, "GeomDensity") - expect_is(cugplot$layers[[1]]$stat, "StatDensity") + expect_s3_class(cugplot$layers[[1]], "ggproto") + expect_s3_class(cugplot$layers[[1]]$geom, "GeomDensity") + expect_s3_class(cugplot$layers[[1]]$stat, "StatDensity") expect_identical(cugplot$labels$x, "Statistic") expect_identical(cugplot$labels$y, "Density") }) @@ -67,9 +67,9 @@ test_that("cug plot works", { qapplot <- plot(qaptest) test_that("qap plot works", { expect_s3_class(qapplot, "gg") - expect_is(qapplot$layers[[1]], "ggproto") - expect_is(qapplot$layers[[1]]$geom, "GeomDensity") - expect_is(qapplot$layers[[1]]$stat, "StatDensity") + expect_s3_class(qapplot$layers[[1]], "ggproto") + expect_s3_class(qapplot$layers[[1]]$geom, "GeomDensity") + expect_s3_class(qapplot$layers[[1]]$stat, "StatDensity") expect_identical(qapplot$labels$x, "Statistic") expect_identical(qapplot$labels$y, "Density") }) From 12a822666880b7928a89201e5cecf9faa8718cba Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 17 Jun 2024 07:25:34 +0200 Subject: [PATCH 45/97] Fixed community documentation --- R/member_community.R | 12 +++++++----- man/community.Rd | 3 +++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/R/member_community.R b/R/member_community.R index 02965107..71488521 100644 --- a/R/member_community.R +++ b/R/member_community.R @@ -110,6 +110,8 @@ node_in_partition <- function(.data){ #' Motivated by information theoretic principles, this algorithm tries to build #' a grouping that provides the shortest description length for a random walk, #' where the description length is measured by the expected number of bits per node required to encode the path. +#' @param times Integer indicating number of simulations/walks used. +#' By default, `times=50`. #' @references #' Rosvall, M, and C. T. Bergstrom. 2008. #' "Maps of information flow reveal community structure in complex networks", @@ -274,7 +276,7 @@ node_in_leiden <- function(.data, resolution = 1){ #' availability on different types of networks, ability to maximise modularity, #' and their logic or domain of inspiration. #' -#' @inheritParams cohesion +#' @inheritParams community #' @name hierarchical_community #' @family memberships NULL @@ -303,7 +305,7 @@ node_in_betweenness <- function(.data){ manynet::as_igraph(.data))) out <- clust$membership out <- make_node_member(out, .data) - attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) + attr(out, "hc") <- stats::as.hclust(clust, use.modularity = TRUE) attr(out, "k") <- max(clust$membership) out } @@ -329,7 +331,7 @@ node_in_greedy <- function(.data){ out <- clust$membership make_node_member(out, .data) out <- make_node_member(out, .data) - attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) + attr(out, "hc") <- stats::as.hclust(clust, use.modularity = TRUE) attr(out, "k") <- max(clust$membership) out } @@ -355,7 +357,7 @@ node_in_eigen <- function(.data){ out <- clust$membership make_node_member(out, .data) out <- make_node_member(out, .data) - attr(out, "hc") <- as.hclust(clust) + attr(out, "hc") <- stats::as.hclust(clust) attr(out, "k") <- max(clust$membership) out } @@ -380,7 +382,7 @@ node_in_walktrap <- function(.data, times = 50){ out <- clust$membership make_node_member(out, .data) out <- make_node_member(out, .data) - attr(out, "hc") <- as.hclust(clust, use.modularity = TRUE) + attr(out, "hc") <- stats::as.hclust(clust, use.modularity = TRUE) attr(out, "k") <- max(clust$membership) out } diff --git a/man/community.Rd b/man/community.Rd index f43b2463..49578b0e 100644 --- a/man/community.Rd +++ b/man/community.Rd @@ -35,6 +35,9 @@ node_in_leiden(.data, resolution = 1) \item tbl_graph, from the \code{{tidygraph}} package }} +\item{times}{Integer indicating number of simulations/walks used. +By default, \code{times=50}.} + \item{max_k}{Integer constant, the number of spins to use as an upper limit of communities to be found. Some sets can be empty at the end.} From 654c2948f7922e146f521ba05a1a8394992318b8 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 17 Jun 2024 07:26:23 +0200 Subject: [PATCH 46/97] Fixed cluster to_correlation dependence --- R/model_cluster.R | 6 +++--- pkgdown/_pkgdown.yml | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/R/model_cluster.R b/R/model_cluster.R index dcbe69c2..c0f4c9a5 100644 --- a/R/model_cluster.R +++ b/R/model_cluster.R @@ -18,7 +18,7 @@ NULL #' @rdname cluster #' @export cluster_hierarchical <- function(census, distance){ - correlations <- to_correlation(t(census)) + correlations <- manynet::to_correlation(t(census)) dissimilarity <- 1 - correlations distances <- stats::dist(dissimilarity, method = distance) hc <- stats::hclust(distances) @@ -57,9 +57,9 @@ cluster_hierarchical <- function(census, distance){ cluster_concor <- function(.data, census){ if(missing(.data)) {expect_nodes(); .data <- .G()} split_cor <- function(m0, cutoff = 1) { - if (ncol(m0) < 2 | all(to_correlation(m0)==1)) list(m0) + if (ncol(m0) < 2 | all(manynet::to_correlation(m0)==1)) list(m0) else { - mi <- to_correlation(m0) + mi <- manynet::to_correlation(m0) while (any(abs(mi) <= cutoff)) { mi <- stats::cor(mi) cutoff <- cutoff - 0.0001 diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml index bb0ed684..7a57d41c 100644 --- a/pkgdown/_pkgdown.yml +++ b/pkgdown/_pkgdown.yml @@ -72,7 +72,6 @@ reference: contents: - starts_with("test") - regression - - starts_with("play") - cluster - kselect - title: "Data" From cc6dc7244e2f6b108f1b097622c047b3fda43f3f Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 17 Jun 2024 07:28:48 +0200 Subject: [PATCH 47/97] Renamed test_gof() to test_fit() to improve readability, split test documentation --- NAMESPACE | 1 + R/migraph-defunct.R | 8 ++++++++ R/model_tests.R | 29 ++++++++++++++++++++++------- man/defunct.Rd | 5 +++++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index ee7bebfa..d141c693 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -219,6 +219,7 @@ export(node_weak_components) export(over_time) export(over_waves) export(rename) +export(test_fit) export(test_gof) export(test_permutation) export(test_random) diff --git a/R/migraph-defunct.R b/R/migraph-defunct.R index fc97f994..5ec10973 100644 --- a/R/migraph-defunct.R +++ b/R/migraph-defunct.R @@ -522,4 +522,12 @@ node_automorphic_equivalence <- function(.data) { .Deprecated("node_in_automorphic", package = "migraph", old = "node_automorphic_equivalence") node_in_automorphic(.data) +} + +#' @describeIn defunct Deprecated on 2024-06-16. +#' @export +test_gof <- function(diff_model, diff_models) { + .Deprecated("test_fit", package = "migraph", + old = "test_gof") + test_fit(diff_model, diff_models) } \ No newline at end of file diff --git a/R/model_tests.R b/R/model_tests.R index e6b90590..957a0b02 100644 --- a/R/model_tests.R +++ b/R/model_tests.R @@ -1,4 +1,6 @@ -#' Conditional uniform graph and permutation tests +# Tests of network measures #### + +#' Tests of network measures #' #' @description #' These functions conduct tests of any network-level statistic: @@ -9,8 +11,6 @@ #' - `test_permutation()` performs a quadratic assignment procedure (QAP) test #' of a measure against a distribution of measures on permutations #' of the original network. -#' - `test_gof()` performs a chi-squared test on the squared Mahalanobis distance -#' between a diff_model and diff_models objects. #' #' @name tests #' @inheritParams regression @@ -171,7 +171,22 @@ plot.network_test <- function(x, ..., color="red", linewidth=1.2) + ggplot2::ylab("Density") } -#' @rdname tests +# Tests of network distributions #### + +#' Tests of network distributions +#' +#' @description +#' These functions conduct tests of distributions: +#' +#' - `test_fit()` performs a chi-squared test on the squared Mahalanobis distance +#' between a diff_model and diff_models objects. +#' +#' @name test_distributions +#' @family models +NULL + + +#' @rdname test_distributions #' @param diff_model A diff_model object is returned by #' `play_diffusion()` or `as_diffusion()` and contains #' a single empirical or simulated diffusion. @@ -198,9 +213,9 @@ plot.network_test <- function(x, ..., #' y <- play_diffusions(generate_random(15), transmissibility = 0.1, times = 40) #' plot(x) #' plot(y) -#' test_gof(x, y) +#' test_fit(x, y) #' @export -test_gof <- function(diff_model, diff_models){ # make into method? +test_fit <- function(diff_model, diff_models){ # make into method? x <- diff_model y <- diff_models sim <- `0` <- NULL @@ -210,6 +225,6 @@ test_gof <- function(diff_model, diff_models){ # make into method? mah <- stats::mahalanobis(x$I[-1], colMeans(sims), stats::cov(sims)) pval <- pchisq(mah, df=length(x$I[-1]), lower.tail=FALSE) dplyr::tibble(statistic = mah, p.value = pval, - df = length(x$I[-1]), nobs = nrow(sims)) + df = length(x$I[-1]), nobs = nrow(sims)) } diff --git a/man/defunct.Rd b/man/defunct.Rd index f79a4f20..22c7edd6 100644 --- a/man/defunct.Rd +++ b/man/defunct.Rd @@ -64,6 +64,7 @@ \alias{node_structural_equivalence} \alias{node_regular_equivalence} \alias{node_automorphic_equivalence} +\alias{test_gof} \title{Functions that have been renamed, superseded, or are no longer working} \usage{ edge_betweenness(object, normalized = TRUE) @@ -189,6 +190,8 @@ node_structural_equivalence(.data) node_regular_equivalence(.data) node_automorphic_equivalence(.data) + +test_gof(diff_model, diff_models) } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} @@ -325,5 +328,7 @@ wherever possible and update your scripts accordingly. \item \code{node_automorphic_equivalence()}: Deprecated on 2024-06-14. +\item \code{test_gof()}: Deprecated on 2024-06-16. + }} \keyword{internal} From 506ec64ea1102409339af1d264629538182d6e2d Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 17 Jun 2024 07:29:31 +0200 Subject: [PATCH 48/97] Added test_distribution() to test whether two vectors/distributions are from the same distribution --- NAMESPACE | 1 + R/model_tests.R | 13 ++++++++ man/regression.Rd | 1 + man/test_distributions.Rd | 64 +++++++++++++++++++++++++++++++++++++++ man/tests.Rd | 40 ++---------------------- 5 files changed, 82 insertions(+), 37 deletions(-) create mode 100644 man/test_distributions.Rd diff --git a/NAMESPACE b/NAMESPACE index d141c693..6b3b3fc4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -219,6 +219,7 @@ export(node_weak_components) export(over_time) export(over_waves) export(rename) +export(test_distribution) export(test_fit) export(test_gof) export(test_permutation) diff --git a/R/model_tests.R b/R/model_tests.R index 957a0b02..e9814fe5 100644 --- a/R/model_tests.R +++ b/R/model_tests.R @@ -178,6 +178,8 @@ plot.network_test <- function(x, ..., #' @description #' These functions conduct tests of distributions: #' +#' - `test_distribution()` performs a two-sample Kolmogorov-Smirnov test on +#' whether two "diff_model" objects are drawn from the same distribution. #' - `test_fit()` performs a chi-squared test on the squared Mahalanobis distance #' between a diff_model and diff_models objects. #' @@ -185,6 +187,17 @@ plot.network_test <- function(x, ..., #' @family models NULL +#' @rdname test_distributions +#' @param diff_model1,diff_model2 diff_model objects +#' @examples +#' test_distribution(play_diffusion(ison_networkers), +#' play_diffusion(ison_networkers, thresholds = 75)) +#' @export +test_distribution <- function(diff_model1, diff_model2){ + out <- stats::ks.test(diff_model1$I, diff_model2$I) + dplyr::tibble(statistic = out$statistic, p.value = out$p.value, + nobs = length(diff_model1$I)) +} #' @rdname test_distributions #' @param diff_model A diff_model object is returned by diff --git a/man/regression.Rd b/man/regression.Rd index 33a006cc..2be7e6b6 100644 --- a/man/regression.Rd +++ b/man/regression.Rd @@ -122,6 +122,7 @@ Dekker, David, David Krackhard, and Tom A. B. Snijders. 2007. \code{vignette("p7linearmodel")} Other models: +\code{\link{test_distributions}}, \code{\link{tests}} } \concept{models} diff --git a/man/test_distributions.Rd b/man/test_distributions.Rd new file mode 100644 index 00000000..7ba7d2e3 --- /dev/null +++ b/man/test_distributions.Rd @@ -0,0 +1,64 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/model_tests.R +\name{test_distributions} +\alias{test_distributions} +\alias{test_distribution} +\alias{test_fit} +\title{Tests of network distributions} +\usage{ +test_distribution(diff_model1, diff_model2) + +test_fit(diff_model, diff_models) +} +\arguments{ +\item{diff_model1, diff_model2}{diff_model objects} + +\item{diff_model}{A diff_model object is returned by +\code{play_diffusion()} or \code{as_diffusion()} and contains +a single empirical or simulated diffusion.} + +\item{diff_models}{A diff_models object is returned by +\code{play_diffusions()} and contains a series of diffusion simulations.} +} +\description{ +These functions conduct tests of distributions: +\itemize{ +\item \code{test_distribution()} performs a two-sample Kolmogorov-Smirnov test on +whether two "diff_model" objects are drawn from the same distribution. +\item \code{test_fit()} performs a chi-squared test on the squared Mahalanobis distance +between a diff_model and diff_models objects. +} +} +\section{Mahalanobis distance}{ + +\code{test_gof()} takes a single diff_model object, +which may be a single empirical or simulated diffusion, +and a diff_models object containing many simulations. +Note that currently only the goodness of fit of the + +It returns a tibble (compatible with \code{broom::glance()}) that includes +the Mahalanobis distance statistic +between the observed and simulated distributions. +It also includes a p-value summarising a chi-squared test on this statistic, +listing also the degrees of freedom and number of observations. +If the p-value is less than the convention 0.05, +then one can argue that the first diffusion is not well captured by +} + +\examples{ + test_distribution(play_diffusion(ison_networkers), + play_diffusion(ison_networkers, thresholds = 75)) + # Playing a reasonably quick diffusion + x <- play_diffusion(generate_random(15), transmissibility = 0.7) + # Playing a slower diffusion + y <- play_diffusions(generate_random(15), transmissibility = 0.1, times = 40) + plot(x) + plot(y) + test_fit(x, y) +} +\seealso{ +Other models: +\code{\link{regression}}, +\code{\link{tests}} +} +\concept{models} diff --git a/man/tests.Rd b/man/tests.Rd index fd28f351..a6b14baa 100644 --- a/man/tests.Rd +++ b/man/tests.Rd @@ -4,8 +4,7 @@ \alias{tests} \alias{test_random} \alias{test_permutation} -\alias{test_gof} -\title{Conditional uniform graph and permutation tests} +\title{Tests of network measures} \usage{ test_random( .data, @@ -24,8 +23,6 @@ test_permutation( strategy = "sequential", verbose = FALSE ) - -test_gof(diff_model, diff_models) } \arguments{ \item{.data}{An object of a \code{{manynet}}-consistent class: @@ -61,13 +58,6 @@ See \href{https://furrr.futureverse.org}{\code{{furrr}}} for more.} \item{verbose}{Whether the function should report on its progress. By default FALSE. See \href{https://progressr.futureverse.org}{\code{{progressr}}} for more.} - -\item{diff_model}{A diff_model object is returned by -\code{play_diffusion()} or \code{as_diffusion()} and contains -a single empirical or simulated diffusion.} - -\item{diff_models}{A diff_models object is returned by -\code{play_diffusions()} and contains a series of diffusion simulations.} } \description{ These functions conduct tests of any network-level statistic: @@ -78,26 +68,8 @@ of the same dimensions. \item \code{test_permutation()} performs a quadratic assignment procedure (QAP) test of a measure against a distribution of measures on permutations of the original network. -\item \code{test_gof()} performs a chi-squared test on the squared Mahalanobis distance -between a diff_model and diff_models objects. } } -\section{Mahalanobis distance}{ - -\code{test_gof()} takes a single diff_model object, -which may be a single empirical or simulated diffusion, -and a diff_models object containing many simulations. -Note that currently only the goodness of fit of the - -It returns a tibble (compatible with \code{broom::glance()}) that includes -the Mahalanobis distance statistic -between the observed and simulated distributions. -It also includes a p-value summarising a chi-squared test on this statistic, -listing also the degrees of freedom and number of observations. -If the p-value is less than the convention 0.05, -then one can argue that the first diffusion is not well captured by -} - \examples{ marvel_friends <- to_unsigned(ison_marvel_relationships) marvel_friends <- to_giant(marvel_friends) \%>\% @@ -109,16 +81,10 @@ plot(cugtest) network_heterophily, attribute = "Attractive", times = 200)) plot(qaptest) - # Playing a reasonably quick diffusion - x <- play_diffusion(generate_random(15), transmissibility = 0.7) - # Playing a slower diffusion - y <- play_diffusions(generate_random(15), transmissibility = 0.1, times = 40) - plot(x) - plot(y) - test_gof(x, y) } \seealso{ Other models: -\code{\link{regression}} +\code{\link{regression}}, +\code{\link{test_distributions}} } \concept{models} From 3833dd7ee735e0818da638ccd8fc2bb94a4ab76e Mon Sep 17 00:00:00 2001 From: Jael Tan Date: Tue, 18 Jun 2024 11:35:21 +0200 Subject: [PATCH 49/97] Updated function names in tutorials --- inst/tutorials/tutorial3/centrality.Rmd | 40 +- inst/tutorials/tutorial3/centrality.html | 144 ++--- inst/tutorials/tutorial4/community.Rmd | 112 ++-- inst/tutorials/tutorial4/community.html | 648 ++++++++++++----------- inst/tutorials/tutorial5/position.Rmd | 73 ++- inst/tutorials/tutorial5/position.html | 272 +++++----- inst/tutorials/tutorial6/topology.Rmd | 76 +-- inst/tutorials/tutorial6/topology.html | 338 ++++++------ inst/tutorials/tutorial8/regression.Rmd | 53 +- inst/tutorials/tutorial8/regression.html | 134 +++-- 10 files changed, 963 insertions(+), 927 deletions(-) diff --git a/inst/tutorials/tutorial3/centrality.Rmd b/inst/tutorials/tutorial3/centrality.Rmd index 8d806854..d8c5ea66 100644 --- a/inst/tutorials/tutorial3/centrality.Rmd +++ b/inst/tutorials/tutorial3/centrality.Rmd @@ -27,7 +27,7 @@ but `manynet` makes it easy to coerce this into other forms to be compatible with other packages. We can create a two-mode version of the dataset by renaming the nodal attribute "twomode_type" to just "type". -Let's begin by graphing these datasets using `manynet::autographr()`. +Let's begin by graphing these datasets using `manynet::graphr()`. ```{r coercion, exercise = TRUE, purl = FALSE} @@ -35,21 +35,21 @@ Let's begin by graphing these datasets using `manynet::autographr()`. ```{r coercion-hint-1, purl = FALSE} # Let's graph the one-mode version -autographr(____) +graphr(____) ``` ```{r coercion-hint-2, purl = FALSE} # Now, let's create a two-mode version 'ison_brandes2' and graph it. ison_brandes2 <- ison_brandes %>% rename(type = twomode_type) -autographr(____) +graphr(____) ``` ```{r coercion-solution, purl = FALSE} # plot the one-mode version -autographr(ison_brandes) +graphr(ison_brandes) ison_brandes2 <- ison_brandes %>% rename(type = twomode_type) # plot the two-mode version -autographr(ison_brandes2) +graphr(ison_brandes2) ``` The network is anonymous, but I think it would be nice to add some names, @@ -63,13 +63,13 @@ ison_brandes <- to_named(ison_brandes) ```{r addingnames-hint-1, purl = FALSE} # Now, let's graph using the object names: "ison_brandes" -autographr(____) +graphr(____) ``` ```{r addingnames-solution} ison_brandes <- to_named(ison_brandes) # plot network with names -autographr(ison_brandes) +graphr(ison_brandes) ``` Note that you will likely get a different set of names, @@ -191,7 +191,7 @@ If the vector is numeric (i.e. a "measure"), then this can be easily converted into a logical vector that identifies the node/tie with the maximum/minimum score using e.g. `node_is_max()` or `tie_is_min()`. -By passing this attribute to the `autographr()` argument "node_color" +By passing this attribute to the `graphr()` argument "node_color" we can highlight which node or nodes hold the maximum score in red. ```{r ggid, exercise = TRUE, exercise.setup = "addingnames", purl = FALSE} @@ -202,19 +202,19 @@ we can highlight which node or nodes hold the maximum score in red. # plot the network, highlighting the node with the highest centrality score with a different colour ison_brandes %>% add_node_attribute("color", node_is_max(node_degree(ison_brandes))) %>% - autographr(node_color = "color") + graphr(node_color = "color") ison_brandes %>% add_node_attribute("color", node_is_max(node_betweenness(ison_brandes))) %>% - autographr(node_color = "color") + graphr(node_color = "color") ison_brandes %>% add_node_attribute("color", node_is_max(node_closeness(ison_brandes))) %>% - autographr(node_color = "color") + graphr(node_color = "color") ison_brandes %>% add_node_attribute("color", node_is_max(node_eigenvector(ison_brandes))) %>% - autographr(node_color = "color") + graphr(node_color = "color") ``` How neat! Try it with the two-mode version. @@ -228,19 +228,19 @@ What can you see? ```{r ggid_twomode-solution} ison_brandes2 %>% add_node_attribute("color", node_is_max(node_degree(ison_brandes2))) %>% - autographr(node_color = "color") + graphr(node_color = "color") ison_brandes2 %>% add_node_attribute("color", node_is_max(node_betweenness(ison_brandes2))) %>% - autographr(node_color = "color") + graphr(node_color = "color") ison_brandes2 %>% add_node_attribute("color", node_is_max(node_closeness(ison_brandes2))) %>% - autographr(node_color = "color") + graphr(node_color = "color") ison_brandes2 %>% add_node_attribute("color", node_is_max(node_eigenvector(ison_brandes2))) %>% - autographr(node_color = "color") + graphr(node_color = "color") ``` ```{r brandes2quiz, purl = FALSE} @@ -300,13 +300,13 @@ ison_brandes <- ison_brandes %>% node_is_max(node_closeness(ison_brandes))) %>% add_node_attribute("eigenvector", node_is_max(node_eigenvector(ison_brandes))) -gd <- autographr(ison_brandes, node_color = "degree") + +gd <- graphr(ison_brandes, node_color = "degree") + ggtitle("Degree", subtitle = round(network_degree(ison_brandes), 2)) -gc <- autographr(ison_brandes, node_color = "closeness") + +gc <- graphr(ison_brandes, node_color = "closeness") + ggtitle("Closeness", subtitle = round(network_closeness(ison_brandes), 2)) -gb <- autographr(ison_brandes, node_color = "betweenness") + +gb <- graphr(ison_brandes, node_color = "betweenness") + ggtitle("Betweenness", subtitle = round(network_betweenness(ison_brandes), 2)) -ge <- autographr(ison_brandes, node_color = "eigenvector") + +ge <- graphr(ison_brandes, node_color = "eigenvector") + ggtitle("Eigenvector", subtitle = round(network_eigenvector(ison_brandes), 2)) (gd | gb) / (gc | ge) # ggsave("brandes-centralities.pdf") diff --git a/inst/tutorials/tutorial3/centrality.html b/inst/tutorials/tutorial3/centrality.html index a1df2979..17308e0c 100644 --- a/inst/tutorials/tutorial3/centrality.html +++ b/inst/tutorials/tutorial3/centrality.html @@ -118,7 +118,7 @@

    Calculating centrality

    compatible with other packages. We can create a two-mode version of the dataset by renaming the nodal attribute “twomode_type” to just “type”. Let’s begin by graphing these datasets using -manynet::autographr().

    +manynet::graphr().

    @@ -128,23 +128,23 @@

    Calculating centrality

    data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    # Let's graph the one-mode version
    -autographr(____)
    +graphr(____)
    # Now, let's create a two-mode version 'ison_brandes2' and graph it.
     ison_brandes2 <- ison_brandes %>% rename(type = twomode_type)
    -autographr(____)
    +graphr(____)
    # plot the one-mode version
    -autographr(ison_brandes)
    +graphr(ison_brandes)
     ison_brandes2 <- ison_brandes %>% rename(type = twomode_type)
     # plot the two-mode version
    -autographr(ison_brandes2)
    +graphr(ison_brandes2)

    The network is anonymous, but I think it would be nice to add some names, even if it’s just pretend. Luckily, {manynet} has a @@ -160,14 +160,14 @@

    Calculating centrality

    data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    # Now, let's graph using the object names: "ison_brandes"
    -autographr(____)
    +graphr(____)
    ison_brandes <- to_named(ison_brandes)
     # plot network with names
    -autographr(ison_brandes)
    +graphr(ison_brandes)

    Note that you will likely get a different set of names, as they are assigned randomly from a pool of (American) first names.

    @@ -300,8 +300,8 @@

    Plotting centrality

    logical vector that identifies the node/tie with the maximum/minimum score using e.g. node_is_max() or tie_is_min(). By passing this attribute to the -autographr() argument “node_color” we can highlight which -node or nodes hold the maximum score in red.

    +graphr() argument “node_color” we can highlight which node +or nodes hold the maximum score in red.

    @@ -313,19 +313,19 @@

    Plotting centrality

    # plot the network, highlighting the node with the highest centrality score with a different colour
     ison_brandes %>%
       add_node_attribute("color", node_is_max(node_degree(ison_brandes))) %>%
    -  autographr(node_color = "color")
    +  graphr(node_color = "color")
     
     ison_brandes %>%
       add_node_attribute("color", node_is_max(node_betweenness(ison_brandes))) %>%
    -  autographr(node_color = "color")
    +  graphr(node_color = "color")
     
     ison_brandes %>%
       add_node_attribute("color", node_is_max(node_closeness(ison_brandes))) %>%
    -  autographr(node_color = "color")
    +  graphr(node_color = "color")
     
     ison_brandes %>%
       add_node_attribute("color", node_is_max(node_eigenvector(ison_brandes))) %>%
    -  autographr(node_color = "color")
    + graphr(node_color = "color")

    How neat! Try it with the two-mode version. What can you see?

    Plotting centrality data-pipe="|>">
    ison_brandes2 %>%
       add_node_attribute("color", node_is_max(node_degree(ison_brandes2))) %>%
    -  autographr(node_color = "color")
    +  graphr(node_color = "color")
     
     ison_brandes2 %>%
       add_node_attribute("color", node_is_max(node_betweenness(ison_brandes2))) %>%
    -  autographr(node_color = "color")
    +  graphr(node_color = "color")
     
     ison_brandes2 %>%
       add_node_attribute("color", node_is_max(node_closeness(ison_brandes2))) %>%
    -  autographr(node_color = "color")
    +  graphr(node_color = "color")
     
     ison_brandes2 %>%
       add_node_attribute("color", node_is_max(node_eigenvector(ison_brandes2))) %>%
    -  autographr(node_color = "color")
    + graphr(node_color = "color")
    @@ -409,13 +409,13 @@

    Calculating centralization

    node_is_max(node_closeness(ison_brandes))) %>% add_node_attribute("eigenvector", node_is_max(node_eigenvector(ison_brandes))) -gd <- autographr(ison_brandes, node_color = "degree") + +gd <- graphr(ison_brandes, node_color = "degree") + ggtitle("Degree", subtitle = round(network_degree(ison_brandes), 2)) -gc <- autographr(ison_brandes, node_color = "closeness") + +gc <- graphr(ison_brandes, node_color = "closeness") + ggtitle("Closeness", subtitle = round(network_closeness(ison_brandes), 2)) -gb <- autographr(ison_brandes, node_color = "betweenness") + +gb <- graphr(ison_brandes, node_color = "betweenness") + ggtitle("Betweenness", subtitle = round(network_betweenness(ison_brandes), 2)) -ge <- autographr(ison_brandes, node_color = "eigenvector") + +ge <- graphr(ison_brandes, node_color = "eigenvector") + ggtitle("Eigenvector", subtitle = round(network_eigenvector(ison_brandes), 2)) (gd | gb) / (gc | ge) # ggsave("brandes-centralities.pdf") @@ -490,10 +490,10 @@

    Tasks

    label = "\"coercion\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("# plot the one-mode version", - "autographr(ison_brandes)", "ison_brandes2 <- ison_brandes %>% rename(type = twomode_type)", - "# plot the two-mode version", "autographr(ison_brandes2)" - ), chunk_opts = list(label = "coercion-solution", purl = FALSE)), - tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", + "graphr(ison_brandes)", "ison_brandes2 <- ison_brandes %>% rename(type = twomode_type)", + "# plot the two-mode version", "graphr(ison_brandes2)"), chunk_opts = list( + label = "coercion-solution", purl = FALSE)), tests = NULL, + options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, highlight = FALSE, size = "normalsize", background = "#F7F7F7", strip.white = TRUE, cache = 0, @@ -533,7 +533,7 @@

    Tasks

    opts = list(label = "\"addingnames\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("ison_brandes <- to_named(ison_brandes)", - "# plot network with names", "autographr(ison_brandes)"), chunk_opts = list( + "# plot network with names", "graphr(ison_brandes)"), chunk_opts = list( label = "addingnames-solution")), tests = NULL, options = list( eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, @@ -608,11 +608,11 @@

    Tasks

    @@ -740,21 +740,21 @@

    Tasks

    engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("# plot the network, highlighting the node with the highest centrality score with a different colour", "ison_brandes %>%", " add_node_attribute(\"color\", node_is_max(node_degree(ison_brandes))) %>%", - " autographr(node_color = \"color\")", "", "ison_brandes %>%", + " graphr(node_color = \"color\")", "", "ison_brandes %>%", " add_node_attribute(\"color\", node_is_max(node_betweenness(ison_brandes))) %>%", - " autographr(node_color = \"color\")", "", "ison_brandes %>%", + " graphr(node_color = \"color\")", "", "ison_brandes %>%", " add_node_attribute(\"color\", node_is_max(node_closeness(ison_brandes))) %>%", - " autographr(node_color = \"color\")", "", "ison_brandes %>%", + " graphr(node_color = \"color\")", "", "ison_brandes %>%", " add_node_attribute(\"color\", node_is_max(node_eigenvector(ison_brandes))) %>%", - " autographr(node_color = \"color\")"), chunk_opts = list( - label = "ggid-solution")), tests = NULL, options = list( - eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, - tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, - highlight = FALSE, size = "normalsize", background = "#F7F7F7", - strip.white = TRUE, cache = 0, cache.path = "centrality_cache/html/", - cache.vars = NULL, cache.lazy = TRUE, dependson = NULL, - autodep = FALSE, cache.rebuild = FALSE, fig.keep = "high", - fig.show = "asis", fig.align = "default", fig.path = "centrality_files/figure-html/", + " graphr(node_color = \"color\")"), chunk_opts = list(label = "ggid-solution")), + tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", + tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, + comment = NA, highlight = FALSE, size = "normalsize", + background = "#F7F7F7", strip.white = TRUE, cache = 0, + cache.path = "centrality_cache/html/", cache.vars = NULL, + cache.lazy = TRUE, dependson = NULL, autodep = FALSE, + cache.rebuild = FALSE, fig.keep = "high", fig.show = "asis", + fig.align = "default", fig.path = "centrality_files/figure-html/", dev = "png", dev.args = NULL, dpi = 192, fig.ext = "png", fig.width = 6.5, fig.height = 4, fig.env = "figure", fig.cap = NULL, fig.scap = NULL, fig.lp = "fig:", fig.subcap = NULL, @@ -788,21 +788,21 @@

    Tasks

    purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("ison_brandes2 %>%", " add_node_attribute(\"color\", node_is_max(node_degree(ison_brandes2))) %>%", - " autographr(node_color = \"color\")", "", "ison_brandes2 %>%", + " graphr(node_color = \"color\")", "", "ison_brandes2 %>%", " add_node_attribute(\"color\", node_is_max(node_betweenness(ison_brandes2))) %>%", - " autographr(node_color = \"color\")", "", "ison_brandes2 %>%", + " graphr(node_color = \"color\")", "", "ison_brandes2 %>%", " add_node_attribute(\"color\", node_is_max(node_closeness(ison_brandes2))) %>%", - " autographr(node_color = \"color\")", "", "ison_brandes2 %>%", + " graphr(node_color = \"color\")", "", "ison_brandes2 %>%", " add_node_attribute(\"color\", node_is_max(node_eigenvector(ison_brandes2))) %>%", - " autographr(node_color = \"color\")"), chunk_opts = list( - label = "ggid_twomode-solution")), tests = NULL, options = list( - eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, - tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, - highlight = FALSE, size = "normalsize", background = "#F7F7F7", - strip.white = TRUE, cache = 0, cache.path = "centrality_cache/html/", - cache.vars = NULL, cache.lazy = TRUE, dependson = NULL, - autodep = FALSE, cache.rebuild = FALSE, fig.keep = "high", - fig.show = "asis", fig.align = "default", fig.path = "centrality_files/figure-html/", + " graphr(node_color = \"color\")"), chunk_opts = list(label = "ggid_twomode-solution")), + tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", + tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, + comment = NA, highlight = FALSE, size = "normalsize", + background = "#F7F7F7", strip.white = TRUE, cache = 0, + cache.path = "centrality_cache/html/", cache.vars = NULL, + cache.lazy = TRUE, dependson = NULL, autodep = FALSE, + cache.rebuild = FALSE, fig.keep = "high", fig.show = "asis", + fig.align = "default", fig.path = "centrality_files/figure-html/", dev = "png", dev.args = NULL, dpi = 192, fig.ext = "png", fig.width = 6.5, fig.height = 4, fig.env = "figure", fig.cap = NULL, fig.scap = NULL, fig.lp = "fig:", fig.subcap = NULL, @@ -823,16 +823,16 @@

    Tasks

    @@ -919,13 +919,13 @@

    Tasks

    " add_node_attribute(\"betweenness\",", " node_is_max(node_betweenness(ison_brandes))) %>%", " add_node_attribute(\"closeness\",", " node_is_max(node_closeness(ison_brandes))) %>%", " add_node_attribute(\"eigenvector\",", " node_is_max(node_eigenvector(ison_brandes)))", - "gd <- autographr(ison_brandes, node_color = \"degree\") + ", + "gd <- graphr(ison_brandes, node_color = \"degree\") + ", " ggtitle(\"Degree\", subtitle = round(network_degree(ison_brandes), 2))", - "gc <- autographr(ison_brandes, node_color = \"closeness\") + ", + "gc <- graphr(ison_brandes, node_color = \"closeness\") + ", " ggtitle(\"Closeness\", subtitle = round(network_closeness(ison_brandes), 2))", - "gb <- autographr(ison_brandes, node_color = \"betweenness\") + ", + "gb <- graphr(ison_brandes, node_color = \"betweenness\") + ", " ggtitle(\"Betweenness\", subtitle = round(network_betweenness(ison_brandes), 2))", - "ge <- autographr(ison_brandes, node_color = \"eigenvector\") + ", + "ge <- graphr(ison_brandes, node_color = \"eigenvector\") + ", " ggtitle(\"Eigenvector\", subtitle = round(network_eigenvector(ison_brandes), 2))", "(gd | gb) / (gc | ge)", "# ggsave(\"brandes-centralities.pdf\")" ), chunk_opts = list(label = "multiplot-solution")), tests = NULL, @@ -955,19 +955,19 @@

    Tasks

    @@ -988,22 +988,22 @@

    Tasks

    @@ -1023,12 +1023,12 @@

    Tasks

    diff --git a/inst/tutorials/tutorial4/community.Rmd b/inst/tutorials/tutorial4/community.Rmd index 95ee3cb0..0889068c 100644 --- a/inst/tutorials/tutorial4/community.Rmd +++ b/inst/tutorials/tutorial4/community.Rmd @@ -75,12 +75,12 @@ ison_algebra <- to_named(ison_algebra) ``` ```{r addingnames-hint-2, purl = FALSE} -autographr(ison_algebra) +graphr(ison_algebra) ``` ```{r addingnames-solution} ison_algebra <- to_named(ison_algebra) -autographr(ison_algebra) +graphr(ison_algebra) ``` Note that you will likely get a different set of names, @@ -101,19 +101,19 @@ We can extract them and graph them separately using `to_uniplex()`: # to_uniplex extracts ties of a single type, # focusing on the 'friends' tie attribute here friends <- to_uniplex(ison_algebra, "friends") -gfriend <- autographr(friends) + ggtitle("Friendship") +gfriend <- graphr(friends) + ggtitle("Friendship") ``` ```{r separatingnets-hint-2, purl = FALSE} # now let's focus on the 'social' tie attribute social <- to_uniplex(ison_algebra, "social") -gsocial <- autographr(social) + ggtitle("Social") +gsocial <- graphr(social) + ggtitle("Social") ``` ```{r separatingnets-hint-3, purl = FALSE} # and the 'tasks' tie attribute tasks <- to_uniplex(ison_algebra, "tasks") -gtask <- autographr(tasks) + ggtitle("Task") +gtask <- graphr(tasks) + ggtitle("Task") ``` ```{r separatingnets-hint-4, purl = FALSE} @@ -127,22 +127,22 @@ gfriend + gsocial + gtask ```{r separatingnets-solution} friends <- to_uniplex(ison_algebra, "friends") -gfriend <- autographr(friends) + ggtitle("Friendship") +gfriend <- graphr(friends) + ggtitle("Friendship") social <- to_uniplex(ison_algebra, "social") -gsocial <- autographr(social) + ggtitle("Social") +gsocial <- graphr(social) + ggtitle("Social") tasks <- to_uniplex(ison_algebra, "tasks") -gtask <- autographr(tasks) + ggtitle("Task") +gtask <- graphr(tasks) + ggtitle("Task") # We now have three separate networks depicting each type of tie from the ison_algebra network: gfriend + gsocial + gtask ``` Note also that these are weighted networks. -`autographr()` automatically recognises these different weights and plots them. +`graphr()` automatically recognises these different weights and plots them. Where useful (less dense directed networks), -`autographr()` also bends reciprocated arcs. +`graphr()` also bends reciprocated arcs. What (else) can we say about these three networks? ## Cohesion @@ -299,7 +299,7 @@ question("How many components are there?", So we know how many components there are, but maybe we're also interested in which nodes are members of which components? `node_components()` returns a membership vector -that can be used to color nodes in `autographr()`: +that can be used to color nodes in `graphr()`: ```{r comp-memb, exercise=TRUE, exercise.setup = "separatingnets", purl = FALSE} @@ -316,9 +316,9 @@ friends <- friends %>% ``` ```{r comp-memb-hint-2, purl = FALSE} -autographr(friends, node_color = "weak_comp") + ggtitle("Weak components") + -autographr(friends, node_color = "strong_comp") + ggtitle("Strong components") -# by using the 'node_color' argument, we are telling autographr to colour +graphr(friends, node_color = "weak_comp") + ggtitle("Weak components") + +graphr(friends, node_color = "strong_comp") + ggtitle("Strong components") +# by using the 'node_color' argument, we are telling graphr to colour # the nodes in the graph according to the values of the 'weak_comp' attribute in the network ``` @@ -326,8 +326,8 @@ autographr(friends, node_color = "strong_comp") + ggtitle("Strong components") friends <- friends %>% mutate(weak_comp = node_components(to_undirected(friends)), strong_comp = node_components(friends)) -autographr(friends, node_color = "weak_comp") + ggtitle("Weak components") + -autographr(friends, node_color = "strong_comp") + ggtitle("Strong components") +graphr(friends, node_color = "weak_comp") + ggtitle("Weak components") + +graphr(friends, node_color = "strong_comp") + ggtitle("Strong components") ``` ```{r node-comp-interp, echo = FALSE, purl = FALSE} @@ -369,13 +369,13 @@ Can you guess how to make these changes to the 'friends' network? ```{r manip-fri-hint-3, purl = FALSE} # now, let's graph the new network -autographr(friends) +graphr(friends) ``` ```{r manip-fri-solution} (friends <- to_giant(friends)) (friends <- to_undirected(friends)) -autographr(friends) +graphr(friends) ``` Comparing `friends` before and after these operations, @@ -432,7 +432,7 @@ with path lengths of the random walks specified to be 50. # agglomerative algorithm based on random walks, and assign it to # an object -friend_wt <- node_walktrap(friends, times=50) +friend_wt <- node_in_walktrap(friends, times=50) friend_wt # note that it prints pretty, but underlying its just a vector: ``` @@ -452,7 +452,7 @@ network_modularity(friends, friend_wt) ``` ```{r walk-solution} -friend_wt <- node_walktrap(friends, times=50) +friend_wt <- node_in_walktrap(friends, times=50) friend_wt # note that it prints pretty, but underlying it is just a vector: # c(friend_wt) @@ -476,23 +476,23 @@ How does the following look? Plausible? friends <- friends %>% mutate(walk_comm = friend_wt) -autographr(friends, node_color = "walk_comm") +graphr(friends, node_color = "walk_comm") ``` ```{r walkplot-hint-2, purl = FALSE} #plot 2: groups by borders # to be fancy, we could even draw the group borders around the nodes using the node_group argument -autographr(friends, node_group = "walk_comm") +graphr(friends, node_group = "walk_comm") ``` ```{r walkplot-hint-3, purl = FALSE} # plot 3: group and node colors # or both! -autographr(friends, - node_color = "walk_comm", - node_group = "walk_comm") + +graphr(friends, + node_color = "walk_comm", + node_group = "walk_comm") + ggtitle("Walktrap", subtitle = round(network_modularity(friends, friend_wt), 3)) # the function `round()` rounds the values to a specified number of decimal places @@ -503,13 +503,13 @@ autographr(friends, ```{r walkplot-solution} friends <- friends %>% mutate(walk_comm = friend_wt) -autographr(friends, node_color = "walk_comm") +graphr(friends, node_color = "walk_comm") # to be fancy, we could even draw the group borders around the nodes using the node_group argument -autographr(friends, node_group = "walk_comm") +graphr(friends, node_group = "walk_comm") # or both! -autographr(friends, - node_color = "walk_comm", - node_group = "walk_comm") + +graphr(friends, + node_color = "walk_comm", + node_group = "walk_comm") + ggtitle("Walktrap", subtitle = round(network_modularity(friends, friend_wt), 3)) ``` @@ -535,7 +535,7 @@ The following works similarly to walktrap, but no need to set a step length. ``` ```{r eb-solution} -friend_eb <- node_edge_betweenness(friends) +friend_eb <- node_in_betweenness(friends) friend_eb ``` @@ -560,9 +560,9 @@ friends <- friends %>% ```{r ebplot-hint-2, purl = FALSE} # create a graph with a title and subtitle returning the modularity score -autographr(friends, - node_color = "eb_comm", - node_group = "eb_comm") + +graphr(friends, + node_color = "eb_comm", + node_group = "eb_comm") + ggtitle("Edge-betweenness", subtitle = round(network_modularity(friends, friend_eb), 3)) ``` @@ -570,9 +570,9 @@ autographr(friends, ```{r ebplot-solution} friends <- friends %>% mutate(eb_comm = friend_eb) -autographr(friends, - node_color = "eb_comm", - node_group = "eb_comm") + +graphr(friends, + node_color = "eb_comm", + node_group = "eb_comm") + ggtitle("Edge-betweenness", subtitle = round(network_modularity(friends, friend_eb), 3)) ``` @@ -597,7 +597,7 @@ although I personally find it both useful and in many cases quite "accurate". ``` ```{r fg-hint-1, purl = FALSE} -friend_fg <- node_fast_greedy(friends) +friend_fg <- node_in_greedy(friends) friend_fg # Does this result in a different community partition? network_modularity(friends, friend_fg) # Compare this to the edge betweenness procedure ``` @@ -606,25 +606,25 @@ network_modularity(friends, friend_fg) # Compare this to the edge betweenness pr # Again, we can visualise these communities in different ways: friends <- friends %>% mutate(fg_comm = friend_fg) -autographr(friends, - node_color = "fg_comm", - node_group = "fg_comm") + +graphr(friends, + node_color = "fg_comm", + node_group = "fg_comm") + ggtitle("Fast-greedy", subtitle = round(network_modularity(friends, friend_fg), 3)) # ``` ```{r fg-solution} -friend_fg <- node_fast_greedy(friends) +friend_fg <- node_in_greedy(friends) friend_fg # Does this result in a different community partition? network_modularity(friends, friend_fg) # Compare this to the edge betweenness procedure # Again, we can visualise these communities in different ways: friends <- friends %>% mutate(fg_comm = friend_fg) -autographr(friends, - node_color = "fg_comm", - node_group = "fg_comm") + +graphr(friends, + node_color = "fg_comm", + node_group = "fg_comm") + ggtitle("Fast-greedy", subtitle = round(network_modularity(friends, friend_fg), 3)) ``` @@ -659,14 +659,14 @@ ison_southern_women ``` ```{r setup-women-hint-2, purl = FALSE} -autographr(ison_southern_women, node_color = "type") -autographr(ison_southern_women, "railway", node_color = "type") +graphr(ison_southern_women, node_color = "type") +graphr(ison_southern_women, "railway", node_color = "type") ``` ```{r setup-women-solution} data("ison_southern_women") ison_southern_women -autographr(ison_southern_women, node_color = "type") +graphr(ison_southern_women, node_color = "type") ``` ### Project two-mode network into two one-mode networks @@ -699,7 +699,7 @@ Or the easy way: # ties to nodes in the second mode (columns) women_graph <- to_mode1(ison_southern_women) -autographr(women_graph) +graphr(women_graph) # note that projection `to_mode1` involves keeping one type of nodes # this is different from to_uniplex above, which keeps one type of ties in the network @@ -712,14 +712,14 @@ autographr(women_graph) # to nodes in the first mode (rows) event_graph <- to_mode2(ison_southern_women) -autographr(event_graph) +graphr(event_graph) ``` ```{r easyway-solution} women_graph <- to_mode1(ison_southern_women) -autographr(women_graph) +graphr(women_graph) event_graph <- to_mode2(ison_southern_women) -autographr(event_graph) +graphr(event_graph) ``` `{manynet}` also includes several other options for how to construct the projection. @@ -730,10 +730,10 @@ Please see the help file for more details. ``` ```{r otherway-solution} -autographr(to_mode2(ison_southern_women, similarity = "jaccard")) + ggtitle("Jaccard") + -autographr(to_mode2(ison_southern_women, similarity = "rand")) + ggtitle("Rand") + -autographr(to_mode2(ison_southern_women, similarity = "pearson")) + ggtitle("Pearson") + -autographr(to_mode2(ison_southern_women, similarity = "yule")) + ggtitle("Yule's Q") +graphr(to_mode2(ison_southern_women, similarity = "jaccard")) + ggtitle("Jaccard") + +graphr(to_mode2(ison_southern_women, similarity = "rand")) + ggtitle("Rand") + +graphr(to_mode2(ison_southern_women, similarity = "pearson")) + ggtitle("Pearson") + +graphr(to_mode2(ison_southern_women, similarity = "yule")) + ggtitle("Yule's Q") ``` Which women/events 'bind' which events/women? diff --git a/inst/tutorials/tutorial4/community.html b/inst/tutorials/tutorial4/community.html index c4f6f411..b2f88d0b 100644 --- a/inst/tutorials/tutorial4/community.html +++ b/inst/tutorials/tutorial4/community.html @@ -167,13 +167,13 @@

    Adding names

    -
    autographr(ison_algebra)
    +
    graphr(ison_algebra)
    ison_algebra <- to_named(ison_algebra)
    -autographr(ison_algebra)
    +graphr(ison_algebra)

    Note that you will likely get a different set of names, as they are assigned randomly from a pool of (American) first names.

    @@ -195,7 +195,7 @@

    Separating multiplex networks

    # to_uniplex extracts ties of a single type,
     # focusing on the 'friends' tie attribute here
     friends <- to_uniplex(ison_algebra, "friends")
    -gfriend <- autographr(friends) + ggtitle("Friendship")
    +gfriend <- graphr(friends) + ggtitle("Friendship")
    Separating multiplex networks data-pipe="|>">
    # now let's focus on the 'social' tie attribute
     social <- to_uniplex(ison_algebra, "social")
    -gsocial <- autographr(social) + ggtitle("Social")
    +gsocial <- graphr(social) + ggtitle("Social")
    Separating multiplex networks data-pipe="|>">
    # and the 'tasks' tie attribute
     tasks <- to_uniplex(ison_algebra, "tasks")
    -gtask <- autographr(tasks) + ggtitle("Task")
    +gtask <- graphr(tasks) + ggtitle("Task")
    Separating multiplex networks data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    friends <- to_uniplex(ison_algebra, "friends")
    -gfriend <- autographr(friends) + ggtitle("Friendship")
    +gfriend <- graphr(friends) + ggtitle("Friendship")
     
     social <- to_uniplex(ison_algebra, "social")
    -gsocial <- autographr(social) + ggtitle("Social")
    +gsocial <- graphr(social) + ggtitle("Social")
     
     tasks <- to_uniplex(ison_algebra, "tasks")
    -gtask <- autographr(tasks) + ggtitle("Task")
    +gtask <- graphr(tasks) + ggtitle("Task")
     
     # We now have three separate networks depicting each type of tie from the ison_algebra network:
     gfriend + gsocial + gtask
    -

    Note also that these are weighted networks. autographr() +

    Note also that these are weighted networks. graphr() automatically recognises these different weights and plots them. Where -useful (less dense directed networks), autographr() also -bends reciprocated arcs. What (else) can we say about these three +useful (less dense directed networks), graphr() also bends +reciprocated arcs. What (else) can we say about these three networks?

    @@ -389,7 +389,7 @@

    Components

    So we know how many components there are, but maybe we’re also interested in which nodes are members of which components? node_components() returns a membership vector that can be -used to color nodes in autographr():

    +used to color nodes in graphr():

    @@ -409,9 +409,9 @@

    Components

    -
    autographr(friends, node_color = "weak_comp") + ggtitle("Weak components") +
    -autographr(friends, node_color = "strong_comp") + ggtitle("Strong components")
    -# by using the 'node_color' argument, we are telling autographr to colour 
    +
    graphr(friends, node_color = "weak_comp") + ggtitle("Weak components") +
    +graphr(friends, node_color = "strong_comp") + ggtitle("Strong components")
    +# by using the 'node_color' argument, we are telling graphr to colour 
     # the nodes in the graph according to the values of the 'weak_comp' attribute in the network 
    Components
    friends <- friends %>% 
       mutate(weak_comp = node_components(to_undirected(friends)),
              strong_comp = node_components(friends))
    -autographr(friends, node_color = "weak_comp") + ggtitle("Weak components") +
    -autographr(friends, node_color = "strong_comp") + ggtitle("Strong components")
    +graphr(friends, node_color = "weak_comp") + ggtitle("Weak components") + +graphr(friends, node_color = "strong_comp") + ggtitle("Strong components")
    @@ -463,14 +463,14 @@

    Community Detection

    data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    # now, let's graph the new network
    -autographr(friends)
    +graphr(friends)
    (friends <- to_giant(friends))
     (friends <- to_undirected(friends))
    -autographr(friends)
    +graphr(friends)

    Comparing friends before and after these operations, you’ll notice the number of ties decreases as reciprocated directed ties @@ -524,7 +524,7 @@

    Walktrap

    # agglomerative algorithm based on random walks, and assign it to # an object -friend_wt <- node_walktrap(friends, times=50) +friend_wt <- node_in_walktrap(friends, times=50) friend_wt # note that it prints pretty, but underlying its just a vector:
    Walktrap
    -
    friend_wt <- node_walktrap(friends, times=50)
    +
    friend_wt <- node_in_walktrap(friends, times=50)
     friend_wt # note that it prints pretty, but underlying it is just a vector:
     # c(friend_wt)
     
    @@ -573,7 +573,7 @@ 

    Walktrap

    friends <- friends %>% mutate(walk_comm = friend_wt) -autographr(friends, node_color = "walk_comm")
    +graphr(friends, node_color = "walk_comm")
    Walktrap
    #plot 2: groups by borders
     
     # to be fancy, we could even draw the group borders around the nodes using the node_group argument
    -autographr(friends, node_group = "walk_comm")
    +graphr(friends, node_group = "walk_comm")
    Walktrap
    # plot 3: group and node colors
     
     # or both!
    -autographr(friends, 
    -           node_color = "walk_comm", 
    -           node_group = "walk_comm") +
    +graphr(friends,
    +       node_color = "walk_comm",
    +       node_group = "walk_comm") +
       ggtitle("Walktrap",
         subtitle = round(network_modularity(friends, friend_wt), 3))
     # the function `round()` rounds the values to a specified number of decimal places
    @@ -603,13 +603,13 @@ 

    Walktrap

    data-lines="0" data-pipe="|>">
    friends <- friends %>% 
       mutate(walk_comm = friend_wt)
    -autographr(friends, node_color = "walk_comm")
    +graphr(friends, node_color = "walk_comm")
     # to be fancy, we could even draw the group borders around the nodes using the node_group argument
    -autographr(friends, node_group = "walk_comm")
    +graphr(friends, node_group = "walk_comm")
     # or both!
    -autographr(friends, 
    -           node_color = "walk_comm", 
    -           node_group = "walk_comm") +
    +graphr(friends,
    +       node_color = "walk_comm",
    +       node_group = "walk_comm") +
       ggtitle("Walktrap",
         subtitle = round(network_modularity(friends, friend_wt), 3))
    @@ -638,7 +638,7 @@

    Edge Betweenness

    -
    friend_eb <- node_edge_betweenness(friends)
    +
    friend_eb <- node_in_betweenness(friends)
     friend_eb

    How does community membership differ here from that found by @@ -666,9 +666,9 @@

    Edge Betweenness

    data-lines="0" data-pipe="|>">
    # create a graph with a title and subtitle returning the modularity score
     
    -autographr(friends, 
    -           node_color = "eb_comm", 
    -           node_group = "eb_comm") +
    +graphr(friends,
    +       node_color = "eb_comm",
    +       node_group = "eb_comm") +
       ggtitle("Edge-betweenness",
         subtitle = round(network_modularity(friends, friend_eb), 3))
    @@ -677,9 +677,9 @@

    Edge Betweenness

    data-lines="0" data-pipe="|>">
    friends <- friends %>% 
       mutate(eb_comm = friend_eb)
    -autographr(friends, 
    -           node_color = "eb_comm", 
    -           node_group = "eb_comm") +
    +graphr(friends,
    +       node_color = "eb_comm",
    +       node_group = "eb_comm") +
       ggtitle("Edge-betweenness",
         subtitle = round(network_modularity(friends, friend_eb), 3))
    @@ -706,7 +706,7 @@

    Fast Greedy

    -
    friend_fg <- node_fast_greedy(friends)
    +
    friend_fg <- node_in_greedy(friends)
     friend_fg # Does this result in a different community partition?
     network_modularity(friends, friend_fg) # Compare this to the edge betweenness procedure
    @@ -716,9 +716,9 @@

    Fast Greedy

    # Again, we can visualise these communities in different ways:
     friends <- friends %>% 
       mutate(fg_comm = friend_fg)
    -autographr(friends, 
    -           node_color = "fg_comm", 
    -           node_group = "fg_comm") +
    +graphr(friends,
    +       node_color = "fg_comm",
    +       node_group = "fg_comm") +
       ggtitle("Fast-greedy",
         subtitle = round(network_modularity(friends, friend_fg), 3))
     # 
    @@ -726,16 +726,16 @@

    Fast Greedy

    -
    friend_fg <- node_fast_greedy(friends)
    +
    friend_fg <- node_in_greedy(friends)
     friend_fg # Does this result in a different community partition?
     network_modularity(friends, friend_fg) # Compare this to the edge betweenness procedure
     
     # Again, we can visualise these communities in different ways:
     friends <- friends %>% 
       mutate(fg_comm = friend_fg)
    -autographr(friends, 
    -           node_color = "fg_comm", 
    -           node_group = "fg_comm") +
    +graphr(friends,
    +       node_color = "fg_comm",
    +       node_group = "fg_comm") +
       ggtitle("Fast-greedy",
         subtitle = round(network_modularity(friends, friend_fg), 3))
    @@ -772,15 +772,15 @@

    Two-mode network: Southern women

    -
    autographr(ison_southern_women, node_color = "type")
    -autographr(ison_southern_women, "railway", node_color = "type")
    +
    graphr(ison_southern_women, node_color = "type")
    +graphr(ison_southern_women, "railway", node_color = "type")
    data("ison_southern_women")
     ison_southern_women
    -autographr(ison_southern_women, node_color = "type")
    +graphr(ison_southern_women, node_color = "type")
    @@ -815,7 +815,7 @@

    Project two-mode network into two one-mode networks

    # ties to nodes in the second mode (columns) women_graph <- to_mode1(ison_southern_women) -autographr(women_graph) +graphr(women_graph) # note that projection `to_mode1` involves keeping one type of nodes # this is different from to_uniplex above, which keeps one type of ties in the network
    @@ -829,15 +829,15 @@

    Project two-mode network into two one-mode networks

    # to nodes in the first mode (rows) event_graph <- to_mode2(ison_southern_women) -autographr(event_graph) +graphr(event_graph)
    women_graph <- to_mode1(ison_southern_women)
    -autographr(women_graph)
    +graphr(women_graph)
     event_graph <- to_mode2(ison_southern_women)
    -autographr(event_graph)
    +graphr(event_graph)

    {manynet} also includes several other options for how to construct the projection. Please see the help file for more details.

    @@ -849,10 +849,10 @@

    Project two-mode network into two one-mode networks

    -
    autographr(to_mode2(ison_southern_women, similarity = "jaccard")) + ggtitle("Jaccard") +
    -autographr(to_mode2(ison_southern_women, similarity = "rand")) + ggtitle("Rand") +
    -autographr(to_mode2(ison_southern_women, similarity = "pearson")) + ggtitle("Pearson") +
    -autographr(to_mode2(ison_southern_women, similarity = "yule")) + ggtitle("Yule's Q")
    +
    graphr(to_mode2(ison_southern_women, similarity = "jaccard")) + ggtitle("Jaccard") +
    +graphr(to_mode2(ison_southern_women, similarity = "rand")) + ggtitle("Rand") +
    +graphr(to_mode2(ison_southern_women, similarity = "pearson")) + ggtitle("Pearson") +
    +graphr(to_mode2(ison_southern_women, similarity = "yule")) + ggtitle("Yule's Q")

    Which women/events ‘bind’ which events/women? Let’s return to the question of cohesion.

    @@ -905,6 +905,10 @@

    Task/Unit Test

    library(manynet) library(migraph) knitr::opts_chunk$set(echo = FALSE) + +friends <- to_uniplex(ison_algebra, "friends") +social <- to_uniplex(ison_algebra, "social") +tasks <- to_uniplex(ison_algebra, "tasks") @@ -938,10 +942,12 @@

    Task/Unit Test

    @@ -1185,16 +1199,18 @@

    Task/Unit Test

    @@ -1312,12 +1330,12 @@

    Task/Unit Test

    @@ -1345,16 +1363,18 @@

    Task/Unit Test

    @@ -1423,19 +1443,21 @@

    Task/Unit Test

    @@ -1505,26 +1527,27 @@

    Task/Unit Test

    @@ -1831,14 +1864,16 @@

    Task/Unit Test

    diff --git a/inst/tutorials/tutorial5/position.Rmd b/inst/tutorials/tutorial5/position.Rmd index 6ee5a281..7cafcd12 100644 --- a/inst/tutorials/tutorial5/position.Rmd +++ b/inst/tutorials/tutorial5/position.Rmd @@ -78,25 +78,25 @@ ____ <- to_uniplex(ison_algebra, _____) # Now, let's compare the each attribute's graph, side-by-side by using "+" # Note: using "/" after each graph will order them vertically; however, it might not be best way # See for example: -gfriend <- autographr(friends) + ggtitle("Friendship") +gfriend <- graphr(friends) + ggtitle("Friendship") gfriend + gsocial + gtask ``` ```{r separatingnets-solution} friends <- to_uniplex(ison_algebra, "friends") -gfriend <- autographr(friends) + ggtitle("Friendship") +gfriend <- graphr(friends) + ggtitle("Friendship") social <- to_uniplex(ison_algebra, "social") -gsocial <- autographr(social) + ggtitle("Social") +gsocial <- graphr(social) + ggtitle("Social") tasks <- to_uniplex(ison_algebra, "tasks") -gtask <- autographr(tasks) + ggtitle("Task") +gtask <- graphr(tasks) + ggtitle("Task") gfriend + gsocial + gtask ``` Note also that these are weighted networks. -`autographr()` automatically recognises these different weights and plots them. +`graphr()` automatically recognises these different weights and plots them. ```{r strongties-qa, echo=FALSE, purl = FALSE} question("If we interpret ties with higher weights as strong ties, and lesser weights as weak ties, then, according to network theory, where would we expect novel information to come from?", @@ -204,18 +204,18 @@ tasks <- tasks %>% # Note 1: we are looking at the 'tasks' network # Note 2: we are interested in the actors 'least constrained' by their position -autographr(____, node_color = "____") +graphr(____, node_color = "____") ``` ```{r constraintplot-hint-4, purl = FALSE} -autographr(tasks, node_size = "constraint", node_color = "low_constraint") +graphr(tasks, node_size = "constraint", node_color = "low_constraint") ``` ```{r constraintplot-solution} tasks <- tasks %>% mutate(constraint = node_constraint(tasks), low_constraint = node_is_min(node_constraint(tasks))) -autographr(tasks, node_size = "constraint", node_color = "low_constraint") +graphr(tasks, node_size = "constraint", node_color = "low_constraint") ``` Why minimum? Because constraint measures how well connected each node's partners are, @@ -252,11 +252,11 @@ In `{migraph}`, finding how the nodes of a network can be partitioned into structurally equivalent classes can be as easy as: ```{r find-se, exercise = TRUE, exercise.setup = "data"} -node_structural_equivalence(ison_algebra) +node_in_structural(ison_algebra) ison_algebra %>% - mutate(se = node_structural_equivalence(ison_algebra)) %>% - autographr(node_color = "se") + mutate(se = node_in_structural(ison_algebra)) %>% + graphr(node_color = "se") ``` But actually, a lot is going on behind the scenes here that we can unpack. @@ -268,7 +268,7 @@ how these classes are identified and how to interpret them. All equivalence classes are based on nodes' similarity across some profile of motifs. In `{migraph}`, we call these motif *censuses*. Any kind of census can be used, and `{migraph}` includes a few options, -but `node_structural_equivalence()` is based off of the census of all the nodes' ties, +but `node_in_structural()` is based off of the census of all the nodes' ties, both outgoing and incoming ties, to characterise their relationships to tie partners. ```{r construct-cor, exercise = TRUE, exercise.setup = "data", purl = FALSE} @@ -321,18 +321,18 @@ ison_algebra %>% node_tie_census() ``` -Note that `node_tie_census()` does not need to be passed to `node_structural_equivalence()` --- +Note that `node_tie_census()` does not need to be passed to `node_in_structural()` --- this is done automatically! -However, the more generic `node_equivalence()` is available and can be used with whichever tie census is desired. +However, the more generic `node_in_equivalence()` is available and can be used with whichever tie census is desired. Feel free to explore using some of the other censuses available in `{migraph}`, though some common ones are already used in the other equivalence convenience functions, -e.g. `node_triad_census()` in `node_regular_equivalence()` -and `node_path_census()` in `node_automorphic_equivalence()`. +e.g. `node_triad_census()` in `node_in_regular()` +and `node_path_census()` in `node_in_automorphic()`. ### Step two: growing a tree of similarity The next part takes this census and creates a dendrogram based on distance or dissimilarity among the nodes' census profiles. -This is all done internally within e.g. `node_structural_equivalence()`, +This is all done internally within e.g. `node_in_structural()`, though there are two important parameters that can be set to obtain different results. First, users can set the type of distance measure used. @@ -346,20 +346,17 @@ but for compatibility and enthusiasts, we also offer `"concor"`, which implements a CONCOR (CONvergence of CORrelations) algorithm. We can see the difference from varying the clustering algorithm and/or distance -by plotting the dendrograms (hidden) in the output from `node_structural_equivalence()`: +by plotting the dendrograms (hidden) in the output from `node_in_structural()`: ```{r varyclust, exercise = TRUE, exercise.setup = "data"} alge <- to_named(ison_algebra) # fake names to make comparison clearer -plot(node_structural_equivalence(alge, - cluster = "hier", distance = "euclidean")) +plot(node_in_structural(alge, cluster = "hier", distance = "euclidean")) # changing the type of distance used -plot(node_structural_equivalence(alge, - cluster = "hier", distance = "manhattan")) +plot(node_in_structural(alge, cluster = "hier", distance = "manhattan")) # changing the clustering algorithm -plot(node_structural_equivalence(alge, - cluster = "concor", distance = "euclidean")) +plot(node_in_structural(alge, cluster = "concor", distance = "euclidean")) ``` ```{r scale-interp, echo = FALSE, purl = FALSE} @@ -408,7 +405,7 @@ the more dissimilar we're allowing nodes in the same cluster to be. We could set this ourselves by just passing `k` an integer. ```{r k-discrete, exercise = TRUE, exercise.setup = "varyclust"} -plot(node_structural_equivalence(alge, k = 2)) +plot(node_in_structural(alge, k = 2)) ``` But we're really just guessing. Maybe 2 is not the best `k`? @@ -452,10 +449,8 @@ can return a somewhat different result to the elbow method. See what we have here, with all other arguments held the same: ```{r elbowsil, exercise = TRUE, exercise.setup = "varyclust"} -plot(node_structural_equivalence(alge, - k = "elbow")) -plot(node_structural_equivalence(alge, - k = "silhouette")) +plot(node_in_structural(alge, k = "elbow")) +plot(node_in_structural(alge, k = "silhouette")) ``` Ok, so it looks like the elbow method returns `k == 3` as a good trade-off @@ -482,7 +477,7 @@ however oftentimes this misses the point in finding clusters of nodes that, despite some variation, can be considered as similar on some dimension. ```{r strict, exercise = TRUE, exercise.setup = "varyclust"} -plot(node_structural_equivalence(alge, k = "strict")) +plot(node_in_structural(alge, k = "strict")) ``` Here for example, no two nodes have precisely the same tie-profile, @@ -501,8 +496,8 @@ We can graph this of course, as above: ```{r strplot, exercise = TRUE, exercise.setup = "varyclust"} alge %>% - mutate(se = node_structural_equivalence(alge)) %>% - autographr(node_color = "se") + mutate(se = node_in_structural(alge)) %>% + graphr(node_color = "se") ``` While this plot adds the structurally equivalent classes information to our earlier graph, @@ -529,7 +524,7 @@ summary(node_tie_census(____), ```{r summ-solution} summary(node_tie_census(alge), - membership = node_structural_equivalence(alge)) + membership = node_in_structural(alge)) ``` This node census produces 96 columns, @@ -558,15 +553,15 @@ plot(as_matrix(____), ```{r block-solution} # plot the blockmodel for the whole network plot(as_matrix(alge), - membership = node_structural_equivalence(alge)) + membership = node_in_structural(alge)) # plot the blockmodel for the friends, tasks, and social networks separately plot(as_matrix(friends), - membership = node_structural_equivalence(alge)) + + membership = node_in_structural(alge)) + plot(as_matrix(tasks), - membership = node_structural_equivalence(alge)) + + membership = node_in_structural(alge)) + plot(as_matrix(social), - membership = node_structural_equivalence(alge)) + membership = node_in_structural(alge)) ``` By passing the membership argument our structural equivalence results, @@ -602,9 +597,9 @@ because even if the original network was simple (not complex), any within-class ties will end up becoming loops and thus the network will be complex. ```{r structblock, exercise = TRUE, exercise.setup = "varyclust", warning=FALSE} -(bm <- to_blocks(alge, node_structural_equivalence(alge))) +(bm <- to_blocks(alge, node_in_structural(alge))) bm <- bm %>% as_tidygraph %>% mutate(name = c("Freaks", "Squares", "Nerds", "Geek")) -autographr(bm) +graphr(bm) ``` diff --git a/inst/tutorials/tutorial5/position.html b/inst/tutorials/tutorial5/position.html index 37f9f87f..547e7363 100644 --- a/inst/tutorials/tutorial5/position.html +++ b/inst/tutorials/tutorial5/position.html @@ -176,7 +176,7 @@

    Separating multiplex networks

    # Now, let's compare the each attribute's graph, side-by-side by using "+"
     # Note: using "/" after each graph will order them vertically; however, it might not be best way
     # See for example:
    -gfriend <- autographr(friends) + ggtitle("Friendship")
    +gfriend <- graphr(friends) + ggtitle("Friendship")
     gfriend + gsocial + gtask
    Separating multiplex networks data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    friends <- to_uniplex(ison_algebra, "friends")
    -gfriend <- autographr(friends) + ggtitle("Friendship")
    +gfriend <- graphr(friends) + ggtitle("Friendship")
     
     social <- to_uniplex(ison_algebra, "social")
    -gsocial <- autographr(social) + ggtitle("Social")
    +gsocial <- graphr(social) + ggtitle("Social")
     
     tasks <- to_uniplex(ison_algebra, "tasks")
    -gtask <- autographr(tasks) + ggtitle("Task")
    +gtask <- graphr(tasks) + ggtitle("Task")
     
     gfriend + gsocial + gtask
    -

    Note also that these are weighted networks. autographr() +

    Note also that these are weighted networks. graphr() automatically recognises these different weights and plots them.

    @@ -276,13 +276,13 @@

    Measuring structural holes

    # Note 1: we are looking at the 'tasks' network # Note 2: we are interested in the actors 'least constrained' by their position -autographr(____, node_color = "____") +graphr(____, node_color = "____")
    -
    autographr(tasks, node_size = "constraint", node_color = "low_constraint")
    +
    graphr(tasks, node_size = "constraint", node_color = "low_constraint")
    Measuring structural holes
    tasks <- tasks %>% 
       mutate(constraint = node_constraint(tasks), 
              low_constraint = node_is_min(node_constraint(tasks)))
    -autographr(tasks, node_size = "constraint", node_color = "low_constraint")
    +graphr(tasks, node_size = "constraint", node_color = "low_constraint")

    Why minimum? Because constraint measures how well connected each node’s partners are, with the implication that having few partners that @@ -326,11 +326,11 @@

    Finding structurally equivalent classes

    -
    node_structural_equivalence(ison_algebra)
    +
    node_in_structural(ison_algebra)
     
     ison_algebra %>% 
    -  mutate(se = node_structural_equivalence(ison_algebra)) %>% 
    -  autographr(node_color = "se")
    + mutate(se = node_in_structural(ison_algebra)) %>% + graphr(node_color = "se")

    But actually, a lot is going on behind the scenes here that we can @@ -345,9 +345,9 @@

    Step one: starting with a census

    profile of motifs. In {migraph}, we call these motif censuses. Any kind of census can be used, and {migraph} includes a few options, but -node_structural_equivalence() is based off of the census of -all the nodes’ ties, both outgoing and incoming ties, to characterise -their relationships to tie partners.

    +node_in_structural() is based off of the census of all the +nodes’ ties, both outgoing and incoming ties, to characterise their +relationships to tie partners.

    @@ -407,25 +407,24 @@

    Step one: starting with a census

    node_tie_census()

    Note that node_tie_census() does not need to be passed -to node_structural_equivalence() — this is done -automatically! However, the more generic node_equivalence() -is available and can be used with whichever tie census is desired. Feel +to node_in_structural() — this is done automatically! +However, the more generic node_in_equivalence() is +available and can be used with whichever tie census is desired. Feel free to explore using some of the other censuses available in {migraph}, though some common ones are already used in the other equivalence convenience functions, -e.g. node_triad_census() in -node_regular_equivalence() and -node_path_census() in -node_automorphic_equivalence().

    +e.g. node_triad_census() in node_in_regular() +and node_path_census() in +node_in_automorphic().

    Step two: growing a tree of similarity

    The next part takes this census and creates a dendrogram based on distance or dissimilarity among the nodes’ census profiles. This is all -done internally within e.g. node_structural_equivalence(), -though there are two important parameters that can be set to obtain -different results.

    +done internally within e.g. node_in_structural(), though +there are two important parameters that can be set to obtain different +results.

    First, users can set the type of distance measure used. For enthusiasts, this is passed on to stats::dist(), so that help page should be consulted for more details. By default @@ -437,21 +436,18 @@

    Step two: growing a tree of similarity

    (CONvergence of CORrelations) algorithm.

    We can see the difference from varying the clustering algorithm and/or distance by plotting the dendrograms (hidden) in the output from -node_structural_equivalence():

    +node_in_structural():

    alge <- to_named(ison_algebra) # fake names to make comparison clearer
    -plot(node_structural_equivalence(alge, 
    -                                 cluster = "hier", distance = "euclidean"))
    +plot(node_in_structural(alge, cluster = "hier", distance = "euclidean"))
     
     # changing the type of distance used
    -plot(node_structural_equivalence(alge, 
    -                                 cluster = "hier", distance = "manhattan"))
    +plot(node_in_structural(alge, cluster = "hier", distance = "manhattan"))
     
     # changing the clustering algorithm
    -plot(node_structural_equivalence(alge, 
    -                                 cluster = "concor", distance = "euclidean"))
    +plot(node_in_structural(alge, cluster = "concor", distance = "euclidean"))
    @@ -500,7 +496,7 @@

    Step three: identifying the number of clusters

    -
    plot(node_structural_equivalence(alge, k = 2))
    +
    plot(node_in_structural(alge, k = 2))

    But we’re really just guessing. Maybe 2 is not the best @@ -538,10 +534,8 @@

    Step three: identifying the number of clusters

    -
    plot(node_structural_equivalence(alge, 
    -                                 k = "elbow"))
    -plot(node_structural_equivalence(alge, 
    -                                 k = "silhouette"))
    +
    plot(node_in_structural(alge, k = "elbow"))
    +plot(node_in_structural(alge, k = "silhouette"))

    Ok, so it looks like the elbow method returns k == 3 as @@ -566,7 +560,7 @@

    Step three: identifying the number of clusters

    -
    plot(node_structural_equivalence(alge, k = "strict"))
    +
    plot(node_in_structural(alge, k = "strict"))

    Here for example, no two nodes have precisely the same tie-profile, @@ -589,8 +583,8 @@

    Summarising profiles

    data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    alge %>% 
    -  mutate(se = node_structural_equivalence(alge)) %>% 
    -  autographr(node_color = "se")
    + mutate(se = node_in_structural(alge)) %>% + graphr(node_color = "se")

    While this plot adds the structurally equivalent classes information @@ -621,7 +615,7 @@

    Summarising profiles

    data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    summary(node_tie_census(alge),
    -        membership = node_structural_equivalence(alge))
    + membership = node_in_structural(alge))

    This node census produces 96 columns, \(16 \text{nodes} * 2 \text{directions} * 3 \text{edge types}\), it @@ -652,15 +646,15 @@

    Summarising profiles

    data-lines="0" data-pipe="|>">
    # plot the blockmodel for the whole network
     plot(as_matrix(alge),
    -     membership = node_structural_equivalence(alge))
    +     membership = node_in_structural(alge))
     
     # plot the blockmodel for the friends, tasks, and social networks separately
     plot(as_matrix(friends),
    -     membership = node_structural_equivalence(alge)) +
    +     membership = node_in_structural(alge)) +
     plot(as_matrix(tasks),
    -     membership = node_structural_equivalence(alge)) +
    +     membership = node_in_structural(alge)) +
     plot(as_matrix(social),
    -     membership = node_structural_equivalence(alge))
    + membership = node_in_structural(alge))

    By passing the membership argument our structural equivalence results, the matrix is re-sorted to cluster or ‘block’ nodes from the @@ -700,11 +694,11 @@

    Reduced graph

    -
    (bm <- to_blocks(alge, node_structural_equivalence(alge)))
    +
    (bm <- to_blocks(alge, node_in_structural(alge)))
     
     bm <- bm %>% as_tidygraph %>% 
       mutate(name = c("Freaks", "Squares", "Nerds", "Geek"))
    -autographr(bm)
    +graphr(bm)

    @@ -797,9 +791,9 @@

    Reduced graph

    code = "", opts = list(label = "\"separatingnets\"", exercise = "TRUE", exercise.setup = "\"data\"", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("friends <- to_uniplex(ison_algebra, \"friends\")", - "gfriend <- autographr(friends) + ggtitle(\"Friendship\")", - "", "social <- to_uniplex(ison_algebra, \"social\")", "gsocial <- autographr(social) + ggtitle(\"Social\")", - "", "tasks <- to_uniplex(ison_algebra, \"tasks\")", "gtask <- autographr(tasks) + ggtitle(\"Task\")", + "gfriend <- graphr(friends) + ggtitle(\"Friendship\")", "", + "social <- to_uniplex(ison_algebra, \"social\")", "gsocial <- graphr(social) + ggtitle(\"Social\")", + "", "tasks <- to_uniplex(ison_algebra, \"tasks\")", "gtask <- graphr(tasks) + ggtitle(\"Task\")", "", "gfriend + gsocial + gtask"), chunk_opts = list(label = "separatingnets-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -828,22 +822,22 @@

    Reduced graph

    @@ -861,28 +855,28 @@

    Reduced graph

    @@ -996,7 +990,7 @@

    Reduced graph

    engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("tasks <- tasks %>% ", " mutate(constraint = node_constraint(tasks), ", " low_constraint = node_is_min(node_constraint(tasks)))", - "autographr(tasks, node_size = \"constraint\", node_color = \"low_constraint\")" + "graphr(tasks, node_size = \"constraint\", node_color = \"low_constraint\")" ), chunk_opts = list(label = "constraintplot-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -1025,17 +1019,17 @@

    Reduced graph

    @@ -1067,7 +1061,7 @@

    Reduced graph

    include = FALSE)), setup = "", chunks = list(list(label = "data", code = "", opts = list(label = "\"data\"", exercise = "TRUE", purl = "FALSE"), engine = "r"), list(label = "find-se", - code = "node_structural_equivalence(ison_algebra)\n\nison_algebra %>% \n mutate(se = node_structural_equivalence(ison_algebra)) %>% \n autographr(node_color = \"se\")", + code = "node_in_structural(ison_algebra)\n\nison_algebra %>% \n mutate(se = node_in_structural(ison_algebra)) %>% \n graphr(node_color = \"se\")", opts = list(label = "\"find-se\"", exercise = "TRUE", exercise.setup = "\"data\""), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = NULL, tests = NULL, options = list(eval = FALSE, @@ -1087,9 +1081,9 @@

    Reduced graph

    message = TRUE, render = NULL, ref.label = NULL, child = NULL, engine = "r", split = FALSE, include = TRUE, purl = TRUE, max.print = 1000, label = "find-se", exercise = TRUE, - exercise.setup = "data", code = c("node_structural_equivalence(ison_algebra)", - "", "ison_algebra %>% ", " mutate(se = node_structural_equivalence(ison_algebra)) %>% ", - " autographr(node_color = \"se\")"), out.width.px = 624, + exercise.setup = "data", code = c("node_in_structural(ison_algebra)", + "", "ison_algebra %>% ", " mutate(se = node_in_structural(ison_algebra)) %>% ", + " graphr(node_color = \"se\")"), out.width.px = 624, out.height.px = 384, params.src = "find-se, exercise = TRUE, exercise.setup = \"data\"", fig.num = 0, exercise.df_print = "paged", exercise.checker = "NULL"), engine = "r", version = "4"), class = c("r", "tutorial_exercise" @@ -1199,7 +1193,7 @@

    Reduced graph

    include = FALSE)), setup = "", chunks = list(list(label = "data", code = "", opts = list(label = "\"data\"", exercise = "TRUE", purl = "FALSE"), engine = "r"), list(label = "varyclust", - code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", opts = list(label = "\"varyclust\"", exercise = "TRUE", exercise.setup = "\"data\""), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = NULL, tests = NULL, options = list(eval = FALSE, @@ -1220,11 +1214,9 @@

    Reduced graph

    engine = "r", split = FALSE, include = TRUE, purl = TRUE, max.print = 1000, label = "varyclust", exercise = TRUE, exercise.setup = "data", code = c("alge <- to_named(ison_algebra) # fake names to make comparison clearer", - "plot(node_structural_equivalence(alge, ", " cluster = \"hier\", distance = \"euclidean\"))", - "", "# changing the type of distance used", "plot(node_structural_equivalence(alge, ", - " cluster = \"hier\", distance = \"manhattan\"))", - "", "# changing the clustering algorithm", "plot(node_structural_equivalence(alge, ", - " cluster = \"concor\", distance = \"euclidean\"))" + "plot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))", + "", "# changing the type of distance used", "plot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))", + "", "# changing the clustering algorithm", "plot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))" ), out.width.px = 624, out.height.px = 384, params.src = "varyclust, exercise = TRUE, exercise.setup = \"data\"", fig.num = 0, exercise.df_print = "paged", exercise.checker = "NULL"), engine = "r", version = "4"), class = c("r", "tutorial_exercise" @@ -1234,11 +1226,11 @@

    Reduced graph

    @@ -1265,13 +1257,13 @@

    Reduced graph

    learnr:::store_exercise_cache(structure(list(label = "k-discrete", global_setup = structure(c("library(learnr)", "library(manynet)", "library(migraph)", "library(patchwork)", "knitr::opts_chunk$set(echo = FALSE)"), chunk_opts = list(label = "setup", - include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", chunks = list(list(label = "data", code = "", opts = list( label = "\"data\"", exercise = "TRUE", purl = "FALSE"), - engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", opts = list(label = "\"varyclust\"", exercise = "TRUE", exercise.setup = "\"data\""), engine = "r"), list( - label = "k-discrete", code = "plot(node_structural_equivalence(alge, k = 2))", + label = "k-discrete", code = "plot(node_in_structural(alge, k = 2))", opts = list(label = "\"k-discrete\"", exercise = "TRUE", exercise.setup = "\"varyclust\""), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = NULL, @@ -1292,7 +1284,7 @@

    Reduced graph

    message = TRUE, render = NULL, ref.label = NULL, child = NULL, engine = "r", split = FALSE, include = TRUE, purl = TRUE, max.print = 1000, label = "k-discrete", exercise = TRUE, - exercise.setup = "varyclust", code = "plot(node_structural_equivalence(alge, k = 2))", + exercise.setup = "varyclust", code = "plot(node_in_structural(alge, k = 2))", out.width.px = 624, out.height.px = 384, params.src = "k-discrete, exercise = TRUE, exercise.setup = \"varyclust\"", fig.num = 0, exercise.df_print = "paged", exercise.checker = "NULL"), engine = "r", version = "4"), class = c("r", "tutorial_exercise" @@ -1311,13 +1303,13 @@

    Reduced graph

    learnr:::store_exercise_cache(structure(list(label = "elbowsil", global_setup = structure(c("library(learnr)", "library(manynet)", "library(migraph)", "library(patchwork)", "knitr::opts_chunk$set(echo = FALSE)"), chunk_opts = list(label = "setup", - include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", chunks = list(list(label = "data", code = "", opts = list( label = "\"data\"", exercise = "TRUE", purl = "FALSE"), - engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", opts = list(label = "\"varyclust\"", exercise = "TRUE", exercise.setup = "\"data\""), engine = "r"), list( - label = "elbowsil", code = "plot(node_structural_equivalence(alge, \n k = \"elbow\"))\nplot(node_structural_equivalence(alge, \n k = \"silhouette\"))", + label = "elbowsil", code = "plot(node_in_structural(alge, k = \"elbow\"))\nplot(node_in_structural(alge, k = \"silhouette\"))", opts = list(label = "\"elbowsil\"", exercise = "TRUE", exercise.setup = "\"varyclust\""), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = NULL, @@ -1338,10 +1330,9 @@

    Reduced graph

    message = TRUE, render = NULL, ref.label = NULL, child = NULL, engine = "r", split = FALSE, include = TRUE, purl = TRUE, max.print = 1000, label = "elbowsil", exercise = TRUE, - exercise.setup = "varyclust", code = c("plot(node_structural_equivalence(alge, ", - " k = \"elbow\"))", "plot(node_structural_equivalence(alge, ", - " k = \"silhouette\"))" - ), out.width.px = 624, out.height.px = 384, params.src = "elbowsil, exercise = TRUE, exercise.setup = \"varyclust\"", + exercise.setup = "varyclust", code = c("plot(node_in_structural(alge, k = \"elbow\"))", + "plot(node_in_structural(alge, k = \"silhouette\"))"), + out.width.px = 624, out.height.px = 384, params.src = "elbowsil, exercise = TRUE, exercise.setup = \"varyclust\"", fig.num = 0, exercise.df_print = "paged", exercise.checker = "NULL"), engine = "r", version = "4"), class = c("r", "tutorial_exercise" ))) @@ -1359,13 +1350,13 @@

    Reduced graph

    learnr:::store_exercise_cache(structure(list(label = "strict", global_setup = structure(c("library(learnr)", "library(manynet)", "library(migraph)", "library(patchwork)", "knitr::opts_chunk$set(echo = FALSE)"), chunk_opts = list(label = "setup", - include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", chunks = list(list(label = "data", code = "", opts = list( label = "\"data\"", exercise = "TRUE", purl = "FALSE"), - engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", opts = list(label = "\"varyclust\"", exercise = "TRUE", exercise.setup = "\"data\""), engine = "r"), list( - label = "strict", code = "plot(node_structural_equivalence(alge, k = \"strict\"))", + label = "strict", code = "plot(node_in_structural(alge, k = \"strict\"))", opts = list(label = "\"strict\"", exercise = "TRUE", exercise.setup = "\"varyclust\""), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = NULL, @@ -1386,7 +1377,7 @@

    Reduced graph

    message = TRUE, render = NULL, ref.label = NULL, child = NULL, engine = "r", split = FALSE, include = TRUE, purl = TRUE, max.print = 1000, label = "strict", exercise = TRUE, - exercise.setup = "varyclust", code = "plot(node_structural_equivalence(alge, k = \"strict\"))", + exercise.setup = "varyclust", code = "plot(node_in_structural(alge, k = \"strict\"))", out.width.px = 624, out.height.px = 384, params.src = "strict, exercise = TRUE, exercise.setup = \"varyclust\"", fig.num = 0, exercise.df_print = "paged", exercise.checker = "NULL"), engine = "r", version = "4"), class = c("r", "tutorial_exercise" @@ -1405,13 +1396,13 @@

    Reduced graph

    learnr:::store_exercise_cache(structure(list(label = "strplot", global_setup = structure(c("library(learnr)", "library(manynet)", "library(migraph)", "library(patchwork)", "knitr::opts_chunk$set(echo = FALSE)"), chunk_opts = list(label = "setup", - include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", chunks = list(list(label = "data", code = "", opts = list( label = "\"data\"", exercise = "TRUE", purl = "FALSE"), - engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", opts = list(label = "\"varyclust\"", exercise = "TRUE", exercise.setup = "\"data\""), engine = "r"), list( - label = "strplot", code = "alge %>% \n mutate(se = node_structural_equivalence(alge)) %>% \n autographr(node_color = \"se\")", + label = "strplot", code = "alge %>% \n mutate(se = node_in_structural(alge)) %>% \n graphr(node_color = \"se\")", opts = list(label = "\"strplot\"", exercise = "TRUE", exercise.setup = "\"varyclust\""), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = NULL, @@ -1432,8 +1423,8 @@

    Reduced graph

    message = TRUE, render = NULL, ref.label = NULL, child = NULL, engine = "r", split = FALSE, include = TRUE, purl = TRUE, max.print = 1000, label = "strplot", exercise = TRUE, - exercise.setup = "varyclust", code = c("alge %>% ", " mutate(se = node_structural_equivalence(alge)) %>% ", - " autographr(node_color = \"se\")"), out.width.px = 624, + exercise.setup = "varyclust", code = c("alge %>% ", " mutate(se = node_in_structural(alge)) %>% ", + " graphr(node_color = \"se\")"), out.width.px = 624, out.height.px = 384, params.src = "strplot, exercise = TRUE, exercise.setup = \"varyclust\"", fig.num = 0, exercise.df_print = "paged", exercise.checker = "NULL"), engine = "r", version = "4"), class = c("r", "tutorial_exercise" @@ -1452,29 +1443,28 @@

    Reduced graph

    learnr:::store_exercise_cache(structure(list(label = "summ", global_setup = structure(c("library(learnr)", "library(manynet)", "library(migraph)", "library(patchwork)", "knitr::opts_chunk$set(echo = FALSE)"), chunk_opts = list(label = "setup", - include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))\nalge %>% \n mutate(se = node_structural_equivalence(alge)) %>% \n autographr(node_color = \"se\")", + include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))\nalge %>% \n mutate(se = node_in_structural(alge)) %>% \n graphr(node_color = \"se\")", chunks = list(list(label = "data", code = "", opts = list( label = "\"data\"", exercise = "TRUE", purl = "FALSE"), - engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", opts = list(label = "\"varyclust\"", exercise = "TRUE", exercise.setup = "\"data\""), engine = "r"), list( - label = "strplot", code = "alge %>% \n mutate(se = node_structural_equivalence(alge)) %>% \n autographr(node_color = \"se\")", + label = "strplot", code = "alge %>% \n mutate(se = node_in_structural(alge)) %>% \n graphr(node_color = \"se\")", opts = list(label = "\"strplot\"", exercise = "TRUE", exercise.setup = "\"varyclust\""), engine = "r"), list(label = "summ", code = "", opts = list(label = "\"summ\"", exercise = "TRUE", exercise.setup = "\"strplot\"", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("summary(node_tie_census(alge),", - " membership = node_structural_equivalence(alge))" - ), chunk_opts = list(label = "summ-solution")), tests = NULL, - options = list(eval = FALSE, echo = TRUE, results = "markup", - tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, - comment = NA, highlight = FALSE, size = "normalsize", - background = "#F7F7F7", strip.white = TRUE, cache = 0, - cache.path = "position_cache/html/", cache.vars = NULL, - cache.lazy = TRUE, dependson = NULL, autodep = FALSE, - cache.rebuild = FALSE, fig.keep = "high", fig.show = "asis", - fig.align = "default", fig.path = "position_files/figure-html/", + " membership = node_in_structural(alge))"), chunk_opts = list( + label = "summ-solution")), tests = NULL, options = list( + eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, + tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, + highlight = FALSE, size = "normalsize", background = "#F7F7F7", + strip.white = TRUE, cache = 0, cache.path = "position_cache/html/", + cache.vars = NULL, cache.lazy = TRUE, dependson = NULL, + autodep = FALSE, cache.rebuild = FALSE, fig.keep = "high", + fig.show = "asis", fig.align = "default", fig.path = "position_files/figure-html/", dev = "png", dev.args = NULL, dpi = 192, fig.ext = "png", fig.width = 6.5, fig.height = 4, fig.env = "figure", fig.cap = NULL, fig.scap = NULL, fig.lp = "fig:", fig.subcap = NULL, @@ -1502,24 +1492,24 @@

    Reduced graph

    learnr:::store_exercise_cache(structure(list(label = "block", global_setup = structure(c("library(learnr)", "library(manynet)", "library(migraph)", "library(patchwork)", "knitr::opts_chunk$set(echo = FALSE)"), chunk_opts = list(label = "setup", - include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))\nalge %>% \n mutate(se = node_structural_equivalence(alge)) %>% \n autographr(node_color = \"se\")", + include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))\nalge %>% \n mutate(se = node_in_structural(alge)) %>% \n graphr(node_color = \"se\")", chunks = list(list(label = "data", code = "", opts = list( label = "\"data\"", exercise = "TRUE", purl = "FALSE"), - engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", opts = list(label = "\"varyclust\"", exercise = "TRUE", exercise.setup = "\"data\""), engine = "r"), list( - label = "strplot", code = "alge %>% \n mutate(se = node_structural_equivalence(alge)) %>% \n autographr(node_color = \"se\")", + label = "strplot", code = "alge %>% \n mutate(se = node_in_structural(alge)) %>% \n graphr(node_color = \"se\")", opts = list(label = "\"strplot\"", exercise = "TRUE", exercise.setup = "\"varyclust\""), engine = "r"), list(label = "block", code = "", opts = list(label = "\"block\"", exercise = "TRUE", exercise.setup = "\"strplot\"", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("# plot the blockmodel for the whole network", - "plot(as_matrix(alge),", " membership = node_structural_equivalence(alge))", + "plot(as_matrix(alge),", " membership = node_in_structural(alge))", "", "# plot the blockmodel for the friends, tasks, and social networks separately", - "plot(as_matrix(friends),", " membership = node_structural_equivalence(alge)) +", - "plot(as_matrix(tasks),", " membership = node_structural_equivalence(alge)) +", - "plot(as_matrix(social),", " membership = node_structural_equivalence(alge))" + "plot(as_matrix(friends),", " membership = node_in_structural(alge)) +", + "plot(as_matrix(tasks),", " membership = node_in_structural(alge)) +", + "plot(as_matrix(social),", " membership = node_in_structural(alge))" ), chunk_opts = list(label = "block-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -1556,13 +1546,13 @@

    Reduced graph

    learnr:::store_exercise_cache(structure(list(label = "structblock", global_setup = structure(c("library(learnr)", "library(manynet)", "library(migraph)", "library(patchwork)", "knitr::opts_chunk$set(echo = FALSE)"), chunk_opts = list(label = "setup", - include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + include = FALSE)), setup = "\nalge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", chunks = list(list(label = "data", code = "", opts = list( label = "\"data\"", exercise = "TRUE", purl = "FALSE"), - engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_structural_equivalence(alge, \n cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_structural_equivalence(alge, \n cluster = \"concor\", distance = \"euclidean\"))", + engine = "r"), list(label = "varyclust", code = "alge <- to_named(ison_algebra) # fake names to make comparison clearer\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"euclidean\"))\n\n# changing the type of distance used\nplot(node_in_structural(alge, cluster = \"hier\", distance = \"manhattan\"))\n\n# changing the clustering algorithm\nplot(node_in_structural(alge, cluster = \"concor\", distance = \"euclidean\"))", opts = list(label = "\"varyclust\"", exercise = "TRUE", exercise.setup = "\"data\""), engine = "r"), list( - label = "structblock", code = "(bm <- to_blocks(alge, node_structural_equivalence(alge)))\n\nbm <- bm %>% as_tidygraph %>% \n mutate(name = c(\"Freaks\", \"Squares\", \"Nerds\", \"Geek\"))\nautographr(bm)", + label = "structblock", code = "(bm <- to_blocks(alge, node_in_structural(alge)))\n\nbm <- bm %>% as_tidygraph %>% \n mutate(name = c(\"Freaks\", \"Squares\", \"Nerds\", \"Geek\"))\ngraphr(bm)", opts = list(label = "\"structblock\"", exercise = "TRUE", exercise.setup = "\"varyclust\"", warning = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, @@ -1583,9 +1573,9 @@

    Reduced graph

    message = TRUE, render = NULL, ref.label = NULL, child = NULL, engine = "r", split = FALSE, include = TRUE, purl = TRUE, max.print = 1000, label = "structblock", exercise = TRUE, - exercise.setup = "varyclust", code = c("(bm <- to_blocks(alge, node_structural_equivalence(alge)))", + exercise.setup = "varyclust", code = c("(bm <- to_blocks(alge, node_in_structural(alge)))", "", "bm <- bm %>% as_tidygraph %>% ", " mutate(name = c(\"Freaks\", \"Squares\", \"Nerds\", \"Geek\"))", - "autographr(bm)"), out.width.px = 624, out.height.px = 384, + "graphr(bm)"), out.width.px = 624, out.height.px = 384, params.src = "structblock, exercise = TRUE, exercise.setup = \"varyclust\", warning=FALSE", fig.num = 0, exercise.df_print = "paged", exercise.checker = "NULL"), engine = "r", version = "4"), class = c("r", "tutorial_exercise" @@ -1599,7 +1589,7 @@

    Reduced graph

    diff --git a/inst/tutorials/tutorial6/topology.Rmd b/inst/tutorials/tutorial6/topology.Rmd index 32ada92b..27e41782 100644 --- a/inst/tutorials/tutorial6/topology.Rmd +++ b/inst/tutorials/tutorial6/topology.Rmd @@ -87,9 +87,9 @@ Add that too. ``` ```{r empty-solution} -(autographr(create_empty(50), "circle") + ggtitle("Empty graph")) -(autographr(create_filled(50)) + ggtitle("Complete graph")) -(autographr(create_filled(50/2)) + ggtitle("Complete graph (smaller)")) +(graphr(create_empty(50), "circle") + ggtitle("Empty graph")) +(graphr(create_filled(50)) + ggtitle("Complete graph")) +(graphr(create_filled(50/2)) + ggtitle("Complete graph (smaller)")) ``` #### Stars @@ -112,9 +112,9 @@ Use the `create_star()` function to graph three star networks: ``` ```{r star-solution} -(autographr(create_star(50)) + ggtitle("Star graph")) -(autographr(create_star(50, directed = TRUE)) + ggtitle("Star out")) -(autographr(to_redirected(create_star(50, directed = TRUE))) + ggtitle("Star in")) +(graphr(create_star(50)) + ggtitle("Star graph")) +(graphr(create_star(50, directed = TRUE)) + ggtitle("Star out")) +(graphr(to_redirected(create_star(50, directed = TRUE))) + ggtitle("Star in")) ``` #### Trees @@ -133,9 +133,9 @@ Again graph three networks: ```{r tree-solution} # width argument specifies the breadth of the branches -(autographr(create_tree(50, width = 2)) + ggtitle("Tree graph")) -(autographr(create_tree(50, width = 2, directed = TRUE)) + ggtitle("Tree out")) -(autographr(create_tree(50, width = 2, directed = TRUE), "tree") + ggtitle("Tree layout")) +(graphr(create_tree(50, width = 2)) + ggtitle("Tree graph")) +(graphr(create_tree(50, width = 2, directed = TRUE)) + ggtitle("Tree out")) +(graphr(create_tree(50, width = 2, directed = TRUE), "tree") + ggtitle("Tree layout")) ``` Try varying the `width` argument to see the result. @@ -188,8 +188,8 @@ and another with half the number of nodes. ``` ```{r lattices-solution} -(autographr(create_lattice(50)) + ggtitle("One-mode lattice graph")) -(autographr(create_lattice(50/2)) + ggtitle("Smaller lattice graph")) +(graphr(create_lattice(50)) + ggtitle("One-mode lattice graph")) +(graphr(create_lattice(50/2)) + ggtitle("Smaller lattice graph")) ``` #### Rings @@ -208,10 +208,10 @@ Graph three ring networks: ``` ```{r rings-solution} -(autographr(create_ring(50)) + ggtitle("Ring graph", subtitle = "Starring Naomi Watts")) +(graphr(create_ring(50)) + ggtitle("Ring graph", subtitle = "Starring Naomi Watts")) # width argument specifies the width of the ring -(autographr(create_ring(50, width = 2), "circle") + ggtitle("The Ring Two", subtitle = "No different?")) -(autographr(create_ring(50, width = 2), "stress") + ggtitle("The Ring Two v2.0")) +(graphr(create_ring(50, width = 2), "circle") + ggtitle("The Ring Two", subtitle = "No different?")) +(graphr(create_ring(50, width = 2), "stress") + ggtitle("The Ring Two v2.0")) ``` ### Probabilistic graphs @@ -236,9 +236,9 @@ Generate three random networks of 50 nodes and a density of 0.08: ``` ```{r random-solution} -(autographr(generate_random(50, 0.08)) + ggtitle("Random 1 graph")) -(autographr(generate_random(50, 0.08)) + ggtitle("Random 2 graph")) -(autographr(generate_random(50, 0.08)) + ggtitle("Random 3 graph")) +(graphr(generate_random(50, 0.08)) + ggtitle("Random 1 graph")) +(graphr(generate_random(50, 0.08)) + ggtitle("Random 2 graph")) +(graphr(generate_random(50, 0.08)) + ggtitle("Random 3 graph")) ``` Keep going if you like... it will be a little different every time. @@ -251,7 +251,7 @@ Try generating a random graph with 200 edges/ties now: ``` ```{r randomno-solution} -(erdren4 <- autographr(generate_random(50, 200)) + ggtitle("Random 1 graph")) +(erdren4 <- graphr(generate_random(50, 200)) + ggtitle("Random 1 graph")) ``` #### Small-world graphs @@ -266,9 +266,9 @@ Graph three small-world networks, all with 50 nodes and a rewiring probability o ``` ```{r smallw-solution} -(autographr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 1 graph")) -(autographr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 2 graph")) -(autographr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 3 graph")) +(graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 1 graph")) +(graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 2 graph")) +(graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 3 graph")) ``` With on average 2.5 ties randomly rewired, does the structure look different? @@ -321,11 +321,11 @@ with alpha parameters of 0.5, 1, and 1.5. ``` ```{r scalef-solution} -(autographr(generate_scalefree(50, 0.5)) + +(graphr(generate_scalefree(50, 0.5)) + ggtitle("Scalefree 1 graph", subtitle = "Power = .5")) -(autographr(generate_scalefree(50, 1)) + +(graphr(generate_scalefree(50, 1)) + ggtitle("Scalefree 2 graph", subtitle = "Power = 1")) -(autographr(generate_scalefree(50, 1.5)) + +(graphr(generate_scalefree(50, 1.5)) + ggtitle("Scalefree 3 graph", subtitle = "Power = 1.5")) ``` @@ -380,7 +380,7 @@ will be split evenly between core and periphery partitions). ``` ```{r core-solution} -(autographr(create_core(50)) + ggtitle("Core")) +(graphr(create_core(50)) + ggtitle("Core")) ``` ### Core-periphery assignment @@ -398,11 +398,11 @@ Any you might think correlate with core status? ``` ```{r gnet-solution} -autographr(ison_lawfirm, node_color = "school") +graphr(ison_lawfirm, node_color = "school") ``` Next, let's assign nodes to the core and periphery blocks -using the `node_core()` function from `{migraph}`. +using the `node_in_core()` function from `{migraph}`. It works pretty straightforwardly. By default it runs down the rank order of nodes by their degree, at each step working out whether including the next highest degree node @@ -414,8 +414,8 @@ in the core will maximise the core-periphery structure of the network. ```{r nodecore-solution} ison_lawfirm %>% - mutate(nc = node_core(ison_lawfirm)) %>% - autographr(node_color = "nc") + mutate(nc = node_in_core(ison_lawfirm)) %>% + graphr(node_color = "nc") ``` This graph suggests that there might even be two cores here, @@ -430,7 +430,7 @@ a core-periphery model of the same dimension using `network_core()`. ``` ```{r netcore-solution} -network_core(ison_lawfirm, node_core(ison_lawfirm)) +network_core(ison_lawfirm, node_in_core(ison_lawfirm)) ``` ```{r corecorr-qa, echo=FALSE, purl = FALSE} @@ -449,7 +449,7 @@ question("What can we say about this correlation.", ) ``` -Note that `node_core()` also includes a method that descends through +Note that `node_in_core()` also includes a method that descends through the rank order of nodes' eigenvector centralities instead of degree centralities. Why might that not be such a good choice here? @@ -464,7 +464,7 @@ between gender and core (or periphery) status. ``` ```{r chisq-solution} -chisq.test(node_core(ison_lawfirm), node_attribute(ison_lawfirm, "Gender")) +chisq.test(node_in_core(ison_lawfirm), node_attribute(ison_lawfirm, "Gender")) ``` ```{r chisq-qa, echo=FALSE, purl = FALSE} @@ -489,7 +489,7 @@ An alternative route is to identify 'core' nodes depending on their _k_-coreness. In `{migraph}`, we can return nodes _k_-coreness with `node_coreness()` instead of -the `node_core()` used for core-periphery. +the `node_in_core()` used for core-periphery. ```{r nodecoren, exercise=TRUE, purl = FALSE} @@ -498,14 +498,14 @@ the `node_core()` used for core-periphery. ```{r nodecoren-solution} ison_lawfirm %>% mutate(ncn = node_coreness(ison_lawfirm)) %>% - autographr(node_color = "ncn") + scale_colour_sdgs() + graphr(node_color = "ncn") + scale_colour_sdgs() ``` ```{r dich-qa, echo=FALSE, purl = FALSE} question("Which has more than two classes/groups.", answer("node_coreness()", correct = TRUE, message = learnr::random_praise()), - answer("node_core()", + answer("node_in_core()", message = learnr::random_encouragement()), random_answer_order = TRUE, allow_retry = TRUE @@ -619,7 +619,7 @@ Can you add a node attribute that highlights which nodes are cutpoints? ```{r closerlook-solution} ison_adolescents |> mutate(cut = node_is_cutpoint(ison_adolescents)) |> - autographr(node_color = "cut") + graphr(node_color = "cut") ``` ### Identifying bridges @@ -633,7 +633,7 @@ Let's do something similar now, but with respect to ties rather than nodes. ```{r tieside-solution} network_adhesion(ison_adolescents) ison_adolescents |> mutate_ties(cut = tie_is_bridge(ison_adolescents)) |> - autographr(edge_color = "cut") + graphr(edge_color = "cut") ``` We could also investigate the opposite of a bridge, @@ -646,7 +646,7 @@ This is called (rather confusingly) tie cohesion. ```{r tiecoh-solution} ison_adolescents |> mutate_ties(coh = tie_cohesion(ison_adolescents)) |> - autographr(edge_color = "coh") + graphr(edge_color = "coh") ``` Where would you target your efforts if you wanted to fragment this network? diff --git a/inst/tutorials/tutorial6/topology.html b/inst/tutorials/tutorial6/topology.html index 25b92265..6577327f 100644 --- a/inst/tutorials/tutorial6/topology.html +++ b/inst/tutorials/tutorial6/topology.html @@ -152,9 +152,9 @@

    Deterministic graphs

    -
    (autographr(create_empty(50), "circle") + ggtitle("Empty graph"))
    -(autographr(create_filled(50)) + ggtitle("Complete graph"))
    -(autographr(create_filled(50/2)) + ggtitle("Complete graph (smaller)"))
    +
    (graphr(create_empty(50), "circle") + ggtitle("Empty graph"))
    +(graphr(create_filled(50)) + ggtitle("Complete graph"))
    +(graphr(create_filled(50/2)) + ggtitle("Complete graph (smaller)"))

    Stars

    @@ -178,9 +178,9 @@

    Stars

    -
    (autographr(create_star(50)) + ggtitle("Star graph"))
    -(autographr(create_star(50, directed = TRUE)) + ggtitle("Star out"))
    -(autographr(to_redirected(create_star(50, directed = TRUE))) + ggtitle("Star in"))
    +
    (graphr(create_star(50)) + ggtitle("Star graph"))
    +(graphr(create_star(50, directed = TRUE)) + ggtitle("Star out"))
    +(graphr(to_redirected(create_star(50, directed = TRUE))) + ggtitle("Star in"))
    @@ -202,9 +202,9 @@

    Trees

    data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    # width argument specifies the breadth of the branches
    -(autographr(create_tree(50, width = 2)) + ggtitle("Tree graph"))
    -(autographr(create_tree(50, width = 2, directed = TRUE)) + ggtitle("Tree out"))
    -(autographr(create_tree(50, width = 2, directed = TRUE), "tree") + ggtitle("Tree layout"))
    +(graphr(create_tree(50, width = 2)) + ggtitle("Tree graph")) +(graphr(create_tree(50, width = 2, directed = TRUE)) + ggtitle("Tree out")) +(graphr(create_tree(50, width = 2, directed = TRUE), "tree") + ggtitle("Tree layout"))

    Try varying the width argument to see the result.

    @@ -247,8 +247,8 @@

    Lattices

    -
    (autographr(create_lattice(50)) + ggtitle("One-mode lattice graph"))
    -(autographr(create_lattice(50/2)) + ggtitle("Smaller lattice graph"))
    +
    (graphr(create_lattice(50)) + ggtitle("One-mode lattice graph"))
    +(graphr(create_lattice(50/2)) + ggtitle("Smaller lattice graph"))
    @@ -269,10 +269,10 @@

    Rings

    -
    (autographr(create_ring(50)) + ggtitle("Ring graph", subtitle = "Starring Naomi Watts"))
    +
    (graphr(create_ring(50)) + ggtitle("Ring graph", subtitle = "Starring Naomi Watts"))
     # width argument specifies the width of the ring
    -(autographr(create_ring(50, width = 2), "circle") + ggtitle("The Ring Two", subtitle = "No different?"))
    -(autographr(create_ring(50, width = 2), "stress") + ggtitle("The Ring Two v2.0"))
    +(graphr(create_ring(50, width = 2), "circle") + ggtitle("The Ring Two", subtitle = "No different?")) +(graphr(create_ring(50, width = 2), "stress") + ggtitle("The Ring Two v2.0"))
    @@ -302,9 +302,9 @@

    Random graphs

    -
    (autographr(generate_random(50, 0.08)) + ggtitle("Random 1 graph"))
    -(autographr(generate_random(50, 0.08)) + ggtitle("Random 2 graph"))
    -(autographr(generate_random(50, 0.08)) + ggtitle("Random 3 graph"))
    +
    (graphr(generate_random(50, 0.08)) + ggtitle("Random 1 graph"))
    +(graphr(generate_random(50, 0.08)) + ggtitle("Random 2 graph"))
    +(graphr(generate_random(50, 0.08)) + ggtitle("Random 3 graph"))

    Keep going if you like… it will be a little different every time. Note that you can also pass the second argument an integer, in which @@ -319,7 +319,7 @@

    Random graphs

    -
    (erdren4 <- autographr(generate_random(50, 200)) + ggtitle("Random 1 graph"))
    +
    (erdren4 <- graphr(generate_random(50, 200)) + ggtitle("Random 1 graph"))
    @@ -336,9 +336,9 @@

    Small-world graphs

    -
    (autographr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 1 graph"))
    -(autographr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 2 graph"))
    -(autographr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 3 graph"))
    +
    (graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 1 graph"))
    +(graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 2 graph"))
    +(graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 3 graph"))

    With on average 2.5 ties randomly rewired, does the structure look different? This is a small-world network, where clustering/transitivity @@ -390,11 +390,11 @@

    Scale-free graphs

    -
    (autographr(generate_scalefree(50, 0.5)) +
    +
    (graphr(generate_scalefree(50, 0.5)) +
         ggtitle("Scalefree 1 graph", subtitle = "Power = .5"))
    -(autographr(generate_scalefree(50, 1)) +
    +(graphr(generate_scalefree(50, 1)) +
         ggtitle("Scalefree 2 graph", subtitle = "Power = 1"))
    -(autographr(generate_scalefree(50, 1.5)) +
    +(graphr(generate_scalefree(50, 1.5)) +
         ggtitle("Scalefree 3 graph", subtitle = "Power = 1.5"))

    You can also test whether a network has a degree distribution that @@ -446,7 +446,7 @@

    Core-periphery graphs

    -
    (autographr(create_core(50)) + ggtitle("Core"))
    +
    (graphr(create_core(50)) + ggtitle("Core"))
    @@ -467,12 +467,12 @@

    Core-periphery assignment

    -
    autographr(ison_lawfirm, node_color = "School")
    +
    graphr(ison_lawfirm, node_color = "school")

    Next, let’s assign nodes to the core and periphery blocks using the -node_core() function from {migraph}. It works -pretty straightforwardly. By default it runs down the rank order of -nodes by their degree, at each step working out whether including the +node_in_core() function from {migraph}. It +works pretty straightforwardly. By default it runs down the rank order +of nodes by their degree, at each step working out whether including the next highest degree node in the core will maximise the core-periphery structure of the network.

    Core-periphery assignment data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    ison_lawfirm %>% 
    -  mutate(nc = node_core(ison_lawfirm)) %>% 
    -  autographr(node_color = "nc")
    + mutate(nc = node_in_core(ison_lawfirm)) %>% + graphr(node_color = "nc")

    This graph suggests that there might even be two cores here, one on the left and one on the right.

    @@ -500,7 +500,7 @@

    Core-periphery assignment

    -
    network_core(ison_lawfirm, node_core(ison_lawfirm))
    +
    network_core(ison_lawfirm, node_in_core(ison_lawfirm))
    @@ -510,7 +510,7 @@

    Core-periphery assignment

    -

    Note that node_core() also includes a method that +

    Note that node_in_core() also includes a method that descends through the rank order of nodes’ eigenvector centralities instead of degree centralities. Why might that not be such a good choice here?

    @@ -528,7 +528,7 @@

    Core-periphery assignment

    -
    chisq.test(node_core(ison_lawfirm), node_attribute(ison_lawfirm, "Gender"))
    +
    chisq.test(node_in_core(ison_lawfirm), node_attribute(ison_lawfirm, "Gender"))
    @@ -544,7 +544,7 @@

    Coreness values

    An alternative route is to identify ‘core’ nodes depending on their k-coreness. In {migraph}, we can return nodes k-coreness with node_coreness() instead of the -node_core() used for core-periphery.

    +node_in_core() used for core-periphery.

    @@ -555,7 +555,7 @@

    Coreness values

    data-lines="0" data-pipe="|>">
    ison_lawfirm %>% 
       mutate(ncn = node_coreness(ison_lawfirm)) %>% 
    -  autographr(node_color = "ncn")
    + graphr(node_color = "ncn") + scale_colour_sdgs()
    @@ -665,7 +665,7 @@

    Identifying cutpoints

    data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    ison_adolescents |> mutate(cut = node_is_cutpoint(ison_adolescents)) |> 
    -  autographr(node_color = "cut")
    + graphr(node_color = "cut")
    @@ -682,7 +682,7 @@

    Identifying bridges

    data-lines="0" data-pipe="|>">
    network_adhesion(ison_adolescents)
     ison_adolescents |> mutate_ties(cut = tie_is_bridge(ison_adolescents)) |> 
    -  autographr(edge_color = "cut")
    + graphr(edge_color = "cut")

    We could also investigate the opposite of a bridge, the degree to which ties are deeply embedded in triangles. This is called (rather @@ -696,7 +696,7 @@

    Identifying bridges

    data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    ison_adolescents |> mutate_ties(coh = tie_cohesion(ison_adolescents)) |> 
    -  autographr(edge_color = "coh")
    + graphr(edge_color = "coh")

    Where would you target your efforts if you wanted to fragment this network? @@ -788,9 +788,9 @@

    Identifying bridges

    chunks = list(list(label = "empty", code = "", opts = list( label = "\"empty\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure(c("(autographr(create_empty(50), \"circle\") + ggtitle(\"Empty graph\"))", - "(autographr(create_filled(50)) + ggtitle(\"Complete graph\"))", - "(autographr(create_filled(50/2)) + ggtitle(\"Complete graph (smaller)\"))" + check = NULL, solution = structure(c("(graphr(create_empty(50), \"circle\") + ggtitle(\"Empty graph\"))", + "(graphr(create_filled(50)) + ggtitle(\"Complete graph\"))", + "(graphr(create_filled(50/2)) + ggtitle(\"Complete graph (smaller)\"))" ), chunk_opts = list(label = "empty-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -849,9 +849,9 @@

    Identifying bridges

    chunks = list(list(label = "star", code = "", opts = list( label = "\"star\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure(c("(autographr(create_star(50)) + ggtitle(\"Star graph\"))", - "(autographr(create_star(50, directed = TRUE)) + ggtitle(\"Star out\"))", - "(autographr(to_redirected(create_star(50, directed = TRUE))) + ggtitle(\"Star in\"))" + check = NULL, solution = structure(c("(graphr(create_star(50)) + ggtitle(\"Star graph\"))", + "(graphr(create_star(50, directed = TRUE)) + ggtitle(\"Star out\"))", + "(graphr(to_redirected(create_star(50, directed = TRUE))) + ggtitle(\"Star in\"))" ), chunk_opts = list(label = "star-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -911,9 +911,9 @@

    Identifying bridges

    label = "\"tree\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("# width argument specifies the breadth of the branches", - "(autographr(create_tree(50, width = 2)) + ggtitle(\"Tree graph\"))", - "(autographr(create_tree(50, width = 2, directed = TRUE)) + ggtitle(\"Tree out\"))", - "(autographr(create_tree(50, width = 2, directed = TRUE), \"tree\") + ggtitle(\"Tree layout\"))" + "(graphr(create_tree(50, width = 2)) + ggtitle(\"Tree graph\"))", + "(graphr(create_tree(50, width = 2, directed = TRUE)) + ggtitle(\"Tree out\"))", + "(graphr(create_tree(50, width = 2, directed = TRUE), \"tree\") + ggtitle(\"Tree layout\"))" ), chunk_opts = list(label = "tree-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -939,28 +939,38 @@

    Identifying bridges

    @@ -998,8 +1008,8 @@

    Identifying bridges

    chunks = list(list(label = "lattices", code = "", opts = list( label = "\"lattices\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure(c("(autographr(create_lattice(50)) + ggtitle(\"One-mode lattice graph\"))", - "(autographr(create_lattice(50/2)) + ggtitle(\"Smaller lattice graph\"))" + check = NULL, solution = structure(c("(graphr(create_lattice(50)) + ggtitle(\"One-mode lattice graph\"))", + "(graphr(create_lattice(50/2)) + ggtitle(\"Smaller lattice graph\"))" ), chunk_opts = list(label = "lattices-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -1058,9 +1068,9 @@

    Identifying bridges

    chunks = list(list(label = "rings", code = "", opts = list( label = "\"rings\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure(c("(autographr(create_ring(50)) + ggtitle(\"Ring graph\", subtitle = \"Starring Naomi Watts\"))", - "# width argument specifies the width of the ring", "(autographr(create_ring(50, width = 2), \"circle\") + ggtitle(\"The Ring Two\", subtitle = \"No different?\"))", - "(autographr(create_ring(50, width = 2), \"stress\") + ggtitle(\"The Ring Two v2.0\"))" + check = NULL, solution = structure(c("(graphr(create_ring(50)) + ggtitle(\"Ring graph\", subtitle = \"Starring Naomi Watts\"))", + "# width argument specifies the width of the ring", "(graphr(create_ring(50, width = 2), \"circle\") + ggtitle(\"The Ring Two\", subtitle = \"No different?\"))", + "(graphr(create_ring(50, width = 2), \"stress\") + ggtitle(\"The Ring Two v2.0\"))" ), chunk_opts = list(label = "rings-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -1119,9 +1129,9 @@

    Identifying bridges

    chunks = list(list(label = "random", code = "", opts = list( label = "\"random\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure(c("(autographr(generate_random(50, 0.08)) + ggtitle(\"Random 1 graph\"))", - "(autographr(generate_random(50, 0.08)) + ggtitle(\"Random 2 graph\"))", - "(autographr(generate_random(50, 0.08)) + ggtitle(\"Random 3 graph\"))" + check = NULL, solution = structure(c("(graphr(generate_random(50, 0.08)) + ggtitle(\"Random 1 graph\"))", + "(graphr(generate_random(50, 0.08)) + ggtitle(\"Random 2 graph\"))", + "(graphr(generate_random(50, 0.08)) + ggtitle(\"Random 3 graph\"))" ), chunk_opts = list(label = "random-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -1180,7 +1190,7 @@

    Identifying bridges

    chunks = list(list(label = "randomno", code = "", opts = list( label = "\"randomno\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure("(erdren4 <- autographr(generate_random(50, 200)) + ggtitle(\"Random 1 graph\"))", chunk_opts = list( + check = NULL, solution = structure("(erdren4 <- graphr(generate_random(50, 200)) + ggtitle(\"Random 1 graph\"))", chunk_opts = list( label = "randomno-solution")), tests = NULL, options = list( eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, @@ -1238,9 +1248,9 @@

    Identifying bridges

    chunks = list(list(label = "smallw", code = "", opts = list( label = "\"smallw\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure(c("(autographr(generate_smallworld(50, 0.025)) + ggtitle(\"Smallworld 1 graph\"))", - "(autographr(generate_smallworld(50, 0.025)) + ggtitle(\"Smallworld 2 graph\"))", - "(autographr(generate_smallworld(50, 0.025)) + ggtitle(\"Smallworld 3 graph\"))" + check = NULL, solution = structure(c("(graphr(generate_smallworld(50, 0.025)) + ggtitle(\"Smallworld 1 graph\"))", + "(graphr(generate_smallworld(50, 0.025)) + ggtitle(\"Smallworld 2 graph\"))", + "(graphr(generate_smallworld(50, 0.025)) + ggtitle(\"Smallworld 3 graph\"))" ), chunk_opts = list(label = "smallw-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -1357,10 +1367,10 @@

    Identifying bridges

    chunks = list(list(label = "scalef", code = "", opts = list( label = "\"scalef\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure(c("(autographr(generate_scalefree(50, 0.5)) +", + check = NULL, solution = structure(c("(graphr(generate_scalefree(50, 0.5)) +", " ggtitle(\"Scalefree 1 graph\", subtitle = \"Power = .5\"))", - "(autographr(generate_scalefree(50, 1)) +", " ggtitle(\"Scalefree 2 graph\", subtitle = \"Power = 1\"))", - "(autographr(generate_scalefree(50, 1.5)) +", " ggtitle(\"Scalefree 3 graph\", subtitle = \"Power = 1.5\"))" + "(graphr(generate_scalefree(50, 1)) +", " ggtitle(\"Scalefree 2 graph\", subtitle = \"Power = 1\"))", + "(graphr(generate_scalefree(50, 1.5)) +", " ggtitle(\"Scalefree 3 graph\", subtitle = \"Power = 1.5\"))" ), chunk_opts = list(label = "scalef-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -1447,13 +1457,13 @@

    Identifying bridges

    @@ -1501,7 +1511,7 @@

    Identifying bridges

    chunks = list(list(label = "core", code = "", opts = list( label = "\"core\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure("(autographr(create_core(50)) + ggtitle(\"Core\"))", chunk_opts = list( + check = NULL, solution = structure("(graphr(create_core(50)) + ggtitle(\"Core\"))", chunk_opts = list( label = "core-solution")), tests = NULL, options = list( eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, @@ -1559,7 +1569,7 @@

    Identifying bridges

    chunks = list(list(label = "gnet", code = "", opts = list( label = "\"gnet\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure("autographr(ison_lawfirm, node_color = \"School\")", chunk_opts = list( + check = NULL, solution = structure("graphr(ison_lawfirm, node_color = \"school\")", chunk_opts = list( label = "gnet-solution")), tests = NULL, options = list( eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, @@ -1618,7 +1628,7 @@

    Identifying bridges

    label = "\"nodecore\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("ison_lawfirm %>% ", - " mutate(nc = node_core(ison_lawfirm)) %>% ", " autographr(node_color = \"nc\")" + " mutate(nc = node_in_core(ison_lawfirm)) %>% ", " graphr(node_color = \"nc\")" ), chunk_opts = list(label = "nodecore-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -1677,7 +1687,7 @@

    Identifying bridges

    chunks = list(list(label = "netcore", code = "", opts = list( label = "\"netcore\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure("network_core(ison_lawfirm, node_core(ison_lawfirm))", chunk_opts = list( + check = NULL, solution = structure("network_core(ison_lawfirm, node_in_core(ison_lawfirm))", chunk_opts = list( label = "netcore-solution")), tests = NULL, options = list( eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, @@ -1704,30 +1714,30 @@

    Identifying bridges

    @@ -1775,7 +1785,7 @@

    Identifying bridges

    chunks = list(list(label = "chisq", code = "", opts = list( label = "\"chisq\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure("chisq.test(node_core(ison_lawfirm), node_attribute(ison_lawfirm, \"Gender\"))", chunk_opts = list( + check = NULL, solution = structure("chisq.test(node_in_core(ison_lawfirm), node_attribute(ison_lawfirm, \"Gender\"))", chunk_opts = list( label = "chisq-solution")), tests = NULL, options = list( eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, @@ -1802,26 +1812,26 @@

    Identifying bridges

    @@ -1870,7 +1880,7 @@

    Identifying bridges

    label = "\"nodecoren\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("ison_lawfirm %>% ", - " mutate(ncn = node_coreness(ison_lawfirm)) %>% ", " autographr(node_color = \"ncn\")" + " mutate(ncn = node_coreness(ison_lawfirm)) %>% ", " graphr(node_color = \"ncn\") + scale_colour_sdgs()" ), chunk_opts = list(label = "nodecoren-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -1897,13 +1907,13 @@

    Identifying bridges

    @@ -1920,22 +1930,22 @@

    Identifying bridges

    @@ -2010,18 +2020,18 @@

    Identifying bridges

    @@ -2097,19 +2107,19 @@

    Identifying bridges

    @@ -2244,15 +2254,15 @@

    Identifying bridges

    label = "\"closerlook\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("ison_adolescents |> mutate(cut = node_is_cutpoint(ison_adolescents)) |> ", - " autographr(node_color = \"cut\")"), chunk_opts = list( - label = "closerlook-solution")), tests = NULL, options = list( - eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, - tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, - highlight = FALSE, size = "normalsize", background = "#F7F7F7", - strip.white = TRUE, cache = 0, cache.path = "topology_cache/html/", - cache.vars = NULL, cache.lazy = TRUE, dependson = NULL, - autodep = FALSE, cache.rebuild = FALSE, fig.keep = "high", - fig.show = "asis", fig.align = "default", fig.path = "topology_files/figure-html/", + " graphr(node_color = \"cut\")"), chunk_opts = list(label = "closerlook-solution")), + tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", + tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, + comment = NA, highlight = FALSE, size = "normalsize", + background = "#F7F7F7", strip.white = TRUE, cache = 0, + cache.path = "topology_cache/html/", cache.vars = NULL, + cache.lazy = TRUE, dependson = NULL, autodep = FALSE, + cache.rebuild = FALSE, fig.keep = "high", fig.show = "asis", + fig.align = "default", fig.path = "topology_files/figure-html/", dev = "png", dev.args = NULL, dpi = 192, fig.ext = "png", fig.width = 6.5, fig.height = 4, fig.env = "figure", fig.cap = NULL, fig.scap = NULL, fig.lp = "fig:", fig.subcap = NULL, @@ -2304,15 +2314,15 @@

    Identifying bridges

    engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("network_adhesion(ison_adolescents)", "ison_adolescents |> mutate_ties(cut = tie_is_bridge(ison_adolescents)) |> ", - " autographr(edge_color = \"cut\")"), chunk_opts = list( - label = "tieside-solution")), tests = NULL, options = list( - eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, - tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, - highlight = FALSE, size = "normalsize", background = "#F7F7F7", - strip.white = TRUE, cache = 0, cache.path = "topology_cache/html/", - cache.vars = NULL, cache.lazy = TRUE, dependson = NULL, - autodep = FALSE, cache.rebuild = FALSE, fig.keep = "high", - fig.show = "asis", fig.align = "default", fig.path = "topology_files/figure-html/", + " graphr(edge_color = \"cut\")"), chunk_opts = list(label = "tieside-solution")), + tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", + tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, + comment = NA, highlight = FALSE, size = "normalsize", + background = "#F7F7F7", strip.white = TRUE, cache = 0, + cache.path = "topology_cache/html/", cache.vars = NULL, + cache.lazy = TRUE, dependson = NULL, autodep = FALSE, + cache.rebuild = FALSE, fig.keep = "high", fig.show = "asis", + fig.align = "default", fig.path = "topology_files/figure-html/", dev = "png", dev.args = NULL, dpi = 192, fig.ext = "png", fig.width = 6.5, fig.height = 4, fig.env = "figure", fig.cap = NULL, fig.scap = NULL, fig.lp = "fig:", fig.subcap = NULL, @@ -2363,15 +2373,15 @@

    Identifying bridges

    label = "\"tiecoh\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("ison_adolescents |> mutate_ties(coh = tie_cohesion(ison_adolescents)) |> ", - " autographr(edge_color = \"coh\")"), chunk_opts = list( - label = "tiecoh-solution")), tests = NULL, options = list( - eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, - tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = NA, - highlight = FALSE, size = "normalsize", background = "#F7F7F7", - strip.white = TRUE, cache = 0, cache.path = "topology_cache/html/", - cache.vars = NULL, cache.lazy = TRUE, dependson = NULL, - autodep = FALSE, cache.rebuild = FALSE, fig.keep = "high", - fig.show = "asis", fig.align = "default", fig.path = "topology_files/figure-html/", + " graphr(edge_color = \"coh\")"), chunk_opts = list(label = "tiecoh-solution")), + tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", + tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, + comment = NA, highlight = FALSE, size = "normalsize", + background = "#F7F7F7", strip.white = TRUE, cache = 0, + cache.path = "topology_cache/html/", cache.vars = NULL, + cache.lazy = TRUE, dependson = NULL, autodep = FALSE, + cache.rebuild = FALSE, fig.keep = "high", fig.show = "asis", + fig.align = "default", fig.path = "topology_files/figure-html/", dev = "png", dev.args = NULL, dpi = 192, fig.ext = "png", fig.width = 6.5, fig.height = 4, fig.env = "figure", fig.cap = NULL, fig.scap = NULL, fig.lp = "fig:", fig.subcap = NULL, @@ -2389,12 +2399,12 @@

    Identifying bridges

    diff --git a/inst/tutorials/tutorial8/regression.Rmd b/inst/tutorials/tutorial8/regression.Rmd index 98c3a548..ae285746 100644 --- a/inst/tutorials/tutorial8/regression.Rmd +++ b/inst/tutorials/tutorial8/regression.Rmd @@ -81,7 +81,7 @@ marvel_friends This gives us a dataset of nearly twenty characters and a little more than 100 edges. Recall that this data has several nodal attributes. Explore a couple of these attributes, "Gender" and "PowerOrigin" visually -using `autographr()`. +using `graphr()`. ```{r plotfriends, exercise=TRUE, purl = FALSE} @@ -92,13 +92,13 @@ using `autographr()`. # you will need to use two different aesthetic dimensions to # represent them together. # Which will you present as shapes and which as colors? -autographr(____, - node_shape = ____, - node_color = ____) +graphr(____, + node_shape = ____, + node_color = ____) ``` ```{r plotfriends-solution} -autographr(marvel_friends, +graphr(marvel_friends, node_shape = "Gender", node_color = "PowerOrigin") ``` @@ -254,14 +254,14 @@ plot(rand.____) ```{r rando-hint-3, purl = FALSE} rand.gender <- test_random(marvel_friends, - network_heterophily, attribute = "Gender", + network_heterophily, attribute = "Gender", times = 1000) rand.power <- test_random(marvel_friends, - network_heterophily, attribute = "PowerOrigin", - times = 1000) + network_heterophily, attribute = "PowerOrigin", + times = 1000) rand.attract <- test_random(marvel_friends, - network_heterophily, attribute = "Attractive", - times = 1000) + network_heterophily, attribute = "Attractive", + times = 1000) plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") plot(rand.attract) + ggtitle("CUG test results for 'Attractive' attribute") @@ -269,14 +269,14 @@ plot(rand.attract) + ggtitle("CUG test results for 'Attractive' attribute") ```{r rando-solution} rand.gender <- test_random(marvel_friends, - network_heterophily, attribute = "Gender", + network_heterophily, attribute = "Gender", times = 1000) rand.power <- test_random(marvel_friends, - network_heterophily, attribute = "PowerOrigin", - times = 1000) + network_heterophily, attribute = "PowerOrigin", + times = 1000) rand.attract <- test_random(marvel_friends, - network_heterophily, attribute = "Attractive", - times = 1000) + network_heterophily, attribute = "Attractive", + times = 1000) plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") plot(rand.attract) + ggtitle("CUG test results for 'Attractive' attribute") @@ -316,18 +316,18 @@ Let's first plot the observed data and some permuted data next to each other. ``` ```{r perm-hint, purl = FALSE} -autographr(generate_permutation(____, with_attr = TRUE), ____) +graphr(generate_permutation(____, with_attr = TRUE), ____) ``` ```{r perm-solution} -old <- autographr(marvel_friends, - labels = FALSE, node_size = 6, - node_color = "PowerOrigin", - node_shape = "Gender") + ggtitle("Original network") -new <- autographr(generate_permutation(marvel_friends, with_attr = TRUE), - labels = FALSE, node_size = 6, - node_color = "PowerOrigin", - node_shape = "Gender") + ggtitle("Permuted network") +old <- graphr(marvel_friends, + labels = FALSE, node_size = 6, + node_color = "PowerOrigin", + node_shape = "Gender") + ggtitle("Original network") +new <- graphr(generate_permutation(marvel_friends, with_attr = TRUE), + labels = FALSE, node_size = 6, + node_color = "PowerOrigin", + node_shape = "Gender") + ggtitle("Permuted network") old + new ``` @@ -368,7 +368,7 @@ test_permutation(____, FUN = ____, attribute = ____, network_heterophily, attribute = "Gender", times = 1000)) (perm.power <- test_permutation(marvel_friends, - network_heterophily, attribute = "PowerOrigin", + network_heterophily, attribute = "PowerOrigin", times = 1000)) (plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") + theme(plot.title = element_text(size=8)) | plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") + theme(plot.title = element_text(size=8))) / @@ -408,8 +408,7 @@ Nodal attributes collected include the primary discipline and number of citation ```{r introeies, exercise=TRUE, purl = FALSE} ison_networkers -autographr(ison_networkers, - node_color = "Discipline") +graphr(ison_networkers, node_color = "Discipline") ``` Let's use both the continuous `Citations` and the categorical `Discipline` variables diff --git a/inst/tutorials/tutorial8/regression.html b/inst/tutorials/tutorial8/regression.html index 7373dc9b..a9796b13 100644 --- a/inst/tutorials/tutorial8/regression.html +++ b/inst/tutorials/tutorial8/regression.html @@ -176,7 +176,7 @@

    Setting up

    This gives us a dataset of nearly twenty characters and a little more than 100 edges. Recall that this data has several nodal attributes. Explore a couple of these attributes, “Gender” and “PowerOrigin” -visually using autographr().

    +visually using graphr().

    @@ -189,14 +189,14 @@

    Setting up

    # you will need to use two different aesthetic dimensions to # represent them together. # Which will you present as shapes and which as colors? -autographr(____, - node_shape = ____, - node_color = ____) +graphr(____, + node_shape = ____, + node_color = ____)
    -
    autographr(marvel_friends, 
    +
    graphr(marvel_friends, 
                node_shape = "Gender",
                node_color = "PowerOrigin")
    @@ -364,14 +364,14 @@

    Conditional uniform graph tests

    data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    rand.gender <- test_random(marvel_friends, 
    -                            network_heterophily, attribute = "Gender", 
    +                           network_heterophily, attribute = "Gender", 
                                times = 1000)
     rand.power <- test_random(marvel_friends, 
    -                           network_heterophily, attribute = "PowerOrigin", 
    -                           times = 1000)
    +                          network_heterophily, attribute = "PowerOrigin", 
    +                          times = 1000)
     rand.attract <- test_random(marvel_friends, 
    -                             network_heterophily, attribute = "Attractive", 
    -                           times = 1000)
    +                            network_heterophily, attribute = "Attractive", 
    +                            times = 1000)
     plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute")
     plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute")
     plot(rand.attract) + ggtitle("CUG test results for 'Attractive' attribute")
    @@ -416,19 +416,19 @@

    Quadratic assignment procedure tests

    -
    autographr(generate_permutation(____, with_attr = TRUE), ____)
    +
    graphr(generate_permutation(____, with_attr = TRUE), ____)
    -
    old <- autographr(marvel_friends, 
    -                  labels = FALSE, node_size = 6, 
    -                  node_color = "PowerOrigin", 
    -                  node_shape = "Gender") + ggtitle("Original network")
    -new <- autographr(generate_permutation(marvel_friends, with_attr = TRUE),
    -                   labels = FALSE, node_size = 6,
    -                  node_color = "PowerOrigin",
    -                  node_shape = "Gender") + ggtitle("Permuted network")
    +
    old <- graphr(marvel_friends,
    +              labels = FALSE, node_size = 6,
    +              node_color = "PowerOrigin",
    +              node_shape = "Gender") + ggtitle("Original network")
    +new <- graphr(generate_permutation(marvel_friends, with_attr = TRUE),
    +              labels = FALSE, node_size = 6,
    +              node_color = "PowerOrigin",
    +              node_shape = "Gender") + ggtitle("Permuted network")
     old + new
    @@ -462,7 +462,7 @@

    Quadratic assignment procedure tests

    network_heterophily, attribute = "Gender", times = 1000)) (perm.power <- test_permutation(marvel_friends, - network_heterophily, attribute = "PowerOrigin", + network_heterophily, attribute = "PowerOrigin", times = 1000)) (plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") + theme(plot.title = element_text(size=8)) | plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") + theme(plot.title = element_text(size=8))) / @@ -502,8 +502,7 @@

    Network linear models

    data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    ison_networkers
    -autographr(ison_networkers,
    -           node_color = "Discipline")
    +graphr(ison_networkers, node_color = "Discipline")

    Let’s use both the continuous Citations and the @@ -667,7 +666,7 @@

    Network linear models

    chunks = list(list(label = "plotfriends", code = "", opts = list( label = "\"plotfriends\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure(c("autographr(marvel_friends, ", + check = NULL, solution = structure(c("graphr(marvel_friends, ", " node_shape = \"Gender\",", " node_color = \"PowerOrigin\")" ), chunk_opts = list(label = "plotfriends-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", @@ -827,15 +826,15 @@

    Network linear models

    @@ -869,12 +868,12 @@

    Network linear models

    label = "\"rando\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("rand.gender <- test_random(marvel_friends, ", - " network_heterophily, attribute = \"Gender\", ", + " network_heterophily, attribute = \"Gender\", ", " times = 1000)", "rand.power <- test_random(marvel_friends, ", - " network_heterophily, attribute = \"PowerOrigin\", ", - " times = 1000)", "rand.attract <- test_random(marvel_friends, ", - " network_heterophily, attribute = \"Attractive\", ", - " times = 1000)", "plot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\")", + " network_heterophily, attribute = \"PowerOrigin\", ", + " times = 1000)", "rand.attract <- test_random(marvel_friends, ", + " network_heterophily, attribute = \"Attractive\", ", + " times = 1000)", "plot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\")", "plot(rand.power) + ggtitle(\"CUG test results for 'PowerOrigin' attribute\")", "plot(rand.attract) + ggtitle(\"CUG test results for 'Attractive' attribute\")" ), chunk_opts = list(label = "rando-solution")), tests = NULL, @@ -918,12 +917,12 @@

    Network linear models

    chunks = list(list(label = "perm", code = "", opts = list( label = "\"perm\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure(c("old <- autographr(marvel_friends, ", - " labels = FALSE, node_size = 6, ", " node_color = \"PowerOrigin\", ", - " node_shape = \"Gender\") + ggtitle(\"Original network\")", - "new <- autographr(generate_permutation(marvel_friends, with_attr = TRUE),", - " labels = FALSE, node_size = 6,", " node_color = \"PowerOrigin\",", - " node_shape = \"Gender\") + ggtitle(\"Permuted network\")", + check = NULL, solution = structure(c("old <- graphr(marvel_friends,", + " labels = FALSE, node_size = 6,", " node_color = \"PowerOrigin\",", + " node_shape = \"Gender\") + ggtitle(\"Original network\")", + "new <- graphr(generate_permutation(marvel_friends, with_attr = TRUE),", + " labels = FALSE, node_size = 6,", " node_color = \"PowerOrigin\",", + " node_shape = \"Gender\") + ggtitle(\"Permuted network\")", "old + new"), chunk_opts = list(label = "perm-solution")), tests = NULL, options = list(eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, tidy.opts = NULL, collapse = FALSE, prompt = FALSE, @@ -952,25 +951,25 @@

    Network linear models

    @@ -1001,8 +1000,8 @@

    Network linear models

    "library(manynet)", "library(migraph)", "library(patchwork)", "library(ggplot2)", "knitr::opts_chunk$set(echo = FALSE)", "marvel_friends <- to_unsigned(ison_marvel_relationships, keep = \"positive\")", "marvel_friends <- to_giant(marvel_friends)", "marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances))" -), chunk_opts = list(label = "setup", include = FALSE)), setup = "rand.gender <- test_random(marvel_friends, \n network_heterophily, attribute = \"Gender\", \n times = 1000)\nrand.power <- test_random(marvel_friends, \n network_heterophily, attribute = \"PowerOrigin\", \n times = 1000)\nrand.attract <- test_random(marvel_friends, \n network_heterophily, attribute = \"Attractive\", \n times = 1000)\nplot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\")\nplot(rand.power) + ggtitle(\"CUG test results for 'PowerOrigin' attribute\")\nplot(rand.attract) + ggtitle(\"CUG test results for 'Attractive' attribute\")", - chunks = list(list(label = "rando-solution", code = "rand.gender <- test_random(marvel_friends, \n network_heterophily, attribute = \"Gender\", \n times = 1000)\nrand.power <- test_random(marvel_friends, \n network_heterophily, attribute = \"PowerOrigin\", \n times = 1000)\nrand.attract <- test_random(marvel_friends, \n network_heterophily, attribute = \"Attractive\", \n times = 1000)\nplot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\")\nplot(rand.power) + ggtitle(\"CUG test results for 'PowerOrigin' attribute\")\nplot(rand.attract) + ggtitle(\"CUG test results for 'Attractive' attribute\")", +), chunk_opts = list(label = "setup", include = FALSE)), setup = "rand.gender <- test_random(marvel_friends, \n network_heterophily, attribute = \"Gender\", \n times = 1000)\nrand.power <- test_random(marvel_friends, \n network_heterophily, attribute = \"PowerOrigin\", \n times = 1000)\nrand.attract <- test_random(marvel_friends, \n network_heterophily, attribute = \"Attractive\", \n times = 1000)\nplot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\")\nplot(rand.power) + ggtitle(\"CUG test results for 'PowerOrigin' attribute\")\nplot(rand.attract) + ggtitle(\"CUG test results for 'Attractive' attribute\")", + chunks = list(list(label = "rando-solution", code = "rand.gender <- test_random(marvel_friends, \n network_heterophily, attribute = \"Gender\", \n times = 1000)\nrand.power <- test_random(marvel_friends, \n network_heterophily, attribute = \"PowerOrigin\", \n times = 1000)\nrand.attract <- test_random(marvel_friends, \n network_heterophily, attribute = \"Attractive\", \n times = 1000)\nplot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\")\nplot(rand.power) + ggtitle(\"CUG test results for 'PowerOrigin' attribute\")\nplot(rand.attract) + ggtitle(\"CUG test results for 'Attractive' attribute\")", opts = list(label = "\"rando-solution\""), engine = "r"), list(label = "testperm", code = "", opts = list(label = "\"testperm\"", exercise = "TRUE", exercise.setup = "\"rando-solution\"", @@ -1010,7 +1009,7 @@

    Network linear models

    error_check = NULL, check = NULL, solution = structure(c("(perm.gender <- test_permutation(marvel_friends, ", " network_heterophily, attribute = \"Gender\",", " times = 1000))", "(perm.power <- test_permutation(marvel_friends, ", - " network_heterophily, attribute = \"PowerOrigin\",", + " network_heterophily, attribute = \"PowerOrigin\",", " times = 1000))", "", "(plot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\") + theme(plot.title = element_text(size=8)) | plot(rand.power) + ggtitle(\"CUG test results for 'PowerOrigin' attribute\") + theme(plot.title = element_text(size=8))) /", "(plot(perm.gender) + ggtitle(\"QAP test results for 'Gender' attribute\") + theme(plot.title = element_text(size=8)) | plot(perm.power) + ggtitle(\"QAP test results for 'PowerOrigin' attribute\") + theme(plot.title = element_text(size=8)))" ), chunk_opts = list(label = "testperm-solution", purl = FALSE)), @@ -1041,25 +1040,25 @@

    Network linear models

    @@ -1091,7 +1090,7 @@

    Network linear models

    "library(ggplot2)", "knitr::opts_chunk$set(echo = FALSE)", "marvel_friends <- to_unsigned(ison_marvel_relationships, keep = \"positive\")", "marvel_friends <- to_giant(marvel_friends)", "marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances))" ), chunk_opts = list(label = "setup", include = FALSE)), setup = NULL, - chunks = list(list(label = "introeies", code = "ison_networkers\nautographr(ison_networkers,\n node_color = \"Discipline\")", + chunks = list(list(label = "introeies", code = "ison_networkers\ngraphr(ison_networkers, node_color = \"Discipline\")", opts = list(label = "\"introeies\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = NULL, tests = NULL, @@ -1112,9 +1111,8 @@

    Network linear models

    message = TRUE, render = NULL, ref.label = NULL, child = NULL, engine = "r", split = FALSE, include = TRUE, purl = FALSE, max.print = 1000, label = "introeies", exercise = TRUE, - code = c("ison_networkers", "autographr(ison_networkers,", - " node_color = \"Discipline\")"), out.width.px = 624, - out.height.px = 384, params.src = "introeies, exercise=TRUE, purl = FALSE", + code = c("ison_networkers", "graphr(ison_networkers, node_color = \"Discipline\")" + ), out.width.px = 624, out.height.px = 384, params.src = "introeies, exercise=TRUE, purl = FALSE", fig.num = 0, exercise.df_print = "paged", exercise.checker = "NULL"), engine = "r", version = "4"), class = c("r", "tutorial_exercise" ))) @@ -1212,31 +1210,31 @@

    Network linear models

    From 43eb71bc469131a7c7f7f2e8d11e0b9e8b937233 Mon Sep 17 00:00:00 2001 From: Jael Tan Date: Tue, 18 Jun 2024 11:40:40 +0200 Subject: [PATCH 50/97] Updated equivalence function names in function description --- R/member_equivalence.R | 8 ++++---- man/equivalence.Rd | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/R/member_equivalence.R b/R/member_equivalence.R index 78a3472a..1a8420d2 100644 --- a/R/member_equivalence.R +++ b/R/member_equivalence.R @@ -5,14 +5,14 @@ #' together with methods for calculating the hierarchical clusters #' provided by a certain distance calculation. #' -#' - `node_equivalence()` assigns nodes membership based on their equivalence +#' - `node_in_equivalence()` assigns nodes membership based on their equivalence #' with respective to some census/class. #' The following functions call this function, together with an appropriate census. -#' - `node_structural_equivalence()` assigns nodes membership based on their +#' - `node_in_structural()` assigns nodes membership based on their #' having equivalent ties to the same other nodes. -#' - `node_regular_equivalence()` assigns nodes membership based on their +#' - `node_in_regular()` assigns nodes membership based on their #' having equivalent patterns of ties. -#' - `node_automorphic_equivalence()` assigns nodes membership based on their +#' - `node_in_automorphic()` assigns nodes membership based on their #' having equivalent distances to other nodes. #' #' A `plot()` method exists for investigating the dendrogram diff --git a/man/equivalence.Rd b/man/equivalence.Rd index 094b0018..d7f0e59c 100644 --- a/man/equivalence.Rd +++ b/man/equivalence.Rd @@ -86,15 +86,15 @@ These functions combine an appropriate \verb{_census()} function together with methods for calculating the hierarchical clusters provided by a certain distance calculation. \itemize{ -\item \code{node_equivalence()} assigns nodes membership based on their equivalence +\item \code{node_in_equivalence()} assigns nodes membership based on their equivalence with respective to some census/class. The following functions call this function, together with an appropriate census. \itemize{ -\item \code{node_structural_equivalence()} assigns nodes membership based on their +\item \code{node_in_structural()} assigns nodes membership based on their having equivalent ties to the same other nodes. -\item \code{node_regular_equivalence()} assigns nodes membership based on their +\item \code{node_in_regular()} assigns nodes membership based on their having equivalent patterns of ties. -\item \code{node_automorphic_equivalence()} assigns nodes membership based on their +\item \code{node_in_automorphic()} assigns nodes membership based on their having equivalent distances to other nodes. } } From 5e06e2bb4337c0ef1b35e9909e3ee4abc573c7d9 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:16:27 +0200 Subject: [PATCH 51/97] Migrated cluster and k to manynet --- R/model_cluster.R | 134 ------------------------------------------- R/model_k.R | 141 ---------------------------------------------- 2 files changed, 275 deletions(-) delete mode 100644 R/model_cluster.R delete mode 100644 R/model_k.R diff --git a/R/model_cluster.R b/R/model_cluster.R deleted file mode 100644 index c0f4c9a5..00000000 --- a/R/model_cluster.R +++ /dev/null @@ -1,134 +0,0 @@ -#' Methods for equivalence clustering -#' -#' @description -#' These functions are used to cluster some census object: -#' -#' - `cluster_hierarchical()` returns a hierarchical clustering object -#' created by `stats::hclust()`. -#' - `cluster_concor()` returns a hierarchical clustering object -#' created from a convergence of correlations procedure (CONCOR). -#' -#' These functions are not intended to be called directly, -#' but are called within `node_equivalence()` and related functions. -#' They are exported and listed here to provide more detailed documentation. -#' @name cluster -#' @inheritParams equivalence -NULL - -#' @rdname cluster -#' @export -cluster_hierarchical <- function(census, distance){ - correlations <- manynet::to_correlation(t(census)) - dissimilarity <- 1 - correlations - distances <- stats::dist(dissimilarity, method = distance) - hc <- stats::hclust(distances) - hc$distances <- distances - hc -} - -# cluster_concor(ison_adolescents) -# cluster_concor(ison_southern_women) -# https://github.com/bwlewis/hclust_in_R/blob/master/hc.R - -#' @rdname cluster -#' @section CONCOR: -#' -#' First a matrix of Pearson correlation coefficients between each pair of nodes -#' profiles in the given census is created. -#' Then, again, we find the correlations of this square, symmetric matrix, -#' and continue to do this iteratively until each entry is either `1` or `-1`. -#' These values are used to split the data into two partitions, -#' with members either holding the values `1` or `-1`. -#' This procedure from census to convergence is then repeated within each block, -#' allowing further partitions to be found. -#' Unlike UCINET, partitions are continued until there are single members in -#' each partition. -#' Then a distance matrix is constructed from records of in which partition phase -#' nodes were separated, -#' and this is given to `stats::hclust()` so that dendrograms etc can be returned. -#' @importFrom stats complete.cases -#' @references -#' Breiger, Ronald L., Scott A. Boorman, and Phipps Arabie. 1975. -#' "An Algorithm for Clustering Relational Data with Applications to -#' Social Network Analysis and Comparison with Multidimensional Scaling". -#' _Journal of Mathematical Psychology_, 12: 328-83. -#' \doi{10.1016/0022-2496(75)90028-0}. -#' @export -cluster_concor <- function(.data, census){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - split_cor <- function(m0, cutoff = 1) { - if (ncol(m0) < 2 | all(manynet::to_correlation(m0)==1)) list(m0) - else { - mi <- manynet::to_correlation(m0) - while (any(abs(mi) <= cutoff)) { - mi <- stats::cor(mi) - cutoff <- cutoff - 0.0001 - } - group <- mi[, 1] > 0 - if(all(group)){ - list(m0) - } else { - list(m0[, group, drop = FALSE], - m0[, !group, drop = FALSE]) - } - } - } - p_list <- list(t(census)) - if(is.null(colnames(p_list[[1]]))) - colnames(p_list[[1]]) <- paste0("V",1:ncol(p_list[[1]])) - p_group <- list() - if(manynet::is_twomode(.data)){ - p_list <- list(p_list[[1]][, !manynet::node_mode(.data), drop = FALSE], - p_list[[1]][, manynet::node_mode(.data), drop = FALSE]) - p_group[[1]] <- lapply(p_list, function(z) colnames(z)) - i <- 2 - } else i <- 1 - while(!all(vapply(p_list, function(x) ncol(x)==1, logical(1)))){ - p_list <- unlist(lapply(p_list, - function(y) split_cor(y)), - recursive = FALSE) - p_group[[i]] <- lapply(p_list, function(z) colnames(z)) - if(i > 2 && length(p_group[[i]]) == length(p_group[[i-1]])) break - i <- i+1 - } - - if(manynet::is_labelled(.data)){ - merges <- sapply(rev(1:(i-1)), - function(p) lapply(p_group[[p]], - function(s){ - g <- match(s, manynet::node_names(.data)) - if(length(g)==1) c(g, 0, p) else - if(length(g)==2) c(g, p) else - c(t(cbind(t(utils::combn(g, 2)), p))) - } )) - } else { - merges <- sapply(rev(1:(i-1)), - function(p) lapply(p_group[[p]], - function(s){ - g <- as.numeric(gsub("^V","",s)) - if(length(g)==1) c(g, 0, p) else - if(length(g)==2) c(g, p) else - c(t(cbind(t(utils::combn(g, 2)), p))) - } )) - } - merges <- c(merges, - list(c(t(cbind(t(utils::combn(seq_len(manynet::network_nodes(.data)), 2)), 0))))) - merged <- matrix(unlist(merges), ncol = 3, byrow = TRUE) - merged <- merged[!duplicated(merged[,1:2]),] - merged[,3] <- abs(merged[,3] - max(merged[,3])) - merged[merged == 0] <- NA - merged <- merged[stats::complete.cases(merged),] - merged <- as.data.frame(merged) - names(merged) <- c("from","to","weight") - - distances <- manynet::as_matrix(manynet::as_igraph(merged)) - distances <- distances + t(distances) - # distances <- distances[-which(rownames(distances)==0),-which(colnames(distances)==0)] - if(manynet::is_labelled(.data)) - rownames(distances) <- colnames(distances) <- manynet::node_names(.data) - hc <- hclust(d = as.dist(distances)) - hc$method <- "concor" - hc$distances <- distances - hc -} - diff --git a/R/model_k.R b/R/model_k.R deleted file mode 100644 index 16e5642a..00000000 --- a/R/model_k.R +++ /dev/null @@ -1,141 +0,0 @@ -#' Methods for selecting clusters -#' -#' @description -#' These functions help select the number of clusters to return from `hc`, -#' some hierarchical clustering object: -#' -#' - `k_strict()` selects a number of clusters in which there is no -#' distance between cluster members. -#' - `k_elbow()` selects a number of clusters in which there is -#' a fair trade-off between parsimony and fit according to the elbow method. -#' - `k_silhouette()` selects a number of clusters that -#' optimises the silhouette score. -#' -#' These functions are generally not user-facing but used internally -#' in e.g. the `*_equivalence()` functions. -#' -#' @inheritParams cohesion -#' @param hc A hierarchical clustering object. -#' @references -#' Thorndike, Robert L. 1953. -#' "Who Belongs in the Family?". -#' _Psychometrika_, 18(4): 267–76. -#' \doi{10.1007/BF02289263}. -#' -#' Rousseeuw, Peter J. 1987. -#' “Silhouettes: A Graphical Aid to the Interpretation and Validation of Cluster Analysis.” -#' _Journal of Computational and Applied Mathematics_, 20: 53–65. -#' \doi{10.1016/0377-0427(87)90125-7}. -#' @name kselect -NULL - -#' @rdname kselect -#' @export -k_strict <- function(hc, .data){ - zero_merged <- hc$merge[round(hc$height,4) == 0,] - k <- nrow(zero_merged) + manynet::network_nodes(.data) - sum(zero_merged < 0) + sum(zero_merged > 0) - k -} - -#' @rdname kselect -#' @param census A motif census object. -#' @param range An integer indicating the maximum number of options to consider. -#' The minimum of this and the number of nodes in the network is used. -#' @export -k_elbow <- function(hc, .data, census, range){ - - clusterCorr <- function(observed_cor_matrix, cluster_vector) { - num_vertices = nrow(observed_cor_matrix) - cluster_cor_mat <- observed_cor_matrix - - obycor <- function(i, j) - mean(observed_cor_matrix[which(cluster_vector[row(observed_cor_matrix)] == - cluster_vector[i] & - cluster_vector[col(observed_cor_matrix)] == - cluster_vector[j])]) - obycor_v <- Vectorize(obycor) - cluster_cor_mat <- outer(1:num_vertices, - 1:num_vertices, - obycor_v) - dimnames(cluster_cor_mat) <- dimnames(observed_cor_matrix) - cluster_cor_mat - } - - elbow_finder <- function(x_values, y_values) { - # Max values to create line - if(min(x_values)==1) x_values <- x_values[2:length(x_values)] - if(min(y_values)==0) y_values <- y_values[2:length(y_values)] - max_df <- data.frame(x = c(min(x_values), max(x_values)), - y = c(min(y_values), max(y_values))) - # Creating straight line between the max values - fit <- stats::lm(max_df$y ~ max_df$x) - # Distance from point to line - distances <- vector() - for (i in seq_len(length(x_values))) { - distances <- c(distances, - abs(stats::coef(fit)[2]*x_values[i] - - y_values[i] + - coef(fit)[1]) / - sqrt(stats::coef(fit)[2]^2 + 1^2)) - } - # Max distance point - x_max_dist <- x_values[which.max(distances)] - x_max_dist - } - - vertices <- manynet::network_nodes(.data) - observedcorrelation <- cor(t(census)) - - resultlist <- list() - correlations <- vector() - for (i in 2:min(range, vertices)) { - cluster_result <- list(label = NA, clusters = NA, correlation = NA) - cluster_result$label <- paste("number of clusters: ", - i) - clusters <- stats::cutree(hc, k = i) - cluster_result$clusters <- clusters - cluster_cor_mat <- clusterCorr(observedcorrelation, clusters) - clustered_observed_cors <- sna::gcor(cluster_cor_mat, observedcorrelation) - cluster_result$correlation <- (clustered_observed_cors) - resultlist <- c(resultlist, cluster_result) - correlations <- c(correlations, clustered_observed_cors) - } - - resultlist$correlations <- c(correlations) - dafr <- data.frame(clusters = 2:min(range, vertices), - correlations = c(correlations)) - correct <- NULL # to satisfy the error god - - # k identification method - elbow_finder(dafr$clusters, dafr$correlations) -} - -#' @rdname kselect -#' @export -k_silhouette <- function(hc, .data, range){ - kcs <- 2:min(range, manynet::network_nodes(.data)) - ns <- seq_len(manynet::network_nodes(.data)) - distances <- hc$distances - ks <- vector() - for(kc in kcs){ - cand <- stats::cutree(hc, kc) - ai <- vector() - bi <- vector() - for(i in ns){ - wig <- which(cand == cand[i]) - wig <- wig[wig != i] - ai <- c(ai, - ifelse(length(wig)==0, - 0, mean(as.matrix(distances)[i, wig]))) - wog <- which(cand != cand[i]) - bi <- c(bi, min(vapply(unique(cand[wog]), function(b){ - mean(as.matrix(distances)[i, wog[cand[wog]==b]]) - }, FUN.VALUE = numeric(1)))) - } - si <- (bi - ai)/ - apply(data.frame(ai, bi), 1, max) - ks <- c(ks, mean(si)) - } - k <- which(ks == max(ks)) + 1 - k -} From 22c4b43aa3bd3346791aa9ead1a002cf215ea063 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:16:47 +0200 Subject: [PATCH 52/97] Migrated centrality measures to manynet --- R/measure_centrality.R | 851 -------------------------------------- man/between_centrality.Rd | 111 ----- man/close_centrality.Rd | 122 ------ man/degree_centrality.Rd | 176 -------- man/eigenv_centrality.Rd | 166 -------- 5 files changed, 1426 deletions(-) delete mode 100644 R/measure_centrality.R delete mode 100644 man/between_centrality.Rd delete mode 100644 man/close_centrality.Rd delete mode 100644 man/degree_centrality.Rd delete mode 100644 man/eigenv_centrality.Rd diff --git a/R/measure_centrality.R b/R/measure_centrality.R deleted file mode 100644 index cd3923d1..00000000 --- a/R/measure_centrality.R +++ /dev/null @@ -1,851 +0,0 @@ -# Degree-like centralities #### - -#' Measures of degree-like centrality and centralisation -#' -#' @description -#' These functions calculate common degree-related centrality measures for one- and two-mode networks: -#' -#' - `node_degree()` measures the degree centrality of nodes in an unweighted network, -#' or weighted degree/strength of nodes in a weighted network; -#' there are several related shortcut functions: -#' - `node_deg()` returns the unnormalised results. -#' - `node_indegree()` returns the `direction = 'in'` results. -#' - `node_outdegree()` returns the `direction = 'out'` results. -#' - `node_multidegree()` measures the ratio between types of ties in a multiplex network. -#' - `node_posneg()` measures the PN (positive-negative) centrality of a signed network. -#' - `tie_degree()` measures the degree centrality of ties in a network -#' - `network_degree()` measures a network's degree centralization; -#' there are several related shortcut functions: -#' - `network_indegree()` returns the `direction = 'out'` results. -#' - `network_outdegree()` returns the `direction = 'out'` results. -#' -#' All measures attempt to use as much information as they are offered, -#' including whether the networks are directed, weighted, or multimodal. -#' If this would produce unintended results, -#' first transform the salient properties using e.g. [to_undirected()] functions. -#' All centrality and centralization measures return normalized measures by default, -#' including for two-mode networks. -#' @name degree_centrality -#' @family centrality -#' @family measures -#' @seealso [to_undirected()] for removing edge directions -#' and [to_unweighted()] for removing weights from a graph. -#' @inheritParams cohesion -#' @param normalized Logical scalar, whether the centrality scores are normalized. -#' Different denominators are used depending on whether the object is one-mode or two-mode, -#' the type of centrality, and other arguments. -#' @param alpha Numeric scalar, the positive tuning parameter introduced in -#' Opsahl et al (2010) for trading off between degree and strength centrality measures. -#' By default, `alpha = 0`, which ignores tie weights and the measure is solely based -#' upon degree (the number of ties). -#' `alpha = 1` ignores the number of ties and provides the sum of the tie weights -#' as strength centrality. -#' Values between 0 and 1 reflect different trade-offs in the relative contributions of -#' degree and strength to the final outcome, with 0.5 as the middle ground. -#' Values above 1 penalise for the number of ties. -#' Of two nodes with the same sum of tie weights, the node with fewer ties will obtain -#' the higher score. -#' This argument is ignored except in the case of a weighted network. -#' @param direction Character string, “out” bases the measure on outgoing ties, -#' “in” on incoming ties, and "all" on either/the sum of the two. -#' For two-mode networks, "all" uses as numerator the sum of differences -#' between the maximum centrality score for the mode -#' against all other centrality scores in the network, -#' whereas "in" uses as numerator the sum of differences -#' between the maximum centrality score for the mode -#' against only the centrality scores of the other nodes in that mode. -#' @return A single centralization score if the object was one-mode, -#' and two centralization scores if the object was two-mode. -#' @importFrom rlang enquo eval_tidy -#' @importFrom igraph graph_from_incidence_matrix is_bipartite degree V -#' @references -#' Faust, Katherine. 1997. -#' "Centrality in affiliation networks." -#' _Social Networks_ 19(2): 157-191. -#' \doi{10.1016/S0378-8733(96)00300-0}. -#' -#' Borgatti, Stephen P., and Martin G. Everett. 1997. -#' "Network analysis of 2-mode data." -#' _Social Networks_ 19(3): 243-270. -#' \doi{10.1016/S0378-8733(96)00301-2}. -#' -#' Borgatti, Stephen P., and Daniel S. Halgin. 2011. -#' "Analyzing affiliation networks." -#' In _The SAGE Handbook of Social Network Analysis_, -#' edited by John Scott and Peter J. Carrington, 417–33. -#' London, UK: Sage. -#' \doi{10.4135/9781446294413.n28}. -#' -#' Opsahl, Tore, Filip Agneessens, and John Skvoretz. 2010. -#' "Node centrality in weighted networks: Generalizing degree and shortest paths." -#' _Social Networks_ 32, 245-251. -#' \doi{10.1016/j.socnet.2010.03.006} -#' @examples -#' node_degree(mpn_elite_mex) -#' node_degree(ison_southern_women) -#' @return Depending on how and what kind of an object is passed to the function, -#' the function will return a `tidygraph` object where the nodes have been updated -NULL - -#' @rdname degree_centrality -#' @importFrom manynet as_igraph -#' @export -node_degree <- function (.data, normalized = TRUE, alpha = 1, - direction = c("all","out","in")){ - - if(missing(.data)) {expect_nodes(); .data <- .G()} - graph <- manynet::as_igraph(.data) - weights <- `if`(manynet::is_weighted(.data), - manynet::tie_weights(.data), NA) - direction <- match.arg(direction) - - # Do the calculations - if (manynet::is_twomode(graph) & normalized){ - degrees <- igraph::degree(graph = graph, - v = igraph::V(graph), - mode = direction, - loops = manynet::is_complex(.data)) - other_set_size <- ifelse(igraph::V(graph)$type, - sum(!igraph::V(graph)$type), - sum(igraph::V(graph)$type)) - out <- degrees/other_set_size - } else { - if (all(is.na(weights))) { - out <- igraph::degree(graph = graph, v = igraph::V(graph), - mode = direction, - loops = manynet::is_complex(.data), - normalized = normalized) - } - else { - ki <- igraph::degree(graph = graph, v = igraph::V(graph), - mode = direction, - loops = manynet::is_complex(.data)) - si <- igraph::strength(graph = graph, vids = igraph::V(graph), - mode = direction, - loops = manynet::is_complex(.data), weights = weights) - out <- ki * (si/ki)^alpha - if(normalized) out <- out/max(out) - } - } - out <- make_node_measure(out, .data) - out -} - -#' @rdname degree_centrality -#' @export -node_deg <- function (.data, alpha = 0, direction = c("all","out","in")){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - node_degree(.data, normalized = FALSE, alpha = alpha, direction = direction) -} - -#' @rdname degree_centrality -#' @export -node_outdegree <- function (.data, normalized = TRUE, alpha = 0){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - node_degree(.data, normalized = normalized, alpha = alpha, direction = "out") -} - -#' @rdname degree_centrality -#' @export -node_indegree <- function (.data, normalized = TRUE, alpha = 0){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - node_degree(.data, normalized = normalized, alpha = alpha, direction = "in") -} - -#' @rdname degree_centrality -#' @param tie1 Character string indicating the first uniplex network. -#' @param tie2 Character string indicating the second uniplex network. -#' @export -node_multidegree <- function (.data, tie1, tie2){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - stopifnot(manynet::is_multiplex(.data)) - out <- node_degree(manynet::to_uniplex(.data, tie1)) - - node_degree(manynet::to_uniplex(.data, tie2)) - make_node_measure(out, .data) -} - -#' @rdname degree_centrality -#' @references -#' Everett, Martin G., and Stephen P. Borgatti. 2014. -#' “Networks Containing Negative Ties.” -#' _Social Networks_ 38:111–20. -#' \doi{10.1016/j.socnet.2014.03.005}. -#' @export -node_posneg <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - stopifnot(manynet::is_signed(.data)) - pos <- manynet::as_matrix(manynet::to_unsigned(.data, keep = "positive")) - neg <- manynet::as_matrix(manynet::to_unsigned(.data, keep = "negative")) - nn <- manynet::network_nodes(.data) - pn <- pos-neg*2 - diag(pn) <- 0 - idmat <- diag(nn) - v1 <- matrix(1,nn,1) - out <- solve(idmat - ((pn%*%t(pn))/(4*(nn-1)^2))) %*% (idmat+( pn/(2*(nn-1)) )) %*% v1 - make_node_measure(out, .data) -} - -#' @rdname degree_centrality -#' @examples -#' tie_degree(ison_adolescents) -#' @export -tie_degree <- function(.data, normalized = TRUE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - edge_adj <- manynet::to_ties(.data) - out <- node_degree(edge_adj, normalized = normalized) - class(out) <- "numeric" - out <- make_tie_measure(out, .data) - out -} - -#' @rdname degree_centrality -#' @examples -#' network_degree(ison_southern_women, direction = "in") -#' @export -network_degree <- function(.data, normalized = TRUE, - direction = c("all", "out", "in")){ - - if(missing(.data)) {expect_nodes(); .data <- .G()} - direction <- match.arg(direction) - - if (manynet::is_twomode(.data)) { - mat <- manynet::as_matrix(.data) - mode <- c(rep(FALSE, nrow(mat)), rep(TRUE, ncol(mat))) - - out <- list() - if (direction == "all") { - if (!normalized) { - allcent <- c(rowSums(mat), colSums(mat)) - out$nodes1 <- sum(max(allcent[!mode]) - allcent)/((nrow(mat) + ncol(mat))*ncol(mat) - 2*(ncol(mat) + nrow(mat) - 1)) - out$nodes2 <- sum(max(allcent[mode]) - allcent)/((nrow(mat) + ncol(mat))*nrow(mat) - 2*(ncol(mat) + nrow(mat) - 1)) - } else if (normalized) { - allcent <- node_degree(mat, normalized = TRUE) - out$nodes1 <- sum(max(allcent[!mode]) - allcent)/((nrow(mat) + ncol(mat) - 1) - (ncol(mat) - 1) / nrow(mat) - (ncol(mat) + nrow(mat) - 1)/nrow(mat)) - out$nodes2 <- sum(max(allcent[mode]) - allcent)/((ncol(mat) + nrow(mat) - 1) - (nrow(mat) - 1) / ncol(mat) - (nrow(mat) + ncol(mat) - 1)/ncol(mat)) - } - } else if (direction == "in") { - out$nodes1 <- sum(max(rowSums(mat)) - rowSums(mat))/((ncol(mat) - 1)*(nrow(mat) - 1)) - out$nodes2 <- sum(max(colSums(mat)) - colSums(mat))/((ncol(mat) - 1)*(nrow(mat) - 1)) - } - out <- c("Mode 1" = out$nodes1, "Mode 2" = out$nodes2) - } else { - out <- igraph::centr_degree(graph = .data, mode = direction, - normalized = normalized)$centralization - } - out <- make_network_measure(out, .data) - out -} - -#' @rdname degree_centrality -#' @export -network_outdegree <- function(.data, normalized = TRUE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - network_degree(.data, normalized = normalized, direction = "out") -} - -#' @rdname degree_centrality -#' @export -network_indegree <- function(.data, normalized = TRUE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - network_degree(.data, normalized = normalized, direction = "in") -} - -# Betweenness-like centralities #### - -#' Measures of betweenness-like centrality and centralisation -#' @description -#' These functions calculate common betweenness-related centrality measures for one- and two-mode networks: -#' -#' - `node_betweenness()` measures the betweenness centralities of nodes in a network. -#' - `node_induced()` measures the induced betweenness centralities of nodes in a network. -#' - `node_flow()` measures the flow betweenness centralities of nodes in a network, -#' which uses an electrical current model for information spreading -#' in contrast to the shortest paths model used by normal betweenness centrality. -#' - `tie_betweenness()` measures the number of shortest paths going through a tie. -#' - `network_betweenness()` measures the betweenness centralization for a network. -#' -#' All measures attempt to use as much information as they are offered, -#' including whether the networks are directed, weighted, or multimodal. -#' If this would produce unintended results, -#' first transform the salient properties using e.g. [to_undirected()] functions. -#' All centrality and centralization measures return normalized measures by default, -#' including for two-mode networks. -#' @name between_centrality -#' @family centrality -#' @family measures -#' @inheritParams degree_centrality -#' @param cutoff The maximum path length to consider when calculating betweenness. -#' If negative or NULL (the default), there's no limit to the path lengths considered. -NULL - -#' @rdname between_centrality -#' @import tidygraph -#' @examples -#' node_betweenness(mpn_elite_mex) -#' node_betweenness(ison_southern_women) -#' @return A numeric vector giving the betweenness centrality measure of each node. -#' @export -node_betweenness <- function(.data, normalized = TRUE, - cutoff = NULL){ - - if(missing(.data)) {expect_nodes(); .data <- .G()} - weights <- `if`(manynet::is_weighted(.data), - manynet::tie_weights(.data), NA) - graph <- manynet::as_igraph(.data) - - # Do the calculations - if (manynet::is_twomode(graph) & normalized){ - betw_scores <- igraph::betweenness(graph = graph, v = igraph::V(graph), - directed = manynet::is_directed(graph)) - other_set_size <- ifelse(igraph::V(graph)$type, sum(!igraph::V(graph)$type), sum(igraph::V(graph)$type)) - set_size <- ifelse(igraph::V(graph)$type, sum(igraph::V(graph)$type), sum(!igraph::V(graph)$type)) - out <- ifelse(set_size > other_set_size, - betw_scores/(2*(set_size-1)*(other_set_size-1)), - betw_scores/(1/2*other_set_size*(other_set_size-1)+1/2*(set_size-1)*(set_size-2)+(set_size-1)*(other_set_size-1))) - } else { - if (is.null(cutoff)) { - out <- igraph::betweenness(graph = graph, v = igraph::V(graph), - directed = manynet::is_directed(graph), weights = weights, - normalized = normalized) - } else { - out <- igraph::betweenness(graph = graph, v = igraph::V(graph), - directed = manynet::is_directed(graph), - cutoff = cutoff, - weights = weights) - } - } - out <- make_node_measure(out, .data) - out -} - -#' @rdname between_centrality -#' @examples -#' node_induced(mpn_elite_mex) -#' @references -#' Everett, Martin and Steve Borgatti. 2010. -#' "Induced, endogenous and exogenous centrality" -#' _Social Networks_, 32: 339-344. -#' \doi{10.1016/j.socnet.2010.06.004} -#' @export -node_induced <- function(.data, normalized = TRUE, - cutoff = NULL){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - endog <- sum(node_betweenness(.data, normalized = normalized, cutoff = cutoff), - na.rm = TRUE) - exog <- vapply(seq.int(manynet::network_nodes(.data)), - function(x) sum(node_betweenness(manynet::delete_nodes(.data, x), - normalized = normalized, cutoff = cutoff), - na.rm = TRUE), - FUN.VALUE = numeric(1)) - out <- endog - exog - make_node_measure(out, .data) -} - - -#' @rdname between_centrality -#' @importFrom sna flowbet -#' @export -node_flow <- function(.data, normalized = TRUE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- sna::flowbet(manynet::as_network(.data), - gmode = ifelse(manynet::is_directed(.data), "digraph", "graph"), - diag = manynet::is_complex(.data), - cmode = ifelse(normalized, "normflow", "rawflow")) - make_node_measure(out, .data) -} - -#' @rdname between_centrality -#' @importFrom igraph edge_betweenness -#' @examples -#' (tb <- tie_betweenness(ison_adolescents)) -#' plot(tb) -#' #ison_adolescents %>% mutate_ties(weight = tb) %>% -#' # autographr() -#' @export -tie_betweenness <- function(.data, normalized = TRUE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - .data <- manynet::as_igraph(.data) - eddies <- manynet::as_edgelist(.data) - eddies <- paste(eddies[["from"]], eddies[["to"]], sep = "-") - out <- igraph::edge_betweenness(.data) - names(out) <- eddies - out <- make_tie_measure(out, .data) - out -} - -#' @rdname between_centrality -#' @examples -#' network_betweenness(ison_southern_women, direction = "in") -#' @export -network_betweenness <- function(.data, normalized = TRUE, - direction = c("all", "out", "in")) { - - if(missing(.data)) {expect_nodes(); .data <- .G()} - direction <- match.arg(direction) - graph <- manynet::as_igraph(.data) - - if (manynet::is_twomode(.data)) { - becent <- node_betweenness(graph, normalized = FALSE) - mode <- igraph::V(graph)$type - mode1 <- length(mode) - sum(mode) - mode2 <- sum(mode) - out <- list() - if (direction == "all") { - if (!normalized) { - out$nodes1 <- sum(max(becent[!mode]) - becent) / ((1/2 * mode2 * (mode2 - 1) + 1/2 * (mode1 - 1)*(mode1 - 2) + (mode1 - 1) * (mode2 - 2))*(mode1 + mode2 - 1) + (mode1 - 1)) - out$nodes2 <- sum(max(becent[mode]) - becent) / ((1/2 * mode1 * (mode1 - 1) + 1/2 * (mode2 - 1)*(mode2 - 2) + (mode2 - 1) * (mode1 - 2))*(mode2 + mode1 - 1) + (mode2 - 1)) - if (mode1 > mode2) { - out$nodes1 <- sum(max(becent[!mode]) - becent) / (2 * (mode1 - 1) * (mode2 - 1) * (mode1 + mode2 - 1) - (mode2 - 1) * (mode1 + mode2 - 2) - 1/2 * (mode1 - mode2) * (mode1 + 3*mode2 - 3)) - } - if (mode2 > mode1) { - out$nodes2 <- sum(max(becent[mode]) - becent) / (2 * (mode2 - 1) * (mode1 - 1) * (mode2 + mode1 - 1) - (mode1 - 1) * (mode2 + mode1 - 2) - 1/2 * (mode2 - mode1) * (mode2 + 3*mode1 - 3)) - } - } else if (normalized) { - out$nodes1 <- sum(max(becent[!mode]) - becent) / ((1/2 * mode2 * (mode2 - 1) + 1/2 * (mode1 - 1)*(mode1 - 2) + (mode1 - 1) * (mode2 - 2))*(mode1 + mode2 - 1) + (mode1 - 1)) - out$nodes2 <- sum(max(becent[mode]) - becent) / ((1/2 * mode1 * (mode1 - 1) + 1/2 * (mode2 - 1)*(mode2 - 2) + (mode2 - 1) * (mode1 - 2))*(mode2 + mode1 - 1) + (mode2 - 1)) - if (mode1 > mode2) { - becent <- node_betweenness(graph, normalized = TRUE) - out$nodes1 <- sum(max(becent[!mode]) - becent) / ((mode1 + mode2 - 1) - (((mode2 - 1)*(mode1 + mode2 - 2) + 1/2*(mode1 - mode2)*(mode1 + (3*mode2) - 3)) / (1/2*(mode1*(mode1 - 1)) + 1/2*(mode2 - 1) * (mode2 - 2) + (mode1 - 1) * (mode2 - 1)))) - } - if (mode2 > mode1) { - becent <- node_betweenness(graph, normalized = TRUE) - out$nodes2 <- sum(max(becent[mode]) - becent) / ((mode1 + mode2 - 1)*((mode1 - 1)*(mode1 + mode2 - 2) / 2*(mode1 - 1)*(mode2 - 1))) - } - } - } else if (direction == "in") { - out$nodes1 <- sum(max(becent[!mode]) - becent[!mode])/((mode1 - 1)*(1/2*mode2*(mode2 - 1) + 1/2*(mode1 - 1)*(mode1 - 2) + (mode1 - 1)*(mode2 - 1))) - out$nodes2 <- sum(max(becent[mode]) - becent[mode])/((mode2 - 1)*(1/2*mode1*(mode1 - 1) + 1/2 * (mode2 - 1) * (mode2 - 2) + (mode2 - 1) * (mode1 - 1))) - if (mode1 > mode2) { - out$nodes1 <- sum(max(becent[!mode]) - becent[!mode]) / (2 * (mode1 - 1)^2 * (mode2 - 1)) - } - if (mode2 > mode1) { - out$nodes2 <- sum(max(becent[mode]) - becent[mode]) / (2 * (mode2 - 1)^2 * (mode1 - 1)) - } - } - out <- c("Mode 1" = out$nodes1, "Mode 2" = out$nodes2) - } else { - out <- igraph::centr_betw(graph = graph)$centralization - } - out <- make_network_measure(out, .data) - out -} - -# Closeness-like centralities #### - -#' Measures of closeness-like centrality and centralisation -#' @description -#' These functions calculate common closeness-related centrality measures for one- and two-mode networks: -#' -#' - `node_closeness()` measures the closeness centrality of nodes in a network. -#' - `node_reach()` measures nodes' reach centrality, -#' or how many nodes they can reach within _k_ steps. -#' - `node_harmonic()` measures nodes' harmonic centrality or valued centrality, -#' which is thought to behave better than reach centrality for disconnected networks. -#' - `node_information()` measures nodes' information centrality or -#' current-flow closeness centrality. -#' - `tie_closeness()` measures the closeness of each tie to other ties in the network. -#' - `network_closeness()` measures a network's closeness centralization. -#' - `network_reach()` measures a network's reach centralization. -#' - `network_harmonic()` measures a network's harmonic centralization. -#' -#' All measures attempt to use as much information as they are offered, -#' including whether the networks are directed, weighted, or multimodal. -#' If this would produce unintended results, -#' first transform the salient properties using e.g. [to_undirected()] functions. -#' All centrality and centralization measures return normalized measures by default, -#' including for two-mode networks. -#' @name close_centrality -#' @family centrality -#' @family measures -#' @inheritParams degree_centrality -NULL - -#' @rdname close_centrality -#' @param cutoff Maximum path length to use during calculations. -#' @import tidygraph -#' @importFrom rlang %||% -#' @examples -#' node_closeness(mpn_elite_mex) -#' node_closeness(ison_southern_women) -#' @export -node_closeness <- function(.data, normalized = TRUE, - direction = "out", cutoff = NULL){ - - if(missing(.data)) {expect_nodes(); .data <- .G()} - weights <- `if`(manynet::is_weighted(.data), - manynet::tie_weights(.data), NA) - graph <- manynet::as_igraph(.data) - - # Do the calculations - if (manynet::is_twomode(graph) & normalized){ - # farness <- rowSums(igraph::distances(graph = graph)) - closeness <- igraph::closeness(graph = graph, vids = igraph::V(graph), mode = direction) - other_set_size <- ifelse(igraph::V(graph)$type, sum(!igraph::V(graph)$type), sum(igraph::V(graph)$type)) - set_size <- ifelse(igraph::V(graph)$type, sum(igraph::V(graph)$type), sum(!igraph::V(graph)$type)) - out <- closeness/(1/(other_set_size+2*set_size-2)) - } else { - cutoff <- cutoff %||% -1 - out <- igraph::closeness(graph = graph, vids = igraph::V(graph), mode = direction, - cutoff = cutoff, weights = weights, normalized = normalized) - } - out <- make_node_measure(out, .data) - out -} - -#' @rdname close_centrality -#' @param k Integer of steps out to calculate reach -#' @examples -#' node_reach(ison_adolescents) -#' @export -node_reach <- function(.data, normalized = TRUE, k = 2){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- rowSums(node_path_census(.data)<=k) - if(normalized) out <- out/(manynet::network_nodes(.data)-1) - out <- make_node_measure(out, .data) - out -} - -#' @rdname close_centrality -#' @references -#' Marchiori, M, and V Latora. 2000. -#' "Harmony in the small-world". -#' _Physica A_ 285: 539-546. -#' -#' Dekker, Anthony. 2005. -#' "Conceptual distance in social network analysis". -#' _Journal of Social Structure_ 6(3). -#' @export -node_harmonic <- function(.data, normalized = TRUE, k = -1){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- igraph::harmonic_centrality(as_igraph(.data), # weighted if present - normalized = normalized, cutoff = k) - out <- make_node_measure(out, .data) - out -} - -#' @rdname close_centrality -#' @importFrom sna infocent -#' @export -node_information <- function(.data, normalized = TRUE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- sna::infocent(manynet::as_network(.data), - gmode = ifelse(manynet::is_directed(.data), "digraph", "graph"), - diag = manynet::is_complex(.data)) - make_node_measure(out, .data) -} - -#' @rdname close_centrality -#' @examples -#' (ec <- tie_closeness(ison_adolescents)) -#' plot(ec) -#' #ison_adolescents %>% -#' # activate(edges) %>% mutate(weight = ec) %>% -#' # autographr() -#' @export -tie_closeness <- function(.data, normalized = TRUE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - edge_adj <- manynet::to_ties(.data) - out <- node_closeness(edge_adj, normalized = normalized) - class(out) <- "numeric" - out <- make_tie_measure(out, .data) - out -} - -#' @rdname close_centrality -#' @examples -#' network_closeness(ison_southern_women, direction = "in") -#' @export -network_closeness <- function(.data, normalized = TRUE, - direction = c("all", "out", "in")){ - - if(missing(.data)) {expect_nodes(); .data <- .G()} - direction <- match.arg(direction) - graph <- manynet::as_igraph(.data) - - if (manynet::is_twomode(.data)) { - clcent <- node_closeness(graph, normalized = TRUE) - mode <- igraph::V(graph)$type - mode1 <- length(mode) - sum(mode) - mode2 <- sum(mode) - out <- list() - if (direction == "in") { - out$nodes1 <- sum(max(clcent[!mode]) - clcent[!mode])/(((mode1 - 2)*(mode1 - 1))/(2 * mode1 - 3)) - out$nodes2 <- sum(max(clcent[mode]) - clcent[mode])/(((mode2 - 2)*(mode2 - 1))/(2 * mode2 - 3)) - if (mode1 > mode2) { #28.43 - lhs <- ((mode2 - 1)*(mode1 - 2) / (2 * mode1 - 3)) - rhs <- ((mode2 - 1)*(mode1 - mode2) / (mode1 + mode2 - 2)) - out$nodes1 <- sum(max(clcent[!mode]) - clcent[!mode])/( lhs + rhs) # 0.2135 - } - if (mode2 > mode1) { - lhs <- ((mode1 - 1)*(mode2 - 2) / (2 * mode2 - 3)) - rhs <- ((mode1 - 1)*(mode2 - mode1) / (mode2 + mode1 - 2)) - out$nodes2 <- sum(max(clcent[mode]) - clcent[mode])/( lhs + rhs) - } - } else { - term1 <- 2*(mode1 - 1) * (mode2 + mode1 - 4)/(3*mode2 + 4*mode1 - 8) - term2 <- 2*(mode1 - 1) * (mode1 - 2)/(2*mode2 + 3*mode1 - 6) - term3 <- 2*(mode1 - 1) * (mode2 - mode1 + 1)/(2*mode2 + 3*mode1 - 4) - out$nodes1 <- sum(max(clcent[!mode]) - clcent) / sum(term1, term2, term3) - term1 <- 2*(mode2 - 1) * (mode1 + mode2 - 4)/(3*mode1 + 4*mode2 - 8) - term2 <- 2*(mode2 - 1) * (mode2 - 2)/(2*mode1 + 3*mode2 - 6) - term3 <- 2*(mode2 - 1) * (mode1 - mode2 + 1)/(2*mode1 + 3*mode2 - 4) - out$nodes2 <- sum(max(clcent[mode]) - clcent) / sum(term1, term2, term3) - - if (mode1 > mode2) { - term1 <- 2*(mode2 - 1) * (mode2 + mode1 - 2) / (3 * mode2 + 4 * mode1 - 8) - term2 <- 2*(mode1 - mode2) * (2 * mode2 - 1) / (5 * mode2 + 2 * mode1 - 6) - term3 <- 2*(mode2 - 1) * (mode1 - 2) / (2 * mode2 + 3 * mode1 - 6) - term4 <- 2 * (mode2 - 1) / (mode1 + 4 * mode2 - 4) - out$nodes1 <- sum(max(clcent[!mode]) - clcent) / sum(term1, term2, term3, term4) - } - if (mode2 > mode1) { - term1 <- 2*(mode1 - 1) * (mode1 + mode2 - 2) / (3 * mode1 + 4 * mode2 - 8) - term2 <- 2*(mode2 - mode1) * (2 * mode1 - 1) / (5 * mode1 + 2 * mode2 - 6) - term3 <- 2*(mode1 - 1) * (mode2 - 2) / (2 * mode1 + 3 * mode2 - 6) - term4 <- 2 * (mode1 - 1) / (mode2 + 4 * mode1 - 4) - out$nodes2 <- sum(max(clcent[mode]) - clcent) / sum(term1, term2, term3, term4) - } - } - out <- c("Mode 1" = out$nodes1, "Mode 2" = out$nodes2) - } else { - out <- igraph::centr_clo(graph = graph, - mode = direction, - normalized = normalized)$centralization - } - out <- make_network_measure(out, .data) - out -} - -#' @rdname close_centrality -#' @export -network_reach <- function(.data, normalized = TRUE, k = 2){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - reaches <- node_reach(.data, normalized = FALSE, k = k) - out <- sum(max(reaches) - reaches) - if(normalized) out <- out / sum(manynet::network_nodes(.data) - reaches) - make_network_measure(out, .data) -} - -#' @rdname close_centrality -#' @export -network_harmonic <- function(.data, normalized = TRUE, k = 2){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - harm <- node_harmonic(.data, normalized = FALSE, k = k) - out <- sum(max(harm) - harm) - if(normalized) out <- out / sum(manynet::network_nodes(.data) - harm) - make_network_measure(out, .data) -} - -# Eigenvector-like centralities #### - -#' Measures of eigenvector-like centrality and centralisation -#' @description -#' These functions calculate common eigenvector-related centrality measures for one- and two-mode networks: -#' -#' - `node_eigenvector()` measures the eigenvector centrality of nodes in a network. -#' - `node_power()` measures the Bonacich, beta, or power centrality of nodes in a network. -#' - `node_alpha()` measures the alpha or Katz centrality of nodes in a network. -#' - `node_pagerank()` measures the pagerank centrality of nodes in a network. -#' - `tie_eigenvector()` measures the eigenvector centrality of ties in a network. -#' - `network_eigenvector()` measures the eigenvector centralization for a network. -#' -#' All measures attempt to use as much information as they are offered, -#' including whether the networks are directed, weighted, or multimodal. -#' If this would produce unintended results, -#' first transform the salient properties using e.g. [to_undirected()] functions. -#' All centrality and centralization measures return normalized measures by default, -#' including for two-mode networks. -#' @name eigenv_centrality -#' @family centrality -#' @family measures -#' @inheritParams degree_centrality -NULL - -#' @rdname eigenv_centrality -#' @section Eigenvector centrality: -#' Eigenvector centrality operates as a measure of a node's influence in a network. -#' The idea is that being connected to well-connected others results in a higher score. -#' Each node's eigenvector centrality can be defined as: -#' \deqn{x_i = \frac{1}{\lambda} \sum_{j \in N} a_{i,j} x_j} -#' where \eqn{a_{i,j} = 1} if \eqn{i} is linked to \eqn{j} and 0 otherwise, -#' and \eqn{\lambda} is a constant representing the principal eigenvalue. -#' Rather than performing this iteration, -#' most routines solve the eigenvector equation \eqn{Ax = \lambda x}. -#' @param scale Logical scalar, whether to rescale the vector so the maximum score is 1. -#' @details -#' We use `{igraph}` routines behind the scenes here for consistency and because they are often faster. -#' For example, `igraph::eigencentrality()` is approximately 25% faster than `sna::evcent()`. -#' @references -#' Bonacich, Phillip. 1991. -#' “Simultaneous Group and Individual Centralities.” -#' _Social Networks_ 13(2):155–68. -#' \doi{10.1016/0378-8733(91)90018-O}. -#' @examples -#' node_eigenvector(mpn_elite_mex) -#' node_eigenvector(ison_southern_women) -#' @return A numeric vector giving the eigenvector centrality measure of each node. -#' @export -node_eigenvector <- function(.data, normalized = TRUE, scale = FALSE){ - - if(missing(.data)) {expect_nodes(); .data <- .G()} - weights <- `if`(manynet::is_weighted(.data), - manynet::tie_weights(.data), NA) - graph <- manynet::as_igraph(.data) - - if(!manynet::is_connected(.data)) - warning("Unconnected networks will only allow nodes from one component have non-zero eigenvector scores.") - - # Do the calculations - if (!manynet::is_twomode(graph)){ - out <- igraph::eigen_centrality(graph = graph, - directed = manynet::is_directed(graph), scale = scale, - options = igraph::arpack_defaults())$vector - if (normalized) out <- out / sqrt(1/2) - if(scale) out <- out / max(out) - } else { - eigen1 <- manynet::to_mode1(graph) - eigen1 <- igraph::eigen_centrality(graph = eigen1, - directed = manynet::is_directed(eigen1), scale = scale, - options = igraph::arpack_defaults())$vector - eigen2 <- manynet::to_mode2(graph) - eigen2 <- igraph::eigen_centrality(graph = eigen2, - directed = manynet::is_directed(eigen2), scale = scale, - options = igraph::arpack_defaults())$vector - out <- c(eigen1, eigen2) - if (normalized) out <- out / sqrt(1/2) - if(scale) out <- out / max(out) - } - out <- make_node_measure(out, .data) - out -} - -#' @rdname eigenv_centrality -#' @param exponent Decay rate for the Bonacich power centrality score. -#' @section Power centrality: -#' Power or beta (or Bonacich) centrality -#' @references -#' Bonacich, Phillip. 1987. -#' “Power and Centrality: A Family of Measures.” -#' _The American Journal of Sociology_, 92(5): 1170–82. -#' \doi{10.1086/228631}. -#' @importFrom igraph power_centrality -#' @examples -#' node_power(ison_southern_women, exponent = 0.5) -#' @return A numeric vector giving each node's power centrality measure. -#' @export -node_power <- function(.data, normalized = TRUE, scale = FALSE, exponent = 1){ - - if(missing(.data)) {expect_nodes(); .data <- .G()} - weights <- `if`(manynet::is_weighted(.data), - manynet::tie_weights(.data), NA) - graph <- manynet::as_igraph(.data) - - # Do the calculations - if (!manynet::is_twomode(graph)){ - out <- igraph::power_centrality(graph = graph, - exponent = exponent, - rescale = scale) - if (normalized) out <- out / sqrt(1/2) - } else { - eigen1 <- manynet::to_mode1(graph) - eigen1 <- igraph::power_centrality(graph = eigen1, - exponent = exponent, - rescale = scale) - eigen2 <- manynet::to_mode2(graph) - eigen2 <- igraph::power_centrality(graph = eigen2, - exponent = exponent, - rescale = scale) - out <- c(eigen1, eigen2) - if (normalized) out <- out / sqrt(1/2) - } - out <- make_node_measure(out, .data) - out -} - -#' @rdname eigenv_centrality -#' @param alpha A constant that trades off the importance of external influence against the importance of connection. -#' When \eqn{\alpha = 0}, only the external influence matters. -#' As \eqn{\alpha} gets larger, only the connectivity matters and we reduce to eigenvector centrality. -#' By default \eqn{\alpha = 0.85}. -#' @section Alpha centrality: -#' Alpha or Katz (or Katz-Bonacich) centrality operates better than eigenvector centrality -#' for directed networks. -#' Eigenvector centrality will return 0s for all nodes not in the main strongly-connected component. -#' Each node's alpha centrality can be defined as: -#' \deqn{x_i = \frac{1}{\lambda} \sum_{j \in N} a_{i,j} x_j + e_i} -#' where \eqn{a_{i,j} = 1} if \eqn{i} is linked to \eqn{j} and 0 otherwise, -#' \eqn{\lambda} is a constant representing the principal eigenvalue, -#' and \eqn{e_i} is some external influence used to ensure that even nodes beyond the main -#' strongly connected component begin with some basic influence. -#' Note that many equations replace \eqn{\frac{1}{\lambda}} with \eqn{\alpha}, -#' hence the name. -#' -#' For example, if \eqn{\alpha = 0.5}, then each direct connection (or alter) would be worth \eqn{(0.5)^1 = 0.5}, -#' each secondary connection (or tertius) would be worth \eqn{(0.5)^2 = 0.25}, -#' each tertiary connection would be worth \eqn{(0.5)^3 = 0.125}, and so on. -#' -#' Rather than performing this iteration though, -#' most routines solve the equation \eqn{x = (I - \frac{1}{\lambda} A^T)^{-1} e}. -#' @importFrom igraph alpha_centrality -#' @references -#' Katz, Leo 1953. -#' "A new status index derived from sociometric analysis". -#' _Psychometrika_. 18(1): 39–43. -#' -#' Bonacich, P. and Lloyd, P. 2001. -#' “Eigenvector-like measures of centrality for asymmetric relations” -#' _Social Networks_. 23(3):191-201. -#' @export -node_alpha <- function(.data, alpha = 0.85){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - make_node_measure(igraph::alpha_centrality(manynet::as_igraph(.data), - alpha = alpha), - .data) -} - -#' @rdname eigenv_centrality -#' @references -#' Brin, Sergey and Page, Larry. 1998. -#' "The anatomy of a large-scale hypertextual web search engine". -#' _Proceedings of the 7th World-Wide Web Conference_. Brisbane, Australia. -#' @export -node_pagerank <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - make_node_measure(igraph::page_rank(manynet::as_igraph(.data)), - .data) -} - -#' @rdname eigenv_centrality -#' @examples -#' tie_eigenvector(ison_adolescents) -#' @export -tie_eigenvector <- function(.data, normalized = TRUE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - edge_adj <- manynet::to_ties(.data) - out <- node_eigenvector(edge_adj, normalized = normalized) - class(out) <- "numeric" - out <- make_tie_measure(out, .data) - out -} - -#' @rdname eigenv_centrality -#' @examples -#' network_eigenvector(mpn_elite_mex) -#' network_eigenvector(ison_southern_women) -#' @export -network_eigenvector <- function(.data, normalized = TRUE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if (manynet::is_twomode(.data)) { - out <- c(igraph::centr_eigen(manynet::as_igraph(manynet::to_mode1(.data)), - normalized = normalized)$centralization, - igraph::centr_eigen(manynet::as_igraph(manynet::to_mode2(.data)), - normalized = normalized)$centralization) - } else { - out <- igraph::centr_eigen(manynet::as_igraph(.data), - normalized = normalized)$centralization - } - out <- make_network_measure(out, .data) - out -} - - diff --git a/man/between_centrality.Rd b/man/between_centrality.Rd deleted file mode 100644 index 660b189d..00000000 --- a/man/between_centrality.Rd +++ /dev/null @@ -1,111 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_centrality.R -\name{between_centrality} -\alias{between_centrality} -\alias{node_betweenness} -\alias{node_induced} -\alias{node_flow} -\alias{tie_betweenness} -\alias{network_betweenness} -\title{Measures of betweenness-like centrality and centralisation} -\usage{ -node_betweenness(.data, normalized = TRUE, cutoff = NULL) - -node_induced(.data, normalized = TRUE, cutoff = NULL) - -node_flow(.data, normalized = TRUE) - -tie_betweenness(.data, normalized = TRUE) - -network_betweenness( - .data, - normalized = TRUE, - direction = c("all", "out", "in") -) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{normalized}{Logical scalar, whether the centrality scores are normalized. -Different denominators are used depending on whether the object is one-mode or two-mode, -the type of centrality, and other arguments.} - -\item{cutoff}{The maximum path length to consider when calculating betweenness. -If negative or NULL (the default), there's no limit to the path lengths considered.} - -\item{direction}{Character string, “out” bases the measure on outgoing ties, -“in” on incoming ties, and "all" on either/the sum of the two. -For two-mode networks, "all" uses as numerator the sum of differences -between the maximum centrality score for the mode -against all other centrality scores in the network, -whereas "in" uses as numerator the sum of differences -between the maximum centrality score for the mode -against only the centrality scores of the other nodes in that mode.} -} -\value{ -A numeric vector giving the betweenness centrality measure of each node. -} -\description{ -These functions calculate common betweenness-related centrality measures for one- and two-mode networks: -\itemize{ -\item \code{node_betweenness()} measures the betweenness centralities of nodes in a network. -\item \code{node_induced()} measures the induced betweenness centralities of nodes in a network. -\item \code{node_flow()} measures the flow betweenness centralities of nodes in a network, -which uses an electrical current model for information spreading -in contrast to the shortest paths model used by normal betweenness centrality. -\item \code{tie_betweenness()} measures the number of shortest paths going through a tie. -\item \code{network_betweenness()} measures the betweenness centralization for a network. -} - -All measures attempt to use as much information as they are offered, -including whether the networks are directed, weighted, or multimodal. -If this would produce unintended results, -first transform the salient properties using e.g. \code{\link[=to_undirected]{to_undirected()}} functions. -All centrality and centralization measures return normalized measures by default, -including for two-mode networks. -} -\examples{ -node_betweenness(mpn_elite_mex) -node_betweenness(ison_southern_women) -node_induced(mpn_elite_mex) -(tb <- tie_betweenness(ison_adolescents)) -plot(tb) -#ison_adolescents \%>\% mutate_ties(weight = tb) \%>\% -# autographr() -network_betweenness(ison_southern_women, direction = "in") -} -\references{ -Everett, Martin and Steve Borgatti. 2010. -"Induced, endogenous and exogenous centrality" -\emph{Social Networks}, 32: 339-344. -\doi{10.1016/j.socnet.2010.06.004} -} -\seealso{ -Other centrality: -\code{\link{close_centrality}}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}} - -Other measures: -\code{\link{close_centrality}}, -\code{\link{closure}}, -\code{\link{cohesion}()}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}}, -\code{\link{features}}, -\code{\link{heterogeneity}}, -\code{\link{hierarchy}}, -\code{\link{holes}}, -\code{\link{net_diffusion}}, -\code{\link{node_diffusion}}, -\code{\link{periods}} -} -\concept{centrality} -\concept{measures} diff --git a/man/close_centrality.Rd b/man/close_centrality.Rd deleted file mode 100644 index f943f41f..00000000 --- a/man/close_centrality.Rd +++ /dev/null @@ -1,122 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_centrality.R -\name{close_centrality} -\alias{close_centrality} -\alias{node_closeness} -\alias{node_reach} -\alias{node_harmonic} -\alias{node_information} -\alias{tie_closeness} -\alias{network_closeness} -\alias{network_reach} -\alias{network_harmonic} -\title{Measures of closeness-like centrality and centralisation} -\usage{ -node_closeness(.data, normalized = TRUE, direction = "out", cutoff = NULL) - -node_reach(.data, normalized = TRUE, k = 2) - -node_harmonic(.data, normalized = TRUE, k = -1) - -node_information(.data, normalized = TRUE) - -tie_closeness(.data, normalized = TRUE) - -network_closeness(.data, normalized = TRUE, direction = c("all", "out", "in")) - -network_reach(.data, normalized = TRUE, k = 2) - -network_harmonic(.data, normalized = TRUE, k = 2) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{normalized}{Logical scalar, whether the centrality scores are normalized. -Different denominators are used depending on whether the object is one-mode or two-mode, -the type of centrality, and other arguments.} - -\item{direction}{Character string, “out” bases the measure on outgoing ties, -“in” on incoming ties, and "all" on either/the sum of the two. -For two-mode networks, "all" uses as numerator the sum of differences -between the maximum centrality score for the mode -against all other centrality scores in the network, -whereas "in" uses as numerator the sum of differences -between the maximum centrality score for the mode -against only the centrality scores of the other nodes in that mode.} - -\item{cutoff}{Maximum path length to use during calculations.} - -\item{k}{Integer of steps out to calculate reach} -} -\description{ -These functions calculate common closeness-related centrality measures for one- and two-mode networks: -\itemize{ -\item \code{node_closeness()} measures the closeness centrality of nodes in a network. -\item \code{node_reach()} measures nodes' reach centrality, -or how many nodes they can reach within \emph{k} steps. -\item \code{node_harmonic()} measures nodes' harmonic centrality or valued centrality, -which is thought to behave better than reach centrality for disconnected networks. -\item \code{node_information()} measures nodes' information centrality or -current-flow closeness centrality. -\item \code{tie_closeness()} measures the closeness of each tie to other ties in the network. -\item \code{network_closeness()} measures a network's closeness centralization. -\item \code{network_reach()} measures a network's reach centralization. -\item \code{network_harmonic()} measures a network's harmonic centralization. -} - -All measures attempt to use as much information as they are offered, -including whether the networks are directed, weighted, or multimodal. -If this would produce unintended results, -first transform the salient properties using e.g. \code{\link[=to_undirected]{to_undirected()}} functions. -All centrality and centralization measures return normalized measures by default, -including for two-mode networks. -} -\examples{ -node_closeness(mpn_elite_mex) -node_closeness(ison_southern_women) -node_reach(ison_adolescents) -(ec <- tie_closeness(ison_adolescents)) -plot(ec) -#ison_adolescents \%>\% -# activate(edges) \%>\% mutate(weight = ec) \%>\% -# autographr() -network_closeness(ison_southern_women, direction = "in") -} -\references{ -Marchiori, M, and V Latora. 2000. -"Harmony in the small-world". -\emph{Physica A} 285: 539-546. - -Dekker, Anthony. 2005. -"Conceptual distance in social network analysis". -\emph{Journal of Social Structure} 6(3). -} -\seealso{ -Other centrality: -\code{\link{between_centrality}}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}} - -Other measures: -\code{\link{between_centrality}}, -\code{\link{closure}}, -\code{\link{cohesion}()}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}}, -\code{\link{features}}, -\code{\link{heterogeneity}}, -\code{\link{hierarchy}}, -\code{\link{holes}}, -\code{\link{net_diffusion}}, -\code{\link{node_diffusion}}, -\code{\link{periods}} -} -\concept{centrality} -\concept{measures} diff --git a/man/degree_centrality.Rd b/man/degree_centrality.Rd deleted file mode 100644 index 043ea40d..00000000 --- a/man/degree_centrality.Rd +++ /dev/null @@ -1,176 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_centrality.R -\name{degree_centrality} -\alias{degree_centrality} -\alias{node_degree} -\alias{node_deg} -\alias{node_outdegree} -\alias{node_indegree} -\alias{node_multidegree} -\alias{node_posneg} -\alias{tie_degree} -\alias{network_degree} -\alias{network_outdegree} -\alias{network_indegree} -\title{Measures of degree-like centrality and centralisation} -\usage{ -node_degree( - .data, - normalized = TRUE, - alpha = 1, - direction = c("all", "out", "in") -) - -node_deg(.data, alpha = 0, direction = c("all", "out", "in")) - -node_outdegree(.data, normalized = TRUE, alpha = 0) - -node_indegree(.data, normalized = TRUE, alpha = 0) - -node_multidegree(.data, tie1, tie2) - -node_posneg(.data) - -tie_degree(.data, normalized = TRUE) - -network_degree(.data, normalized = TRUE, direction = c("all", "out", "in")) - -network_outdegree(.data, normalized = TRUE) - -network_indegree(.data, normalized = TRUE) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{normalized}{Logical scalar, whether the centrality scores are normalized. -Different denominators are used depending on whether the object is one-mode or two-mode, -the type of centrality, and other arguments.} - -\item{alpha}{Numeric scalar, the positive tuning parameter introduced in -Opsahl et al (2010) for trading off between degree and strength centrality measures. -By default, \code{alpha = 0}, which ignores tie weights and the measure is solely based -upon degree (the number of ties). -\code{alpha = 1} ignores the number of ties and provides the sum of the tie weights -as strength centrality. -Values between 0 and 1 reflect different trade-offs in the relative contributions of -degree and strength to the final outcome, with 0.5 as the middle ground. -Values above 1 penalise for the number of ties. -Of two nodes with the same sum of tie weights, the node with fewer ties will obtain -the higher score. -This argument is ignored except in the case of a weighted network.} - -\item{direction}{Character string, “out” bases the measure on outgoing ties, -“in” on incoming ties, and "all" on either/the sum of the two. -For two-mode networks, "all" uses as numerator the sum of differences -between the maximum centrality score for the mode -against all other centrality scores in the network, -whereas "in" uses as numerator the sum of differences -between the maximum centrality score for the mode -against only the centrality scores of the other nodes in that mode.} - -\item{tie1}{Character string indicating the first uniplex network.} - -\item{tie2}{Character string indicating the second uniplex network.} -} -\value{ -A single centralization score if the object was one-mode, -and two centralization scores if the object was two-mode. - -Depending on how and what kind of an object is passed to the function, -the function will return a \code{tidygraph} object where the nodes have been updated -} -\description{ -These functions calculate common degree-related centrality measures for one- and two-mode networks: -\itemize{ -\item \code{node_degree()} measures the degree centrality of nodes in an unweighted network, -or weighted degree/strength of nodes in a weighted network; -there are several related shortcut functions: -\itemize{ -\item \code{node_deg()} returns the unnormalised results. -\item \code{node_indegree()} returns the \code{direction = 'in'} results. -\item \code{node_outdegree()} returns the \code{direction = 'out'} results. -} -\item \code{node_multidegree()} measures the ratio between types of ties in a multiplex network. -\item \code{node_posneg()} measures the PN (positive-negative) centrality of a signed network. -\item \code{tie_degree()} measures the degree centrality of ties in a network -\item \code{network_degree()} measures a network's degree centralization; -there are several related shortcut functions: -\itemize{ -\item \code{network_indegree()} returns the \code{direction = 'out'} results. -\item \code{network_outdegree()} returns the \code{direction = 'out'} results. -} -} - -All measures attempt to use as much information as they are offered, -including whether the networks are directed, weighted, or multimodal. -If this would produce unintended results, -first transform the salient properties using e.g. \code{\link[=to_undirected]{to_undirected()}} functions. -All centrality and centralization measures return normalized measures by default, -including for two-mode networks. -} -\examples{ -node_degree(mpn_elite_mex) -node_degree(ison_southern_women) -tie_degree(ison_adolescents) -network_degree(ison_southern_women, direction = "in") -} -\references{ -Faust, Katherine. 1997. -"Centrality in affiliation networks." -\emph{Social Networks} 19(2): 157-191. -\doi{10.1016/S0378-8733(96)00300-0}. - -Borgatti, Stephen P., and Martin G. Everett. 1997. -"Network analysis of 2-mode data." -\emph{Social Networks} 19(3): 243-270. -\doi{10.1016/S0378-8733(96)00301-2}. - -Borgatti, Stephen P., and Daniel S. Halgin. 2011. -"Analyzing affiliation networks." -In \emph{The SAGE Handbook of Social Network Analysis}, -edited by John Scott and Peter J. Carrington, 417–33. -London, UK: Sage. -\doi{10.4135/9781446294413.n28}. - -Opsahl, Tore, Filip Agneessens, and John Skvoretz. 2010. -"Node centrality in weighted networks: Generalizing degree and shortest paths." -\emph{Social Networks} 32, 245-251. -\doi{10.1016/j.socnet.2010.03.006} - -Everett, Martin G., and Stephen P. Borgatti. 2014. -“Networks Containing Negative Ties.” -\emph{Social Networks} 38:111–20. -\doi{10.1016/j.socnet.2014.03.005}. -} -\seealso{ -\code{\link[=to_undirected]{to_undirected()}} for removing edge directions -and \code{\link[=to_unweighted]{to_unweighted()}} for removing weights from a graph. - -Other centrality: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{eigenv_centrality}} - -Other measures: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{closure}}, -\code{\link{cohesion}()}, -\code{\link{eigenv_centrality}}, -\code{\link{features}}, -\code{\link{heterogeneity}}, -\code{\link{hierarchy}}, -\code{\link{holes}}, -\code{\link{net_diffusion}}, -\code{\link{node_diffusion}}, -\code{\link{periods}} -} -\concept{centrality} -\concept{measures} diff --git a/man/eigenv_centrality.Rd b/man/eigenv_centrality.Rd deleted file mode 100644 index 3716e10c..00000000 --- a/man/eigenv_centrality.Rd +++ /dev/null @@ -1,166 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_centrality.R -\name{eigenv_centrality} -\alias{eigenv_centrality} -\alias{node_eigenvector} -\alias{node_power} -\alias{node_alpha} -\alias{node_pagerank} -\alias{tie_eigenvector} -\alias{network_eigenvector} -\title{Measures of eigenvector-like centrality and centralisation} -\usage{ -node_eigenvector(.data, normalized = TRUE, scale = FALSE) - -node_power(.data, normalized = TRUE, scale = FALSE, exponent = 1) - -node_alpha(.data, alpha = 0.85) - -node_pagerank(.data) - -tie_eigenvector(.data, normalized = TRUE) - -network_eigenvector(.data, normalized = TRUE) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{normalized}{Logical scalar, whether the centrality scores are normalized. -Different denominators are used depending on whether the object is one-mode or two-mode, -the type of centrality, and other arguments.} - -\item{scale}{Logical scalar, whether to rescale the vector so the maximum score is 1.} - -\item{exponent}{Decay rate for the Bonacich power centrality score.} - -\item{alpha}{A constant that trades off the importance of external influence against the importance of connection. -When \eqn{\alpha = 0}, only the external influence matters. -As \eqn{\alpha} gets larger, only the connectivity matters and we reduce to eigenvector centrality. -By default \eqn{\alpha = 0.85}.} -} -\value{ -A numeric vector giving the eigenvector centrality measure of each node. - -A numeric vector giving each node's power centrality measure. -} -\description{ -These functions calculate common eigenvector-related centrality measures for one- and two-mode networks: -\itemize{ -\item \code{node_eigenvector()} measures the eigenvector centrality of nodes in a network. -\item \code{node_power()} measures the Bonacich, beta, or power centrality of nodes in a network. -\item \code{node_alpha()} measures the alpha or Katz centrality of nodes in a network. -\item \code{node_pagerank()} measures the pagerank centrality of nodes in a network. -\item \code{tie_eigenvector()} measures the eigenvector centrality of ties in a network. -\item \code{network_eigenvector()} measures the eigenvector centralization for a network. -} - -All measures attempt to use as much information as they are offered, -including whether the networks are directed, weighted, or multimodal. -If this would produce unintended results, -first transform the salient properties using e.g. \code{\link[=to_undirected]{to_undirected()}} functions. -All centrality and centralization measures return normalized measures by default, -including for two-mode networks. -} -\details{ -We use \code{{igraph}} routines behind the scenes here for consistency and because they are often faster. -For example, \code{igraph::eigencentrality()} is approximately 25\% faster than \code{sna::evcent()}. -} -\section{Eigenvector centrality}{ - -Eigenvector centrality operates as a measure of a node's influence in a network. -The idea is that being connected to well-connected others results in a higher score. -Each node's eigenvector centrality can be defined as: -\deqn{x_i = \frac{1}{\lambda} \sum_{j \in N} a_{i,j} x_j} -where \eqn{a_{i,j} = 1} if \eqn{i} is linked to \eqn{j} and 0 otherwise, -and \eqn{\lambda} is a constant representing the principal eigenvalue. -Rather than performing this iteration, -most routines solve the eigenvector equation \eqn{Ax = \lambda x}. -} - -\section{Power centrality}{ - -Power or beta (or Bonacich) centrality -} - -\section{Alpha centrality}{ - -Alpha or Katz (or Katz-Bonacich) centrality operates better than eigenvector centrality -for directed networks. -Eigenvector centrality will return 0s for all nodes not in the main strongly-connected component. -Each node's alpha centrality can be defined as: -\deqn{x_i = \frac{1}{\lambda} \sum_{j \in N} a_{i,j} x_j + e_i} -where \eqn{a_{i,j} = 1} if \eqn{i} is linked to \eqn{j} and 0 otherwise, -\eqn{\lambda} is a constant representing the principal eigenvalue, -and \eqn{e_i} is some external influence used to ensure that even nodes beyond the main -strongly connected component begin with some basic influence. -Note that many equations replace \eqn{\frac{1}{\lambda}} with \eqn{\alpha}, -hence the name. - -For example, if \eqn{\alpha = 0.5}, then each direct connection (or alter) would be worth \eqn{(0.5)^1 = 0.5}, -each secondary connection (or tertius) would be worth \eqn{(0.5)^2 = 0.25}, -each tertiary connection would be worth \eqn{(0.5)^3 = 0.125}, and so on. - -Rather than performing this iteration though, -most routines solve the equation \eqn{x = (I - \frac{1}{\lambda} A^T)^{-1} e}. -} - -\examples{ -node_eigenvector(mpn_elite_mex) -node_eigenvector(ison_southern_women) -node_power(ison_southern_women, exponent = 0.5) -tie_eigenvector(ison_adolescents) -network_eigenvector(mpn_elite_mex) -network_eigenvector(ison_southern_women) -} -\references{ -Bonacich, Phillip. 1991. -“Simultaneous Group and Individual Centralities.” -\emph{Social Networks} 13(2):155–68. -\doi{10.1016/0378-8733(91)90018-O}. - -Bonacich, Phillip. 1987. -“Power and Centrality: A Family of Measures.” -\emph{The American Journal of Sociology}, 92(5): 1170–82. -\doi{10.1086/228631}. - -Katz, Leo 1953. -"A new status index derived from sociometric analysis". -\emph{Psychometrika}. 18(1): 39–43. - -Bonacich, P. and Lloyd, P. 2001. -“Eigenvector-like measures of centrality for asymmetric relations” -\emph{Social Networks}. 23(3):191-201. - -Brin, Sergey and Page, Larry. 1998. -"The anatomy of a large-scale hypertextual web search engine". -\emph{Proceedings of the 7th World-Wide Web Conference}. Brisbane, Australia. -} -\seealso{ -Other centrality: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{degree_centrality}} - -Other measures: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{closure}}, -\code{\link{cohesion}()}, -\code{\link{degree_centrality}}, -\code{\link{features}}, -\code{\link{heterogeneity}}, -\code{\link{hierarchy}}, -\code{\link{holes}}, -\code{\link{net_diffusion}}, -\code{\link{node_diffusion}}, -\code{\link{periods}} -} -\concept{centrality} -\concept{measures} From bef956a29f5d861f3f294ad400ac4c92b553bcdc Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:17:13 +0200 Subject: [PATCH 53/97] Migrated node_roulette() to manynet --- R/member_cliques.R | 129 --------------------------------------------- man/cliques.Rd | 85 ----------------------------- 2 files changed, 214 deletions(-) delete mode 100644 R/member_cliques.R delete mode 100644 man/cliques.Rd diff --git a/R/member_cliques.R b/R/member_cliques.R deleted file mode 100644 index dd9391f8..00000000 --- a/R/member_cliques.R +++ /dev/null @@ -1,129 +0,0 @@ -#' Clique partitioning algorithms -#' -#' @description -#' These functions create a vector of nodes' memberships in -#' cliques: -#' -#' - `node_in_roulette()` assigns nodes to maximally diverse groups. -#' -#' @section Maximally diverse grouping problem: -#' This well known computational problem is a NP-hard problem -#' with a number of relevant applications, -#' including the formation of groups of students that have encountered -#' each other least or least recently. -#' Essentially, the aim is to return a membership of nodes in cliques -#' that minimises the sum of their previous (weighted) ties: -#' -#' \deqn{\sum_{g=1}^{m} \sum_{i=1}^{n-1} \sum_{j=i+1}^{n} x_{ij} y_{ig} y_{jg}} -#' -#' where \eqn{y_{ig} = 1} if node \eqn{i} is in group \eqn{g}, and 0 otherwise. -#' -#' \eqn{x_{ij}} is the existing network data. -#' If this is an empty network, the function will just return cliques. -#' To run this repeatedly, one can join a clique network of the membership result -#' with the original network, using this as the network data for the next round. -#' -#' A form of the Lai and Hao (2016) iterated maxima search (IMS) is used here. -#' This performs well for small and moderately sized networks. -#' It includes both weak and strong perturbations to an initial solution -#' to ensure that a robust solution from the broader state space is identified. -#' The user is referred to Lai and Hao (2016) and Lai et al (2021) for more details. -#' @inheritParams cohesion -#' @name cliques -#' @family memberships -NULL - -#' @rdname cliques -#' @param num_groups An integer indicating the number of groups desired. -#' @param group_size An integer indicating the desired size of most of the groups. -#' Note that if the number of nodes is not divisible into groups of equal size, -#' there may be some larger or smaller groups. -#' @param times An integer of the number of search iterations the algorithm should complete. -#' By default this is the number of nodes in the network multiplied by the number of groups. -#' This heuristic may be insufficient for small networks and numbers of groups, -#' and burdensome for large networks and numbers of groups, but can be overwritten. -#' At every 10th iteration, a stronger perturbation of a number of successive changes, -#' approximately the number of nodes divided by the number of groups, -#' will take place irrespective of whether it improves the objective function. -#' @references -#' Lai, Xiangjing, and Jin-Kao Hao. 2016. -#' “Iterated Maxima Search for the Maximally Diverse Grouping Problem.” -#' _European Journal of Operational Research_ 254(3):780–800. -#' \doi{10.1016/j.ejor.2016.05.018}. -#' -#' Lai, Xiangjing, Jin-Kao Hao, Zhang-Hua Fu, and Dong Yue. 2021. -#' “Neighborhood Decomposition Based Variable Neighborhood Search and Tabu Search for Maximally Diverse Grouping.” -#' _European Journal of Operational Research_ 289(3):1067–86. -#' \doi{10.1016/j.ejor.2020.07.048}. -#' @export -node_in_roulette <- function(.data, num_groups, group_size, times = NULL){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(missing(num_groups) & missing(group_size)){ - stop(paste("Either `num_groups` must indicate number of groups desired", - "or `group_size` must indicate the desired average size of groups.")) - } - n <- manynet::network_nodes(.data) - my_vec <- sample(seq.int(n)) - # Initial partition - if(!missing(num_groups)){ - out <- cut(seq_along(my_vec), num_groups, labels = FALSE)[my_vec] - } else { - out <- ceiling(seq_along(my_vec) / group_size)[my_vec] - } - if(is.null(times)) times <- n * max(out) - # Get fitness - mat <- manynet::as_matrix(.data) - fit <- sum(.to_cliques(out) * mat) - soln <- out - for(t in seq.int(times)){ - soln <- .weakPerturb(soln) - new_fit <- sum(.to_cliques(soln) * mat) - if(new_fit < fit){ - out <- soln - fit <- new_fit - } - if(t %% 10) soln <- .strongPerturb(soln) - } - make_node_member(out, .data) -} - -.to_cliques <- function(member){ - (member == t(matrix(member, length(member), length(member))))*1 -} - -.weakPerturb <- function(soln){ - gsizes <- table(soln) - evens <- all(gsizes == max(gsizes)) - if(evens){ - soln <- .swapMove(soln) - } else { - if(stats::runif(1)<0.5) soln <- .swapMove(soln) else - soln <- .oneMove(soln) - } - soln -} - -.swapMove <- function(soln){ - from <- sample(seq.int(length(soln)), 1) - to <- sample(which(soln != soln[from]), 1) - soln[c(to,from)] <- soln[c(from,to)] - soln -} - -.oneMove <- function(soln){ - gsizes <- table(soln) - maxg <- which(gsizes == max(gsizes)) - from <- sample(which(soln %in% maxg), 1) - soln[from] <- sample(which(gsizes != max(gsizes)), 1) - soln -} - -.strongPerturb <- function(soln, strength = 1){ - times <- ceiling(strength * length(soln)/max(soln)) - for (t in seq.int(times)){ - soln <- .weakPerturb(soln) - } - soln -} - - diff --git a/man/cliques.Rd b/man/cliques.Rd deleted file mode 100644 index dd73a204..00000000 --- a/man/cliques.Rd +++ /dev/null @@ -1,85 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/member_cliques.R -\name{cliques} -\alias{cliques} -\alias{node_in_roulette} -\title{Clique partitioning algorithms} -\usage{ -node_in_roulette(.data, num_groups, group_size, times = NULL) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{num_groups}{An integer indicating the number of groups desired.} - -\item{group_size}{An integer indicating the desired size of most of the groups. -Note that if the number of nodes is not divisible into groups of equal size, -there may be some larger or smaller groups.} - -\item{times}{An integer of the number of search iterations the algorithm should complete. -By default this is the number of nodes in the network multiplied by the number of groups. -This heuristic may be insufficient for small networks and numbers of groups, -and burdensome for large networks and numbers of groups, but can be overwritten. -At every 10th iteration, a stronger perturbation of a number of successive changes, -approximately the number of nodes divided by the number of groups, -will take place irrespective of whether it improves the objective function.} -} -\description{ -These functions create a vector of nodes' memberships in -cliques: -\itemize{ -\item \code{node_in_roulette()} assigns nodes to maximally diverse groups. -} -} -\section{Maximally diverse grouping problem}{ - -This well known computational problem is a NP-hard problem -with a number of relevant applications, -including the formation of groups of students that have encountered -each other least or least recently. -Essentially, the aim is to return a membership of nodes in cliques -that minimises the sum of their previous (weighted) ties: - -\deqn{\sum_{g=1}^{m} \sum_{i=1}^{n-1} \sum_{j=i+1}^{n} x_{ij} y_{ig} y_{jg}} - -where \eqn{y_{ig} = 1} if node \eqn{i} is in group \eqn{g}, and 0 otherwise. - -\eqn{x_{ij}} is the existing network data. -If this is an empty network, the function will just return cliques. -To run this repeatedly, one can join a clique network of the membership result -with the original network, using this as the network data for the next round. - -A form of the Lai and Hao (2016) iterated maxima search (IMS) is used here. -This performs well for small and moderately sized networks. -It includes both weak and strong perturbations to an initial solution -to ensure that a robust solution from the broader state space is identified. -The user is referred to Lai and Hao (2016) and Lai et al (2021) for more details. -} - -\references{ -Lai, Xiangjing, and Jin-Kao Hao. 2016. -“Iterated Maxima Search for the Maximally Diverse Grouping Problem.” -\emph{European Journal of Operational Research} 254(3):780–800. -\doi{10.1016/j.ejor.2016.05.018}. - -Lai, Xiangjing, Jin-Kao Hao, Zhang-Hua Fu, and Dong Yue. 2021. -“Neighborhood Decomposition Based Variable Neighborhood Search and Tabu Search for Maximally Diverse Grouping.” -\emph{European Journal of Operational Research} 289(3):1067–86. -\doi{10.1016/j.ejor.2020.07.048}. -} -\seealso{ -Other memberships: -\code{\link{community}}, -\code{\link{components}()}, -\code{\link{core}}, -\code{\link{equivalence}}, -\code{\link{hierarchical_community}} -} -\concept{memberships} From dc84ea50a148acaed252e8ab6405227f34397a20 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:17:26 +0200 Subject: [PATCH 54/97] Migrated closure measures to manynet --- R/measure_closure.R | 140 -------------------------------------------- man/closure.Rd | 104 -------------------------------- 2 files changed, 244 deletions(-) delete mode 100644 R/measure_closure.R delete mode 100644 man/closure.Rd diff --git a/R/measure_closure.R b/R/measure_closure.R deleted file mode 100644 index 42582b9e..00000000 --- a/R/measure_closure.R +++ /dev/null @@ -1,140 +0,0 @@ -#' Measures of network closure -#' -#' @description -#' These functions offer methods for summarising the closure in configurations -#' in one-, two-, and three-mode networks: -#' -#' - `network_reciprocity()` measures reciprocity in a (usually directed) network. -#' - `node_reciprocity()` measures nodes' reciprocity. -#' - `network_transitivity()` measures transitivity in a network. -#' - `node_transitivity()` measures nodes' transitivity. -#' - `network_equivalency()` measures equivalence or reinforcement -#' in a (usually two-mode) network. -#' - `network_congruency()` measures congruency across two two-mode networks. -#' -#' @details -#' For one-mode networks, shallow wrappers of igraph versions exist via -#' `network_reciprocity` and `network_transitivity`. -#' -#' For two-mode networks, `network_equivalency` calculates the proportion of three-paths in the network -#' that are closed by fourth tie to establish a "shared four-cycle" structure. -#' -#' For three-mode networks, `network_congruency` calculates the proportion of three-paths -#' spanning two two-mode networks that are closed by a fourth tie to establish a -#' "congruent four-cycle" structure. -#' @inheritParams cohesion -#' @param object2 Optionally, a second (two-mode) matrix, igraph, or tidygraph -#' @param method For reciprocity, either `default` or `ratio`. -#' See `?igraph::reciprocity` -#' @name closure -#' @family measures -#' @references -#' Robins, Garry L, and Malcolm Alexander. 2004. -#' Small worlds among interlocking directors: Network structure and distance in bipartite graphs. -#' \emph{Computational & Mathematical Organization Theory} 10(1): 69–94. -#' \doi{10.1023/B:CMOT.0000032580.12184.c0}. -#' -#' Knoke, David, Mario Diani, James Hollway, and Dimitris C Christopoulos. 2021. -#' \emph{Multimodal Political Networks}. -#' Cambridge University Press. Cambridge University Press. -#' \doi{10.1017/9781108985000} -NULL - -#' @rdname closure -#' @importFrom igraph reciprocity -#' @examples -#' network_reciprocity(ison_southern_women) -#' @export -network_reciprocity <- function(.data, method = "default") { - if(missing(.data)) {expect_nodes(); .data <- .G()} - make_network_measure(igraph::reciprocity(manynet::as_igraph(.data), mode = method), - .data) -} - -#' @rdname closure -#' @examples -#' node_reciprocity(to_unweighted(ison_networkers)) -#' @export -node_reciprocity <- function(.data) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- manynet::as_matrix(.data) - make_node_measure(rowSums(out * t(out))/rowSums(out), - .data) -} - -#' @rdname closure -#' @importFrom igraph transitivity -#' @examples -#' network_transitivity(ison_adolescents) -#' @export -network_transitivity <- function(.data) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - make_network_measure(igraph::transitivity(manynet::as_igraph(.data)), - .data) -} - -#' @rdname closure -#' @examples -#' node_transitivity(ison_adolescents) -#' @export -node_transitivity <- function(.data) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - make_node_measure(igraph::transitivity(manynet::as_igraph(.data), - type = "local"), - .data) -} - -#' @rdname closure -#' @section Equivalency: -#' The `network_equivalency()` function calculates the Robins and Alexander (2004) -#' clustering coefficient for two-mode networks. -#' Note that for weighted two-mode networks, the result is divided by the average tie weight. -#' @examples -#' network_equivalency(ison_southern_women) -#' @export -network_equivalency <- function(.data) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - if (manynet::is_twomode(.data)) { - mat <- manynet::as_matrix(.data) - c <- ncol(mat) - indegrees <- colSums(mat) - twopaths <- crossprod(mat) - diag(twopaths) <- 0 - output <- sum(twopaths * (twopaths - 1)) / - (sum(twopaths * (twopaths - 1)) + - sum(twopaths * - (matrix(indegrees, c, c) - twopaths))) - if (is.nan(output)) output <- 1 - if(manynet::is_weighted(.data)) output <- output / mean(mat[mat>0]) - } else stop("This function expects a two-mode network") - make_network_measure(output, .data) -} - -#' @rdname closure -#' @export -network_congruency <- function(.data, object2){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(missing(.data) | missing(object2)) stop("This function expects two two-mode networks") - if(!manynet::is_twomode(.data) | !manynet::is_twomode(object2)) stop("This function expects two two-mode networks") - if(manynet::network_dims(.data)[2] != manynet::network_dims(object2)[1]) - stop(paste("This function expects the number of nodes", - "in the second mode of the first network", "to be the same as the number of nodes", - "in the first mode of the second network.")) - mat1 <- manynet::as_matrix(.data) - mat2 <- manynet::as_matrix(object2) - connects <- ncol(mat1) - twopaths1 <- crossprod(mat1) - indegrees <- diag(twopaths1) - diag(twopaths1) <- 0 - twopaths2 <- tcrossprod(mat2) - outdegrees <- diag(twopaths2) - diag(twopaths2) <- 0 - twopaths <- twopaths1 + twopaths2 - degrees <- indegrees + outdegrees - output <- sum(twopaths * (twopaths - 1)) / - (sum(twopaths * (twopaths - 1)) + - sum(twopaths * - (matrix(degrees, connects, connects) - twopaths))) - if (is.nan(output)) output <- 1 - make_network_measure(output, .data) -} diff --git a/man/closure.Rd b/man/closure.Rd deleted file mode 100644 index 18502e58..00000000 --- a/man/closure.Rd +++ /dev/null @@ -1,104 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_closure.R -\name{closure} -\alias{closure} -\alias{network_reciprocity} -\alias{node_reciprocity} -\alias{network_transitivity} -\alias{node_transitivity} -\alias{network_equivalency} -\alias{network_congruency} -\title{Measures of network closure} -\usage{ -network_reciprocity(.data, method = "default") - -node_reciprocity(.data) - -network_transitivity(.data) - -node_transitivity(.data) - -network_equivalency(.data) - -network_congruency(.data, object2) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{method}{For reciprocity, either \code{default} or \code{ratio}. -See \code{?igraph::reciprocity}} - -\item{object2}{Optionally, a second (two-mode) matrix, igraph, or tidygraph} -} -\description{ -These functions offer methods for summarising the closure in configurations -in one-, two-, and three-mode networks: -\itemize{ -\item \code{network_reciprocity()} measures reciprocity in a (usually directed) network. -\item \code{node_reciprocity()} measures nodes' reciprocity. -\item \code{network_transitivity()} measures transitivity in a network. -\item \code{node_transitivity()} measures nodes' transitivity. -\item \code{network_equivalency()} measures equivalence or reinforcement -in a (usually two-mode) network. -\item \code{network_congruency()} measures congruency across two two-mode networks. -} -} -\details{ -For one-mode networks, shallow wrappers of igraph versions exist via -\code{network_reciprocity} and \code{network_transitivity}. - -For two-mode networks, \code{network_equivalency} calculates the proportion of three-paths in the network -that are closed by fourth tie to establish a "shared four-cycle" structure. - -For three-mode networks, \code{network_congruency} calculates the proportion of three-paths -spanning two two-mode networks that are closed by a fourth tie to establish a -"congruent four-cycle" structure. -} -\section{Equivalency}{ - -The \code{network_equivalency()} function calculates the Robins and Alexander (2004) -clustering coefficient for two-mode networks. -Note that for weighted two-mode networks, the result is divided by the average tie weight. -} - -\examples{ -network_reciprocity(ison_southern_women) -node_reciprocity(to_unweighted(ison_networkers)) -network_transitivity(ison_adolescents) -node_transitivity(ison_adolescents) -network_equivalency(ison_southern_women) -} -\references{ -Robins, Garry L, and Malcolm Alexander. 2004. -Small worlds among interlocking directors: Network structure and distance in bipartite graphs. -\emph{Computational & Mathematical Organization Theory} 10(1): 69–94. -\doi{10.1023/B:CMOT.0000032580.12184.c0}. - -Knoke, David, Mario Diani, James Hollway, and Dimitris C Christopoulos. 2021. -\emph{Multimodal Political Networks}. -Cambridge University Press. Cambridge University Press. -\doi{10.1017/9781108985000} -} -\seealso{ -Other measures: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{cohesion}()}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}}, -\code{\link{features}}, -\code{\link{heterogeneity}}, -\code{\link{hierarchy}}, -\code{\link{holes}}, -\code{\link{net_diffusion}}, -\code{\link{node_diffusion}}, -\code{\link{periods}} -} -\concept{measures} From d06531b39b9355938576fc9c0ca054b8a6190c3a Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:17:40 +0200 Subject: [PATCH 55/97] Migrated components to manynet --- R/member_components.R | 68 ------------------------------------------- man/components.Rd | 66 ----------------------------------------- 2 files changed, 134 deletions(-) delete mode 100644 R/member_components.R delete mode 100644 man/components.Rd diff --git a/R/member_components.R b/R/member_components.R deleted file mode 100644 index f6efce9f..00000000 --- a/R/member_components.R +++ /dev/null @@ -1,68 +0,0 @@ -#' Component partitioning algorithms -#' -#' @description -#' These functions create a vector of nodes' memberships in -#' components or degrees of coreness: -#' -#' - `node_in_component()` assigns nodes' component membership -#' using edge direction where available. -#' - `node_in_weak()` assigns nodes' component membership -#' ignoring edge direction. -#' - `node_in_strong()` assigns nodes' component membership -#' based on edge direction. -#' -#' In graph theory, components, sometimes called connected components, -#' are induced subgraphs from partitioning the nodes into disjoint sets. -#' All nodes that are members of the same partition as _i_ are reachable -#' from _i_. -#' -#' For directed networks, -#' strongly connected components consist of subgraphs where there are paths -#' in each direction between member nodes. -#' Weakly connected components consist of subgraphs where there is a path -#' in either direction between member nodes. -#' -#' Coreness captures the maximal subgraphs in which each vertex has at least -#' degree _k_, where _k_ is also the order of the subgraph. -#' As described in `igraph::coreness`, -#' a node's coreness is _k_ if it belongs to the _k_-core -#' but not to the (_k_+1)-core. -#' @inheritParams cohesion -#' @name components -#' @family memberships -NULL - -#' @rdname components -#' @importFrom igraph components -#' @examples -#' node_in_component(mpn_bristol) -#' @export -node_in_component <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) - make_node_member(igraph::components(.data, mode = "strong")$membership, - .data) -} - -#' @rdname components -#' @importFrom igraph components -#' @export -node_in_weak <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) - make_node_member(igraph::components(.data, mode = "weak")$membership, - .data) -} - -#' @rdname components -#' @importFrom igraph components -#' @export -node_in_strong <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) - make_node_member(igraph::components(.data, mode = "strong")$membership, - .data) -} - - - diff --git a/man/components.Rd b/man/components.Rd deleted file mode 100644 index cb4687c4..00000000 --- a/man/components.Rd +++ /dev/null @@ -1,66 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/member_components.R -\name{components} -\alias{components} -\alias{node_in_component} -\alias{node_in_weak} -\alias{node_in_strong} -\title{Component partitioning algorithms} -\usage{ -node_in_component(.data) - -node_in_weak(.data) - -node_in_strong(.data) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} -} -\description{ -These functions create a vector of nodes' memberships in -components or degrees of coreness: -\itemize{ -\item \code{node_in_component()} assigns nodes' component membership -using edge direction where available. -\item \code{node_in_weak()} assigns nodes' component membership -ignoring edge direction. -\item \code{node_in_strong()} assigns nodes' component membership -based on edge direction. -} - -In graph theory, components, sometimes called connected components, -are induced subgraphs from partitioning the nodes into disjoint sets. -All nodes that are members of the same partition as \emph{i} are reachable -from \emph{i}. - -For directed networks, -strongly connected components consist of subgraphs where there are paths -in each direction between member nodes. -Weakly connected components consist of subgraphs where there is a path -in either direction between member nodes. - -Coreness captures the maximal subgraphs in which each vertex has at least -degree \emph{k}, where \emph{k} is also the order of the subgraph. -As described in \code{igraph::coreness}, -a node's coreness is \emph{k} if it belongs to the \emph{k}-core -but not to the (\emph{k}+1)-core. -} -\examples{ -node_in_component(mpn_bristol) -} -\seealso{ -Other memberships: -\code{\link{cliques}}, -\code{\link{community}}, -\code{\link{core}}, -\code{\link{equivalence}}, -\code{\link{hierarchical_community}} -} -\concept{memberships} From 04edafc82fa023bef28a1d9600f75c3276f26689 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:18:07 +0200 Subject: [PATCH 56/97] Migrated equivalence memberships to manynet --- R/member_equivalence.R | 143 ----------------------------------- R/migraph-defunct.R | 168 ++--------------------------------------- man/cluster.Rd | 68 ----------------- man/equivalence.Rd | 130 ------------------------------- man/kselect.Rd | 58 -------------- 5 files changed, 8 insertions(+), 559 deletions(-) delete mode 100644 R/member_equivalence.R delete mode 100644 man/cluster.Rd delete mode 100644 man/equivalence.Rd delete mode 100644 man/kselect.Rd diff --git a/R/member_equivalence.R b/R/member_equivalence.R deleted file mode 100644 index 1a8420d2..00000000 --- a/R/member_equivalence.R +++ /dev/null @@ -1,143 +0,0 @@ -#' Equivalence clustering algorithms -#' -#' @description -#' These functions combine an appropriate `_census()` function -#' together with methods for calculating the hierarchical clusters -#' provided by a certain distance calculation. -#' -#' - `node_in_equivalence()` assigns nodes membership based on their equivalence -#' with respective to some census/class. -#' The following functions call this function, together with an appropriate census. -#' - `node_in_structural()` assigns nodes membership based on their -#' having equivalent ties to the same other nodes. -#' - `node_in_regular()` assigns nodes membership based on their -#' having equivalent patterns of ties. -#' - `node_in_automorphic()` assigns nodes membership based on their -#' having equivalent distances to other nodes. -#' -#' A `plot()` method exists for investigating the dendrogram -#' of the hierarchical cluster and showing the returned cluster -#' assignment. -#' @name equivalence -#' @family memberships -#' @inheritParams cohesion -#' @param census A matrix returned by a `node_*_census()` function. -#' @param k Typically a character string indicating which method -#' should be used to select the number of clusters to return. -#' By default `"silhouette"`, other options include `"elbow"` and `"strict"`. -#' `"strict"` returns classes with members only when strictly equivalent. -#' `"silhouette"` and `"elbow"` select classes based on the distance between -#' clusters or between nodes within a cluster. -#' Fewer, identifiable letters, e.g. `"e"` for elbow, is sufficient. -#' Alternatively, if `k` is passed an integer, e.g. `k = 3`, -#' then all selection routines are skipped in favour of this number of clusters. -#' @param cluster Character string indicating whether clusters should be -#' clustered hierarchically (`"hierarchical"`) or -#' through convergence of correlations (`"concor"`). -#' Fewer, identifiable letters, e.g. `"c"` for CONCOR, is sufficient. -#' @param distance Character string indicating which distance metric -#' to pass on to `stats::dist`. -#' By default `"euclidean"`, but other options include -#' `"maximum"`, `"manhattan"`, `"canberra"`, `"binary"`, and `"minkowski"`. -#' Fewer, identifiable letters, e.g. `"e"` for Euclidean, is sufficient. -#' @param range Integer indicating the maximum number of (k) clusters -#' to evaluate. -#' Ignored when `k = "strict"` or a discrete number is given for `k`. -#' @importFrom stats as.dist hclust cutree coef cor median -#' @importFrom sna gcor -#' @source \url{https://github.com/aslez/concoR} -NULL - -#' @rdname equivalence -#' @export -node_in_equivalence <- function(.data, census, - k = c("silhouette", "elbow", "strict"), - cluster = c("hierarchical", "concor"), - distance = c("euclidean", "maximum", "manhattan", - "canberra", "binary", "minkowski"), - range = 8L){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - hc <- switch(match.arg(cluster), - hierarchical = cluster_hierarchical(`if`(manynet::is_twomode(.data), - manynet::to_onemode(census), census), - match.arg(distance)), - concor = cluster_concor(.data, census)) - - if(!is.numeric(k)) - k <- switch(match.arg(k), - strict = k_strict(hc, .data), - elbow = k_elbow(hc, .data, census, range), - silhouette = k_silhouette(hc, .data, range)) - - out <- make_node_member(stats::cutree(hc, k), .data) - attr(out, "hc") <- hc - attr(out, "k") <- k - out -} - -#' @rdname equivalence -#' @examples -#' \donttest{ -#' (nse <- node_in_structural(mpn_elite_usa_advice)) -#' plot(nse) -#' } -#' @export -node_in_structural <- function(.data, - k = c("silhouette", "elbow", "strict"), - cluster = c("hierarchical", "concor"), - distance = c("euclidean", "maximum", "manhattan", - "canberra", "binary", "minkowski"), - range = 8L){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - mat <- node_tie_census(.data) - if(any(colSums(t(mat))==0)){ - mat <- cbind(mat, (colSums(t(mat))==0)) - } - node_in_equivalence(.data, mat, - k = k, cluster = cluster, distance = distance, range = range) -} - -#' @rdname equivalence -#' @examples -#' \donttest{ -#' (nre <- node_in_regular(mpn_elite_usa_advice, -#' cluster = "concor")) -#' plot(nre) -#' } -#' @export -node_in_regular <- function(.data, - k = c("silhouette", "elbow", "strict"), - cluster = c("hierarchical", "concor"), - distance = c("euclidean", "maximum", "manhattan", - "canberra", "binary", "minkowski"), - range = 8L){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(manynet::is_twomode(.data)){ - mat <- as.matrix(node_quad_census(.data)) - } else { - mat <- node_triad_census(.data) - } - if(any(colSums(mat) == 0)) mat <- mat[,-which(colSums(mat) == 0)] - node_in_equivalence(.data, mat, - k = k, cluster = cluster, distance = distance, range = range) -} - -#' @rdname equivalence -#' @examples -#' \donttest{ -#' (nae <- node_in_automorphic(mpn_elite_usa_advice, -#' k = "elbow")) -#' plot(nae) -#' } -#' @export -node_in_automorphic <- function(.data, - k = c("silhouette", "elbow", "strict"), - cluster = c("hierarchical", "concor"), - distance = c("euclidean", "maximum", "manhattan", - "canberra", "binary", "minkowski"), - range = 8L){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - mat <- node_path_census(.data) - node_in_equivalence(.data, mat, - k = k, cluster = cluster, distance = distance, range = range) -} diff --git a/R/migraph-defunct.R b/R/migraph-defunct.R index 5ec10973..c6656176 100644 --- a/R/migraph-defunct.R +++ b/R/migraph-defunct.R @@ -364,170 +364,18 @@ node_homophily <- function(object, attribute) { node_heterophily(object, attribute) } -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_optimal <- function(.data) { - .Deprecated("node_in_optimal", package = "migraph", - old = "node_optimal") - node_in_optimal(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_kernighanlin <- function(.data) { - .Deprecated("node_in_partition", package = "migraph", - old = "node_kernighanlin") - node_in_partition(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_edge_betweenness <- function(.data) { - .Deprecated("node_in_betweenness", package = "migraph", - old = "node_edge_betweenness") - node_in_betweenness(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_fast_greedy <- function(.data) { - .Deprecated("node_in_greedy", package = "migraph", - old = "node_fast_greedy") - node_in_greedy(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_leading_eigen <- function(.data) { - .Deprecated("node_in_eigen", package = "migraph", - old = "node_leading_eigen") - node_in_eigen(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_walktrap <- function(.data) { - .Deprecated("node_in_walktrap", package = "migraph", - old = "node_walktrap") - node_in_walktrap(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_infomap <- function(.data) { - .Deprecated("node_in_infomap", package = "migraph", - old = "node_infomap") - node_in_infomap(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_spinglass <- function(.data) { - .Deprecated("node_in_spinglass", package = "migraph", - old = "node_spinglass") - node_in_spinglass(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_fluid <- function(.data) { - .Deprecated("node_in_fluid", package = "migraph", - old = "node_fluid") - node_in_fluid(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_leiden <- function(.data) { - .Deprecated("node_in_leiden", package = "migraph", - old = "node_leiden") - node_in_leiden(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_louvain <- function(.data) { - .Deprecated("node_in_louvain", package = "migraph", - old = "node_louvain") - node_in_louvain(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_core <- function(.data) { - .Deprecated("node_in_core", package = "migraph", - old = "node_core") - node_in_core(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_roulette <- function(.data) { - .Deprecated("node_in_roulette", package = "migraph", - old = "node_roulette") - node_in_roulette(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_components <- function(.data) { - .Deprecated("node_in_component", package = "migraph", - old = "node_components") - node_in_component(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_weak_components <- function(.data) { - .Deprecated("node_in_weak", package = "migraph", - old = "node_weak_components") - node_in_weak(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_strong_components <- function(.data) { - .Deprecated("node_in_strong", package = "migraph", - old = "node_strong_components") - node_in_strong(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_equivalence <- function(.data) { - .Deprecated("node_in_equivalence", package = "migraph", - old = "node_equivalence") - node_in_equivalence(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_structural_equivalence <- function(.data) { - .Deprecated("node_in_structural", package = "migraph", - old = "node_structural_equivalence") - node_in_structural(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_regular_equivalence <- function(.data) { - .Deprecated("node_in_regular", package = "migraph", - old = "node_regular_equivalence") - node_in_regular(.data) -} - -#' @describeIn defunct Deprecated on 2024-06-14. -#' @export -node_automorphic_equivalence <- function(.data) { - .Deprecated("node_in_automorphic", package = "migraph", - old = "node_automorphic_equivalence") - node_in_automorphic(.data) -} - #' @describeIn defunct Deprecated on 2024-06-16. #' @export test_gof <- function(diff_model, diff_models) { .Deprecated("test_fit", package = "migraph", old = "test_gof") test_fit(diff_model, diff_models) +} + +#' @describeIn defunct Deprecated on 2024-06-19. +#' @export +node_adopter <- function(diff_model) { + .Deprecated("node_in_adopter", package = "migraph", + old = "node_adopter") + node_in_adopter(diff_model) } \ No newline at end of file diff --git a/man/cluster.Rd b/man/cluster.Rd deleted file mode 100644 index 076ee2f0..00000000 --- a/man/cluster.Rd +++ /dev/null @@ -1,68 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/model_cluster.R -\name{cluster} -\alias{cluster} -\alias{cluster_hierarchical} -\alias{cluster_concor} -\title{Methods for equivalence clustering} -\usage{ -cluster_hierarchical(census, distance) - -cluster_concor(.data, census) -} -\arguments{ -\item{census}{A matrix returned by a \verb{node_*_census()} function.} - -\item{distance}{Character string indicating which distance metric -to pass on to \code{stats::dist}. -By default \code{"euclidean"}, but other options include -\code{"maximum"}, \code{"manhattan"}, \code{"canberra"}, \code{"binary"}, and \code{"minkowski"}. -Fewer, identifiable letters, e.g. \code{"e"} for Euclidean, is sufficient.} - -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} -} -\description{ -These functions are used to cluster some census object: -\itemize{ -\item \code{cluster_hierarchical()} returns a hierarchical clustering object -created by \code{stats::hclust()}. -\item \code{cluster_concor()} returns a hierarchical clustering object -created from a convergence of correlations procedure (CONCOR). -} - -These functions are not intended to be called directly, -but are called within \code{node_equivalence()} and related functions. -They are exported and listed here to provide more detailed documentation. -} -\section{CONCOR}{ - - -First a matrix of Pearson correlation coefficients between each pair of nodes -profiles in the given census is created. -Then, again, we find the correlations of this square, symmetric matrix, -and continue to do this iteratively until each entry is either \code{1} or \code{-1}. -These values are used to split the data into two partitions, -with members either holding the values \code{1} or \code{-1}. -This procedure from census to convergence is then repeated within each block, -allowing further partitions to be found. -Unlike UCINET, partitions are continued until there are single members in -each partition. -Then a distance matrix is constructed from records of in which partition phase -nodes were separated, -and this is given to \code{stats::hclust()} so that dendrograms etc can be returned. -} - -\references{ -Breiger, Ronald L., Scott A. Boorman, and Phipps Arabie. 1975. -"An Algorithm for Clustering Relational Data with Applications to -Social Network Analysis and Comparison with Multidimensional Scaling". -\emph{Journal of Mathematical Psychology}, 12: 328-83. -\doi{10.1016/0022-2496(75)90028-0}. -} diff --git a/man/equivalence.Rd b/man/equivalence.Rd deleted file mode 100644 index d7f0e59c..00000000 --- a/man/equivalence.Rd +++ /dev/null @@ -1,130 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/member_equivalence.R -\name{equivalence} -\alias{equivalence} -\alias{node_in_equivalence} -\alias{node_in_structural} -\alias{node_in_regular} -\alias{node_in_automorphic} -\title{Equivalence clustering algorithms} -\source{ -\url{https://github.com/aslez/concoR} -} -\usage{ -node_in_equivalence( - .data, - census, - k = c("silhouette", "elbow", "strict"), - cluster = c("hierarchical", "concor"), - distance = c("euclidean", "maximum", "manhattan", "canberra", "binary", "minkowski"), - range = 8L -) - -node_in_structural( - .data, - k = c("silhouette", "elbow", "strict"), - cluster = c("hierarchical", "concor"), - distance = c("euclidean", "maximum", "manhattan", "canberra", "binary", "minkowski"), - range = 8L -) - -node_in_regular( - .data, - k = c("silhouette", "elbow", "strict"), - cluster = c("hierarchical", "concor"), - distance = c("euclidean", "maximum", "manhattan", "canberra", "binary", "minkowski"), - range = 8L -) - -node_in_automorphic( - .data, - k = c("silhouette", "elbow", "strict"), - cluster = c("hierarchical", "concor"), - distance = c("euclidean", "maximum", "manhattan", "canberra", "binary", "minkowski"), - range = 8L -) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{census}{A matrix returned by a \verb{node_*_census()} function.} - -\item{k}{Typically a character string indicating which method -should be used to select the number of clusters to return. -By default \code{"silhouette"}, other options include \code{"elbow"} and \code{"strict"}. -\code{"strict"} returns classes with members only when strictly equivalent. -\code{"silhouette"} and \code{"elbow"} select classes based on the distance between -clusters or between nodes within a cluster. -Fewer, identifiable letters, e.g. \code{"e"} for elbow, is sufficient. -Alternatively, if \code{k} is passed an integer, e.g. \code{k = 3}, -then all selection routines are skipped in favour of this number of clusters.} - -\item{cluster}{Character string indicating whether clusters should be -clustered hierarchically (\code{"hierarchical"}) or -through convergence of correlations (\code{"concor"}). -Fewer, identifiable letters, e.g. \code{"c"} for CONCOR, is sufficient.} - -\item{distance}{Character string indicating which distance metric -to pass on to \code{stats::dist}. -By default \code{"euclidean"}, but other options include -\code{"maximum"}, \code{"manhattan"}, \code{"canberra"}, \code{"binary"}, and \code{"minkowski"}. -Fewer, identifiable letters, e.g. \code{"e"} for Euclidean, is sufficient.} - -\item{range}{Integer indicating the maximum number of (k) clusters -to evaluate. -Ignored when \code{k = "strict"} or a discrete number is given for \code{k}.} -} -\description{ -These functions combine an appropriate \verb{_census()} function -together with methods for calculating the hierarchical clusters -provided by a certain distance calculation. -\itemize{ -\item \code{node_in_equivalence()} assigns nodes membership based on their equivalence -with respective to some census/class. -The following functions call this function, together with an appropriate census. -\itemize{ -\item \code{node_in_structural()} assigns nodes membership based on their -having equivalent ties to the same other nodes. -\item \code{node_in_regular()} assigns nodes membership based on their -having equivalent patterns of ties. -\item \code{node_in_automorphic()} assigns nodes membership based on their -having equivalent distances to other nodes. -} -} - -A \code{plot()} method exists for investigating the dendrogram -of the hierarchical cluster and showing the returned cluster -assignment. -} -\examples{ -\donttest{ -(nse <- node_in_structural(mpn_elite_usa_advice)) -plot(nse) -} -\donttest{ -(nre <- node_in_regular(mpn_elite_usa_advice, - cluster = "concor")) -plot(nre) -} -\donttest{ -(nae <- node_in_automorphic(mpn_elite_usa_advice, - k = "elbow")) -plot(nae) -} -} -\seealso{ -Other memberships: -\code{\link{cliques}}, -\code{\link{community}}, -\code{\link{components}()}, -\code{\link{core}}, -\code{\link{hierarchical_community}} -} -\concept{memberships} diff --git a/man/kselect.Rd b/man/kselect.Rd deleted file mode 100644 index 7b45409e..00000000 --- a/man/kselect.Rd +++ /dev/null @@ -1,58 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/model_k.R -\name{kselect} -\alias{kselect} -\alias{k_strict} -\alias{k_elbow} -\alias{k_silhouette} -\title{Methods for selecting clusters} -\usage{ -k_strict(hc, .data) - -k_elbow(hc, .data, census, range) - -k_silhouette(hc, .data, range) -} -\arguments{ -\item{hc}{A hierarchical clustering object.} - -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{census}{A motif census object.} - -\item{range}{An integer indicating the maximum number of options to consider. -The minimum of this and the number of nodes in the network is used.} -} -\description{ -These functions help select the number of clusters to return from \code{hc}, -some hierarchical clustering object: -\itemize{ -\item \code{k_strict()} selects a number of clusters in which there is no -distance between cluster members. -\item \code{k_elbow()} selects a number of clusters in which there is -a fair trade-off between parsimony and fit according to the elbow method. -\item \code{k_silhouette()} selects a number of clusters that -optimises the silhouette score. -} - -These functions are generally not user-facing but used internally -in e.g. the \verb{*_equivalence()} functions. -} -\references{ -Thorndike, Robert L. 1953. -"Who Belongs in the Family?". -\emph{Psychometrika}, 18(4): 267–76. -\doi{10.1007/BF02289263}. - -Rousseeuw, Peter J. 1987. -“Silhouettes: A Graphical Aid to the Interpretation and Validation of Cluster Analysis.” -\emph{Journal of Computational and Applied Mathematics}, 20: 53–65. -\doi{10.1016/0377-0427(87)90125-7}. -} From 1cdc41eebdbf68602f1ccb92465f0c0f185f5819 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:18:22 +0200 Subject: [PATCH 57/97] Migrated cohesion measures to manynet --- R/measure_cohesion.R | 131 ------------------------------------------- man/cohesion.Rd | 97 -------------------------------- 2 files changed, 228 deletions(-) delete mode 100644 R/measure_cohesion.R delete mode 100644 man/cohesion.Rd diff --git a/R/measure_cohesion.R b/R/measure_cohesion.R deleted file mode 100644 index 91f955a8..00000000 --- a/R/measure_cohesion.R +++ /dev/null @@ -1,131 +0,0 @@ -#' Measures of network cohesion or connectedness -#' -#' @description -#' These functions return values or vectors relating to how connected a network is -#' and the number of nodes or edges to remove that would increase fragmentation. -#' -#' - `network_density()` measures the ratio of ties to the number -#' of possible ties. -#' - `network_components()` measures the number of (strong) components -#' in the network. -#' - `network_cohesion()` measures the minimum number of nodes to remove -#' from the network needed to increase the number of components. -#' - `network_adhesion()` measures the minimum number of ties to remove -#' from the network needed to increase the number of components. -#' - `network_diameter()` measures the maximum path length in the network. -#' - `network_length()` measures the average path length in the network. -#' - `network_independence()` measures the independence number, -#' or size of the largest independent set in the network. -#' @param .data An object of a `{manynet}`-consistent class: -#' \itemize{ -#' \item matrix (adjacency or incidence) from `{base}` R -#' \item edgelist, a data frame from `{base}` R or tibble from `{tibble}` -#' \item igraph, from the `{igraph}` package -#' \item network, from the `{network}` package -#' \item tbl_graph, from the `{tidygraph}` package -#' } -#' @name cohesion -#' @family measures -NULL - -#' @rdname cohesion -#' @importFrom igraph edge_density -#' @examples -#' network_density(mpn_elite_mex) -#' network_density(mpn_elite_usa_advice) -#' @export -network_density <- function(.data) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - if (manynet::is_twomode(.data)) { - mat <- manynet::as_matrix(.data) - out <- sum(mat) / (nrow(mat) * ncol(mat)) - } else { - out <- igraph::edge_density(manynet::as_igraph(.data)) - } - make_network_measure(out, .data) -} - -#' @rdname cohesion -#' @section Cohesion: -#' To get the 'weak' components of a directed graph, -#' please use `manynet::to_undirected()` first. -#' @importFrom igraph components -#' @examples -#' network_components(mpn_ryanair) -#' network_components(manynet::to_undirected(mpn_ryanair)) -#' @export -network_components <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - object <- manynet::as_igraph(.data) - make_network_measure(igraph::components(object, mode = "strong")$no, - object) -} - -#' @rdname cohesion -#' @importFrom igraph cohesion -#' @references -#' White, Douglas R and Frank Harary. 2001. -#' "The Cohesiveness of Blocks In Social Networks: Node Connectivity and Conditional Density." -#' _Sociological Methodology_ 31(1): 305-59. -#' @examples -#' network_cohesion(manynet::ison_marvel_relationships) -#' network_cohesion(manynet::to_giant(manynet::ison_marvel_relationships)) -#' @export -network_cohesion <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - make_network_measure(igraph::cohesion(manynet::as_igraph(.data)), .data) -} - -#' @rdname cohesion -#' @importFrom igraph adhesion -#' @examples -#' network_adhesion(manynet::ison_marvel_relationships) -#' network_adhesion(manynet::to_giant(manynet::ison_marvel_relationships)) -#' @export -network_adhesion <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - make_network_measure(igraph::adhesion(manynet::as_igraph(.data)), .data) -} - -#' @rdname cohesion -#' @importFrom igraph diameter -#' @examples -#' network_diameter(manynet::ison_marvel_relationships) -#' network_diameter(manynet::to_giant(manynet::ison_marvel_relationships)) -#' @export -network_diameter <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - object <- manynet::as_igraph(.data) - make_network_measure(igraph::diameter(object, - directed = manynet::is_directed(object)), - object) -} - -#' @rdname cohesion -#' @importFrom igraph mean_distance -#' @examples -#' network_length(manynet::ison_marvel_relationships) -#' network_length(manynet::to_giant(manynet::ison_marvel_relationships)) -#' @export -network_length <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - object <- manynet::as_igraph(.data) - make_network_measure(igraph::mean_distance(object, - directed = manynet::is_directed(object)), - object) -} - -#' @rdname cohesion -#' @importFrom igraph ivs_size -#' @examples -#' network_independence(manynet::ison_adolescents) -#' @export -network_independence <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(manynet::is_twomode(.data)){ - out <- igraph::ivs_size(manynet::to_mode1(manynet::as_igraph(.data))) - } else { - out <- igraph::ivs_size(manynet::to_undirected(manynet::as_igraph(.data))) - } - make_network_measure(out, .data) -} diff --git a/man/cohesion.Rd b/man/cohesion.Rd deleted file mode 100644 index 55cc7120..00000000 --- a/man/cohesion.Rd +++ /dev/null @@ -1,97 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_cohesion.R -\name{cohesion} -\alias{cohesion} -\alias{network_density} -\alias{network_components} -\alias{network_cohesion} -\alias{network_adhesion} -\alias{network_diameter} -\alias{network_length} -\alias{network_independence} -\title{Measures of network cohesion or connectedness} -\usage{ -network_density(.data) - -network_components(.data) - -network_cohesion(.data) - -network_adhesion(.data) - -network_diameter(.data) - -network_length(.data) - -network_independence(.data) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} -} -\description{ -These functions return values or vectors relating to how connected a network is -and the number of nodes or edges to remove that would increase fragmentation. -\itemize{ -\item \code{network_density()} measures the ratio of ties to the number -of possible ties. -\item \code{network_components()} measures the number of (strong) components -in the network. -\item \code{network_cohesion()} measures the minimum number of nodes to remove -from the network needed to increase the number of components. -\item \code{network_adhesion()} measures the minimum number of ties to remove -from the network needed to increase the number of components. -\item \code{network_diameter()} measures the maximum path length in the network. -\item \code{network_length()} measures the average path length in the network. -\item \code{network_independence()} measures the independence number, -or size of the largest independent set in the network. -} -} -\section{Cohesion}{ - -To get the 'weak' components of a directed graph, -please use \code{manynet::to_undirected()} first. -} - -\examples{ -network_density(mpn_elite_mex) -network_density(mpn_elite_usa_advice) - network_components(mpn_ryanair) - network_components(manynet::to_undirected(mpn_ryanair)) -network_cohesion(manynet::ison_marvel_relationships) -network_cohesion(manynet::to_giant(manynet::ison_marvel_relationships)) -network_adhesion(manynet::ison_marvel_relationships) -network_adhesion(manynet::to_giant(manynet::ison_marvel_relationships)) -network_diameter(manynet::ison_marvel_relationships) -network_diameter(manynet::to_giant(manynet::ison_marvel_relationships)) -network_length(manynet::ison_marvel_relationships) -network_length(manynet::to_giant(manynet::ison_marvel_relationships)) -network_independence(manynet::ison_adolescents) -} -\references{ -White, Douglas R and Frank Harary. 2001. -"The Cohesiveness of Blocks In Social Networks: Node Connectivity and Conditional Density." -\emph{Sociological Methodology} 31(1): 305-59. -} -\seealso{ -Other measures: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{closure}}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}}, -\code{\link{features}}, -\code{\link{heterogeneity}}, -\code{\link{hierarchy}}, -\code{\link{holes}}, -\code{\link{net_diffusion}}, -\code{\link{node_diffusion}}, -\code{\link{periods}} -} -\concept{measures} From 9b4873bec904f1b7fc5a59f4f848d01247acd4d2 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:18:49 +0200 Subject: [PATCH 58/97] Migrated community memberships to manynet --- R/member_community.R | 389 ---------------------------------- man/community.Rd | 196 ----------------- man/hierarchical_community.Rd | 121 ----------- 3 files changed, 706 deletions(-) delete mode 100644 R/member_community.R delete mode 100644 man/community.Rd delete mode 100644 man/hierarchical_community.Rd diff --git a/R/member_community.R b/R/member_community.R deleted file mode 100644 index 71488521..00000000 --- a/R/member_community.R +++ /dev/null @@ -1,389 +0,0 @@ -# Non-hierarchical community partitioning #### - -#' Non-hierarchical community partitioning algorithms -#' -#' @description -#' These functions offer algorithms for partitioning -#' networks into sets of communities: -#' -#' - `node_in_optimal()` is a problem-solving algorithm that seeks to maximise -#' modularity over all possible partitions. -#' - `node_in_kernaghinlin()` is a greedy, iterative, deterministic -#' partitioning algorithm that results in two equally-sized communities. -#' - `node_in_infomap()` is an algorithm based on the information in random walks. -#' - `node_in_spinglass()` is a greedy, iterative, probabilistic algorithm, -#' based on analogy to model from statistical physics. -#' - `node_in_fluid()` is a propogation-based partitioning algorithm, -#' based on analogy to model from fluid dynamics. -#' - `node_in_louvain()` is an agglomerative multilevel algorithm that seeks to maximise -#' modularity over all possible partitions. -#' - `node_in_leiden()` is an agglomerative multilevel algorithm that seeks to maximise -#' the Constant Potts Model over all possible partitions. -#' -#' The different algorithms offer various advantages in terms of computation time, -#' availability on different types of networks, ability to maximise modularity, -#' and their logic or domain of inspiration. -#' -#' @inheritParams cohesion -#' @name community -#' @family memberships -NULL - -#' @rdname community -#' @section Optimal: -#' The general idea is to calculate the modularity of all possible partitions, -#' and choose the community structure that maximises this modularity measure. -#' Note that this is an NP-complete problem with exponential time complexity. -#' The guidance in the igraph package is networks of <50-200 nodes is probably fine. -#' @references -#' Brandes, Ulrik, Daniel Delling, Marco Gaertler, Robert Gorke, Martin Hoefer, Zoran Nikoloski, Dorothea Wagner. 2008. -#' "On Modularity Clustering", -#' _IEEE Transactions on Knowledge and Data Engineering_ 20(2):172-188. -#' @examples -#' node_in_optimal(ison_adolescents) -#' @export -node_in_optimal <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- igraph::cluster_optimal(manynet::as_igraph(.data) - )$membership - make_node_member(out, .data) -} - -#' @rdname community -#' @references -#' Kernighan, Brian W., and Shen Lin. 1970. -#' "An efficient heuristic procedure for partitioning graphs." -#' _The Bell System Technical Journal_ 49(2): 291-307. -#' \doi{10.1002/j.1538-7305.1970.tb01770.x} -#' @examples -#' node_in_partition(ison_adolescents) -#' node_in_partition(ison_southern_women) -#' @export -node_in_partition <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - # assign groups arbitrarily - n <- manynet::network_nodes(.data) - group_size <- ifelse(n %% 2 == 0, n/2, (n+1)/2) - - # count internal and external costs of each vertex - g <- manynet::as_matrix(manynet::to_multilevel(.data)) - g1 <- g[1:group_size, 1:group_size] - g2 <- g[(group_size+1):n, (group_size+1):n] - intergroup <- g[1:group_size, (group_size+1):n] - - g2.intcosts <- rowSums(g2) - g2.extcosts <- colSums(intergroup) - - g1.intcosts <- rowSums(g1) - g1.extcosts <- rowSums(intergroup) - - # count edge costs of each vertex - g1.net <- g1.extcosts - g1.intcosts - g2.net <- g2.extcosts - g2.intcosts - - g1.net <- sort(g1.net, decreasing = TRUE) - g2.net <- sort(g2.net, decreasing = TRUE) - - # swap pairs of vertices (one from each group) that give a positive sum of net edge costs - if(length(g1.net)!=length(g2.net)) { - g2.net <- c(g2.net,0) - } else {g2.net} - - sums <- as.integer(unname(g1.net + g2.net)) - # positions in sequence of names at which sum >= 0 - index <- which(sums >= 0 %in% sums) - g1.newnames <- g1.names <- names(g1.net) - g2.newnames <- g2.names <- names(g2.net) - # make swaps based on positions in sequence - for (i in index) { - g1.newnames[i] <- g2.names[i] - g2.newnames[i] <- g1.names[i] - } - - # extract names of vertices in each group after swaps - out <- ifelse(manynet::node_names(.data) %in% g1.newnames, 1, 2) - make_node_member(out, .data) -} - -#' @rdname community -#' @section Infomap: -#' Motivated by information theoretic principles, this algorithm tries to build -#' a grouping that provides the shortest description length for a random walk, -#' where the description length is measured by the expected number of bits per node required to encode the path. -#' @param times Integer indicating number of simulations/walks used. -#' By default, `times=50`. -#' @references -#' Rosvall, M, and C. T. Bergstrom. 2008. -#' "Maps of information flow reveal community structure in complex networks", -#' _PNAS_ 105:1118. -#' \doi{10.1073/pnas.0706851105} -#' -#' Rosvall, M., D. Axelsson, and C. T. Bergstrom. 2009. -#' "The map equation", -#' _Eur. Phys. J. Special Topics_ 178: 13. -#' \doi{10.1140/epjst/e2010-01179-1} -#' @examples -#' node_in_infomap(ison_adolescents) -#' @export -node_in_infomap <- function(.data, times = 50){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- igraph::cluster_infomap(manynet::as_igraph(.data), - nb.trials = times - )$membership - make_node_member(out, .data) -} - -#' @rdname community -#' @param max_k Integer constant, the number of spins to use as an upper limit -#' of communities to be found. Some sets can be empty at the end. -#' @param resolution The Reichardt-Bornholdt “gamma” resolution parameter for modularity. -#' By default 1, making existing and non-existing ties equally important. -#' Smaller values make existing ties more important, -#' and larger values make missing ties more important. -#' @section Spin-glass: -#' This is motivated by analogy to the Potts model in statistical physics. -#' Each node can be in one of _k_ "spin states", -#' and ties (particle interactions) provide information about which pairs of nodes -#' want similar or different spin states. -#' The final community definitions are represented by the nodes' spin states -#' after a number of updates. -#' A different implementation than the default is used in the case of signed networks, -#' such that nodes connected by negative ties will be more likely found in separate communities. -#' @references -#' Reichardt, Jorg, and Stefan Bornholdt. 2006. -#' "Statistical Mechanics of Community Detection" -#' _Physical Review E_, 74(1): 016110–14. -#' \doi{10.1073/pnas.0605965104} -#' -#' Traag, VA, and Jeroen Bruggeman. 2008. -#' "Community detection in networks with positive and negative links". -#' @examples -#' node_in_spinglass(ison_adolescents) -#' @export -node_in_spinglass <- function(.data, max_k = 200, resolution = 1){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- igraph::cluster_spinglass(manynet::as_igraph(.data), - spins = max_k, gamma = resolution, - implementation = ifelse(manynet::is_signed(.data), "neg", "orig") - )$membership - make_node_member(out, .data) -} - -#' @rdname community -#' @section Fluid: -#' The general idea is to observe how a discrete number of fluids interact, expand and contract, -#' in a non-homogenous environment, i.e. the network structure. -#' Unlike the `{igraph}` implementation that this function wraps, -#' this function iterates over all possible numbers of communities and returns the membership -#' associated with the highest modularity. -#' @references -#' Parés F, Gasulla DG, et. al. 2018. -#' "Fluid Communities: A Competitive, Scalable and Diverse Community Detection Algorithm". -#' In: _Complex Networks & Their Applications VI_ -#' Springer, 689: 229. -#' \doi{10.1007/978-3-319-72150-7_19} -#' @examples -#' node_in_fluid(ison_adolescents) -#' @export -node_in_fluid <- function(.data) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - .data <- as_igraph(.data) - mods <- vapply(seq.int(manynet::network_nodes(.data)), function(x) - igraph::modularity(.data, membership = igraph::membership( - igraph::cluster_fluid_communities(.data, x))), - FUN.VALUE = numeric(1)) - out <- igraph::membership(igraph::cluster_fluid_communities( - .data, no.of.communities = which.max(mods))) - make_node_member(out, .data) -} - -#' @rdname community -#' @section Louvain: -#' The general idea is to take a hierarchical approach to optimising the modularity criterion. -#' Nodes begin in their own communities and are re-assigned in a local, greedy way: -#' each node is moved to the community where it achieves the highest contribution to modularity. -#' When no further modularity-increasing reassignments are possible, -#' the resulting communities are considered nodes (like a reduced graph), -#' and the process continues. -#' @references -#' Blondel, Vincent, Jean-Loup Guillaume, Renaud Lambiotte, Etienne Lefebvre. 2008. -#' "Fast unfolding of communities in large networks", -#' _J. Stat. Mech._ P10008. -#' @examples -#' node_in_louvain(ison_adolescents) -#' @export -node_in_louvain <- function(.data, resolution = 1){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- igraph::cluster_louvain(manynet::as_igraph(.data), - resolution = resolution - )$membership - make_node_member(out, .data) -} - -#' @rdname community -#' @section Leiden: -#' The general idea is to optimise the Constant Potts Model, -#' which does not suffer from the resolution limit, instead of modularity. -#' As outlined in the `{igraph}` package, -#' the Constant Potts Model object function is: -#' -#' \deqn{\frac{1}{2m} \sum_{ij}(A_{ij}-\gamma n_i n_j)\delta(\sigma_i, \sigma_j)} -#' -#' where _m_ is the total tie weight, -#' \eqn{A_{ij}} is the tie weight between _i_ and _j_, -#' \eqn{\gamma} is the so-called resolution parameter, -#' \eqn{n_i} is the node weight of node _i_, -#' and \eqn{\delta(\sigma_i, \sigma_j) = 1} if and only if -#' _i_ and _j_ are in the same communities and 0 otherwise. -#' @references -#' Traag, V. A., L Waltman, and NJ van Eck. 2019. -#' "From Louvain to Leiden: guaranteeing well-connected communities", -#' _Scientific Reports_, 9(1):5233. -#' \doi{10.1038/s41598-019-41695-z} -#' @examples -#' node_in_leiden(ison_adolescents) -#' @export -node_in_leiden <- function(.data, resolution = 1){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(manynet::is_weighted(.data)){ # Traag resolution default - n <- manynet::network_nodes(.data) - resolution <- sum(manynet::tie_weights(.data))/(n*(n - 1)/2) - } - out <- igraph::cluster_leiden(manynet::as_igraph(.data), - resolution_parameter = resolution - )$membership - make_node_member(out, .data) -} - -# Hierarchical community partitioning #### - -#' Hierarchical community partitioning algorithms -#' -#' @description -#' These functions offer algorithms for hierarchically clustering -#' networks into communities. Since all of the following are hierarchical, -#' their dendrograms can be plotted: -#' -#' - `node_in_betweenness()` is a hierarchical, decomposition algorithm -#' where edges are removed in decreasing order of the number of -#' shortest paths passing through the edge. -#' - `node_in_greedy()` is a hierarchical, agglomerative algorithm, -#' that tries to optimize modularity in a greedy manner. -#' - `node_in_eigen()` is a top-down, hierarchical algorithm. -#' - `node_in_walktrap()` is a hierarchical, agglomerative algorithm based on random walks. -#' -#' The different algorithms offer various advantages in terms of computation time, -#' availability on different types of networks, ability to maximise modularity, -#' and their logic or domain of inspiration. -#' -#' @inheritParams community -#' @name hierarchical_community -#' @family memberships -NULL - -#' @rdname hierarchical_community -#' @section Edge-betweenness: -#' This is motivated by the idea that edges connecting different groups -#' are more likely to lie on multiple shortest paths when they are the -#' only option to go from one group to another. -#' This method yields good results but is very slow because of -#' the computational complexity of edge-betweenness calculations and -#' the betweenness scores have to be re-calculated after every edge removal. -#' Networks of ~700 nodes and ~3500 ties are around the upper size limit -#' that are feasible with this approach. -#' @references -#' Newman, M, and M Girvan. 2004. -#' "Finding and evaluating community structure in networks." -#' _Physical Review E_ 69: 026113. -#' @examples -#' node_in_betweenness(ison_adolescents) -#' plot(node_in_betweenness(ison_adolescents)) -#' @export -node_in_betweenness <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - clust <- suppressWarnings(igraph::cluster_edge_betweenness( - manynet::as_igraph(.data))) - out <- clust$membership - out <- make_node_member(out, .data) - attr(out, "hc") <- stats::as.hclust(clust, use.modularity = TRUE) - attr(out, "k") <- max(clust$membership) - out -} - -#' @rdname hierarchical_community -#' @section Fast-greedy: -#' Initially, each node is assigned a separate community. -#' Communities are then merged iteratively such that each merge -#' yields the largest increase in the current value of modularity, -#' until no further increases to the modularity are possible. -#' The method is fast and recommended as a first approximation -#' because it has no parameters to tune. -#' However, it is known to suffer from a resolution limit. -#' @references -#' Clauset, A, MEJ Newman, MEJ and C Moore. -#' "Finding community structure in very large networks." -#' @examples -#' node_in_greedy(ison_adolescents) -#' @export -node_in_greedy <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - clust <- igraph::cluster_fast_greedy(manynet::as_igraph(.data)) - out <- clust$membership - make_node_member(out, .data) - out <- make_node_member(out, .data) - attr(out, "hc") <- stats::as.hclust(clust, use.modularity = TRUE) - attr(out, "k") <- max(clust$membership) - out -} - -#' @rdname hierarchical_community -#' @section Leading eigenvector: -#' In each step, the network is bifurcated such that modularity increases most. -#' The splits are determined according to the leading eigenvector of the modularity matrix. -#' A stopping condition prevents tightly connected groups from being split further. -#' Note that due to the eigenvector calculations involved, -#' this algorithm will perform poorly on degenerate networks, -#' but will likely obtain a higher modularity than fast-greedy (at some cost of speed). -#' @references -#' Newman, MEJ. 2006. -#' "Finding community structure using the eigenvectors of matrices" -#' _Physical Review E_ 74:036104. -#' @examples -#' node_in_eigen(ison_adolescents) -#' @export -node_in_eigen <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - clust <- igraph::cluster_leading_eigen(manynet::as_igraph(.data)) - out <- clust$membership - make_node_member(out, .data) - out <- make_node_member(out, .data) - attr(out, "hc") <- stats::as.hclust(clust) - attr(out, "k") <- max(clust$membership) - out -} - -#' @rdname hierarchical_community -#' @section Walktrap: -#' The general idea is that random walks on a network are more likely to stay -#' within the same community because few edges lead outside a community. -#' By repeating random walks of 4 steps many times, -#' information about the hierarchical merging of communities is collected. -#' @param times Integer indicating number of simulations/walks used. -#' By default, `times=50`. -#' @references -#' Pons, Pascal, and Matthieu Latapy -#' "Computing communities in large networks using random walks". -#' @examples -#' node_in_walktrap(ison_adolescents) -#' @export -node_in_walktrap <- function(.data, times = 50){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - clust <- igraph::cluster_walktrap(manynet::as_igraph(.data)) - out <- clust$membership - make_node_member(out, .data) - out <- make_node_member(out, .data) - attr(out, "hc") <- stats::as.hclust(clust, use.modularity = TRUE) - attr(out, "k") <- max(clust$membership) - out -} - diff --git a/man/community.Rd b/man/community.Rd deleted file mode 100644 index 49578b0e..00000000 --- a/man/community.Rd +++ /dev/null @@ -1,196 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/member_community.R -\name{community} -\alias{community} -\alias{node_in_optimal} -\alias{node_in_partition} -\alias{node_in_infomap} -\alias{node_in_spinglass} -\alias{node_in_fluid} -\alias{node_in_louvain} -\alias{node_in_leiden} -\title{Non-hierarchical community partitioning algorithms} -\usage{ -node_in_optimal(.data) - -node_in_partition(.data) - -node_in_infomap(.data, times = 50) - -node_in_spinglass(.data, max_k = 200, resolution = 1) - -node_in_fluid(.data) - -node_in_louvain(.data, resolution = 1) - -node_in_leiden(.data, resolution = 1) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{times}{Integer indicating number of simulations/walks used. -By default, \code{times=50}.} - -\item{max_k}{Integer constant, the number of spins to use as an upper limit -of communities to be found. Some sets can be empty at the end.} - -\item{resolution}{The Reichardt-Bornholdt “gamma” resolution parameter for modularity. -By default 1, making existing and non-existing ties equally important. -Smaller values make existing ties more important, -and larger values make missing ties more important.} -} -\description{ -These functions offer algorithms for partitioning -networks into sets of communities: -\itemize{ -\item \code{node_in_optimal()} is a problem-solving algorithm that seeks to maximise -modularity over all possible partitions. -\item \code{node_in_kernaghinlin()} is a greedy, iterative, deterministic -partitioning algorithm that results in two equally-sized communities. -\item \code{node_in_infomap()} is an algorithm based on the information in random walks. -\item \code{node_in_spinglass()} is a greedy, iterative, probabilistic algorithm, -based on analogy to model from statistical physics. -\item \code{node_in_fluid()} is a propogation-based partitioning algorithm, -based on analogy to model from fluid dynamics. -\item \code{node_in_louvain()} is an agglomerative multilevel algorithm that seeks to maximise -modularity over all possible partitions. -\item \code{node_in_leiden()} is an agglomerative multilevel algorithm that seeks to maximise -the Constant Potts Model over all possible partitions. -} - -The different algorithms offer various advantages in terms of computation time, -availability on different types of networks, ability to maximise modularity, -and their logic or domain of inspiration. -} -\section{Optimal}{ - -The general idea is to calculate the modularity of all possible partitions, -and choose the community structure that maximises this modularity measure. -Note that this is an NP-complete problem with exponential time complexity. -The guidance in the igraph package is networks of <50-200 nodes is probably fine. -} - -\section{Infomap}{ - -Motivated by information theoretic principles, this algorithm tries to build -a grouping that provides the shortest description length for a random walk, -where the description length is measured by the expected number of bits per node required to encode the path. -} - -\section{Spin-glass}{ - -This is motivated by analogy to the Potts model in statistical physics. -Each node can be in one of \emph{k} "spin states", -and ties (particle interactions) provide information about which pairs of nodes -want similar or different spin states. -The final community definitions are represented by the nodes' spin states -after a number of updates. -A different implementation than the default is used in the case of signed networks, -such that nodes connected by negative ties will be more likely found in separate communities. -} - -\section{Fluid}{ - -The general idea is to observe how a discrete number of fluids interact, expand and contract, -in a non-homogenous environment, i.e. the network structure. -Unlike the \code{{igraph}} implementation that this function wraps, -this function iterates over all possible numbers of communities and returns the membership -associated with the highest modularity. -} - -\section{Louvain}{ - -The general idea is to take a hierarchical approach to optimising the modularity criterion. -Nodes begin in their own communities and are re-assigned in a local, greedy way: -each node is moved to the community where it achieves the highest contribution to modularity. -When no further modularity-increasing reassignments are possible, -the resulting communities are considered nodes (like a reduced graph), -and the process continues. -} - -\section{Leiden}{ - -The general idea is to optimise the Constant Potts Model, -which does not suffer from the resolution limit, instead of modularity. -As outlined in the \code{{igraph}} package, -the Constant Potts Model object function is: - -\deqn{\frac{1}{2m} \sum_{ij}(A_{ij}-\gamma n_i n_j)\delta(\sigma_i, \sigma_j)} - -where \emph{m} is the total tie weight, -\eqn{A_{ij}} is the tie weight between \emph{i} and \emph{j}, -\eqn{\gamma} is the so-called resolution parameter, -\eqn{n_i} is the node weight of node \emph{i}, -and \eqn{\delta(\sigma_i, \sigma_j) = 1} if and only if -\emph{i} and \emph{j} are in the same communities and 0 otherwise. -} - -\examples{ -node_in_optimal(ison_adolescents) -node_in_partition(ison_adolescents) -node_in_partition(ison_southern_women) -node_in_infomap(ison_adolescents) -node_in_spinglass(ison_adolescents) -node_in_fluid(ison_adolescents) -node_in_louvain(ison_adolescents) -node_in_leiden(ison_adolescents) -} -\references{ -Brandes, Ulrik, Daniel Delling, Marco Gaertler, Robert Gorke, Martin Hoefer, Zoran Nikoloski, Dorothea Wagner. 2008. -"On Modularity Clustering", -\emph{IEEE Transactions on Knowledge and Data Engineering} 20(2):172-188. - -Kernighan, Brian W., and Shen Lin. 1970. -"An efficient heuristic procedure for partitioning graphs." -\emph{The Bell System Technical Journal} 49(2): 291-307. -\doi{10.1002/j.1538-7305.1970.tb01770.x} - -Rosvall, M, and C. T. Bergstrom. 2008. -"Maps of information flow reveal community structure in complex networks", -\emph{PNAS} 105:1118. -\doi{10.1073/pnas.0706851105} - -Rosvall, M., D. Axelsson, and C. T. Bergstrom. 2009. -"The map equation", -\emph{Eur. Phys. J. Special Topics} 178: 13. -\doi{10.1140/epjst/e2010-01179-1} - -Reichardt, Jorg, and Stefan Bornholdt. 2006. -"Statistical Mechanics of Community Detection" -\emph{Physical Review E}, 74(1): 016110–14. -\doi{10.1073/pnas.0605965104} - -Traag, VA, and Jeroen Bruggeman. 2008. -"Community detection in networks with positive and negative links". - -Parés F, Gasulla DG, et. al. 2018. -"Fluid Communities: A Competitive, Scalable and Diverse Community Detection Algorithm". -In: \emph{Complex Networks & Their Applications VI} -Springer, 689: 229. -\doi{10.1007/978-3-319-72150-7_19} - -Blondel, Vincent, Jean-Loup Guillaume, Renaud Lambiotte, Etienne Lefebvre. 2008. -"Fast unfolding of communities in large networks", -\emph{J. Stat. Mech.} P10008. - -Traag, V. A., L Waltman, and NJ van Eck. 2019. -"From Louvain to Leiden: guaranteeing well-connected communities", -\emph{Scientific Reports}, 9(1):5233. -\doi{10.1038/s41598-019-41695-z} -} -\seealso{ -Other memberships: -\code{\link{cliques}}, -\code{\link{components}()}, -\code{\link{core}}, -\code{\link{equivalence}}, -\code{\link{hierarchical_community}} -} -\concept{memberships} diff --git a/man/hierarchical_community.Rd b/man/hierarchical_community.Rd deleted file mode 100644 index 4b0874de..00000000 --- a/man/hierarchical_community.Rd +++ /dev/null @@ -1,121 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/member_community.R -\name{hierarchical_community} -\alias{hierarchical_community} -\alias{node_in_betweenness} -\alias{node_in_greedy} -\alias{node_in_eigen} -\alias{node_in_walktrap} -\title{Hierarchical community partitioning algorithms} -\usage{ -node_in_betweenness(.data) - -node_in_greedy(.data) - -node_in_eigen(.data) - -node_in_walktrap(.data, times = 50) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{times}{Integer indicating number of simulations/walks used. -By default, \code{times=50}.} -} -\description{ -These functions offer algorithms for hierarchically clustering -networks into communities. Since all of the following are hierarchical, -their dendrograms can be plotted: -\itemize{ -\item \code{node_in_betweenness()} is a hierarchical, decomposition algorithm -where edges are removed in decreasing order of the number of -shortest paths passing through the edge. -\item \code{node_in_greedy()} is a hierarchical, agglomerative algorithm, -that tries to optimize modularity in a greedy manner. -\item \code{node_in_eigen()} is a top-down, hierarchical algorithm. -\item \code{node_in_walktrap()} is a hierarchical, agglomerative algorithm based on random walks. -} - -The different algorithms offer various advantages in terms of computation time, -availability on different types of networks, ability to maximise modularity, -and their logic or domain of inspiration. -} -\section{Edge-betweenness}{ - -This is motivated by the idea that edges connecting different groups -are more likely to lie on multiple shortest paths when they are the -only option to go from one group to another. -This method yields good results but is very slow because of -the computational complexity of edge-betweenness calculations and -the betweenness scores have to be re-calculated after every edge removal. -Networks of ~700 nodes and ~3500 ties are around the upper size limit -that are feasible with this approach. -} - -\section{Fast-greedy}{ - -Initially, each node is assigned a separate community. -Communities are then merged iteratively such that each merge -yields the largest increase in the current value of modularity, -until no further increases to the modularity are possible. -The method is fast and recommended as a first approximation -because it has no parameters to tune. -However, it is known to suffer from a resolution limit. -} - -\section{Leading eigenvector}{ - -In each step, the network is bifurcated such that modularity increases most. -The splits are determined according to the leading eigenvector of the modularity matrix. -A stopping condition prevents tightly connected groups from being split further. -Note that due to the eigenvector calculations involved, -this algorithm will perform poorly on degenerate networks, -but will likely obtain a higher modularity than fast-greedy (at some cost of speed). -} - -\section{Walktrap}{ - -The general idea is that random walks on a network are more likely to stay -within the same community because few edges lead outside a community. -By repeating random walks of 4 steps many times, -information about the hierarchical merging of communities is collected. -} - -\examples{ -node_in_betweenness(ison_adolescents) -plot(node_in_betweenness(ison_adolescents)) -node_in_greedy(ison_adolescents) -node_in_eigen(ison_adolescents) -node_in_walktrap(ison_adolescents) -} -\references{ -Newman, M, and M Girvan. 2004. -"Finding and evaluating community structure in networks." -\emph{Physical Review E} 69: 026113. - -Clauset, A, MEJ Newman, MEJ and C Moore. -"Finding community structure in very large networks." - -Newman, MEJ. 2006. -"Finding community structure using the eigenvectors of matrices" -\emph{Physical Review E} 74:036104. - -Pons, Pascal, and Matthieu Latapy -"Computing communities in large networks using random walks". -} -\seealso{ -Other memberships: -\code{\link{cliques}}, -\code{\link{community}}, -\code{\link{components}()}, -\code{\link{core}}, -\code{\link{equivalence}} -} -\concept{memberships} From f783c655499bf48e2e513a6a127e036808a4d2dc Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:19:03 +0200 Subject: [PATCH 59/97] Migrated core to manynet --- R/member_core.R | 82 ------------------------------------------------- man/core.Rd | 76 --------------------------------------------- 2 files changed, 158 deletions(-) delete mode 100644 R/member_core.R delete mode 100644 man/core.Rd diff --git a/R/member_core.R b/R/member_core.R deleted file mode 100644 index c8bab2c0..00000000 --- a/R/member_core.R +++ /dev/null @@ -1,82 +0,0 @@ -#' Core-periphery clustering algorithms -#' @description -#' These functions identify nodes belonging to (some level of) the core of a network: -#' -#' - `node_in_core()` assigns nodes to either the core or periphery. -#' - `node_coreness()` assigns nodes to their level of k-coreness. -#' -#' @inheritParams cohesion -#' @param method Which method to use to identify cores and periphery. -#' By default this is "degree", -#' which relies on the heuristic that high degree nodes are more likely to be in the core. -#' An alternative is "eigenvector", which instead begins with high eigenvector nodes. -#' Other methods, such as a genetic algorithm, CONCOR, and Rombach-Porter, -#' can be added if there is interest. -#' @name core -#' @family memberships -NULL - -#' @rdname core -#' @section Core-periphery: -#' This function is used to identify which nodes should belong to the core, -#' and which to the periphery. -#' It seeks to minimize the following quantity: -#' \deqn{Z(S_1) = \sum_{(i% as_tidygraph %>% -#' # mutate(corep = node_in_core(mpn_elite_usa_advice)) %>% -#' # autographr(node_color = "corep") -#' node_in_core(mpn_elite_usa_advice) -#' @export -node_in_core <- function(.data, method = c("degree", "eigenvector")){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - method <- match.arg(method) - if(manynet::is_directed(.data)) warning("Asymmetric core-periphery not yet implemented.") - if(method == "degree"){ - degi <- node_degree(.data, normalized = FALSE, - alpha = ifelse(manynet::is_weighted(.data), 1, 0)) - } else if (method == "eigenvector") { - degi <- node_eigenvector(.data, normalized = FALSE) - } else stop("This function expects either 'degree' or 'eigenvector' method to be specified.") - nord <- order(degi, decreasing = TRUE) - zbest <- manynet::network_nodes(.data)*3 - kbest <- 0 - z <- 1/2*sum(degi) - for(k in 1:(manynet::network_nodes(.data)-1)){ - z <- z + k - 1 - degi[nord][k] - if(z < zbest){ - zbest <- z - kbest <- k - } - } - out <- ifelse(seq_len(manynet::network_nodes(.data)) %in% nord[seq_len(kbest)], - 1,2) - make_node_member(out, .data) -} - -#' @rdname core -#' @examples -#' node_coreness(ison_adolescents) -#' @export -node_coreness <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) - out <- igraph::coreness(.data) - make_node_measure(out, .data) -} - diff --git a/man/core.Rd b/man/core.Rd deleted file mode 100644 index c2e07bd4..00000000 --- a/man/core.Rd +++ /dev/null @@ -1,76 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/member_core.R -\name{core} -\alias{core} -\alias{node_in_core} -\alias{node_coreness} -\title{Core-periphery clustering algorithms} -\usage{ -node_in_core(.data, method = c("degree", "eigenvector")) - -node_coreness(.data) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{method}{Which method to use to identify cores and periphery. -By default this is "degree", -which relies on the heuristic that high degree nodes are more likely to be in the core. -An alternative is "eigenvector", which instead begins with high eigenvector nodes. -Other methods, such as a genetic algorithm, CONCOR, and Rombach-Porter, -can be added if there is interest.} -} -\description{ -These functions identify nodes belonging to (some level of) the core of a network: -\itemize{ -\item \code{node_in_core()} assigns nodes to either the core or periphery. -\item \code{node_coreness()} assigns nodes to their level of k-coreness. -} -} -\section{Core-periphery}{ - -This function is used to identify which nodes should belong to the core, -and which to the periphery. -It seeks to minimize the following quantity: -\deqn{Z(S_1) = \sum_{(i\% as_tidygraph \%>\% -# mutate(corep = node_in_core(mpn_elite_usa_advice)) \%>\% -# autographr(node_color = "corep") -node_in_core(mpn_elite_usa_advice) -node_coreness(ison_adolescents) -} -\references{ -Borgatti, Stephen P., & Everett, Martin G. 1999. -Models of core /periphery structures. -\emph{Social Networks}, 21, 375–395. -\doi{10.1016/S0378-8733(99)00019-2} - -Lip, Sean Z. W. 2011. -“A Fast Algorithm for the Discrete Core/Periphery Bipartitioning Problem.” -\doi{10.48550/arXiv.1102.5511} -} -\seealso{ -Other memberships: -\code{\link{cliques}}, -\code{\link{community}}, -\code{\link{components}()}, -\code{\link{equivalence}}, -\code{\link{hierarchical_community}} -} -\concept{memberships} From b1d6578a6d8c1d54bdd73a1e3cfdd0daeab31e6e Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:19:17 +0200 Subject: [PATCH 60/97] Migrated heterogeneity measures to manynet --- R/measure_heterogeneity.R | 208 -------------------------------------- man/heterogeneity.Rd | 141 -------------------------- 2 files changed, 349 deletions(-) delete mode 100644 R/measure_heterogeneity.R delete mode 100644 man/heterogeneity.Rd diff --git a/R/measure_heterogeneity.R b/R/measure_heterogeneity.R deleted file mode 100644 index f40bb626..00000000 --- a/R/measure_heterogeneity.R +++ /dev/null @@ -1,208 +0,0 @@ -#' Measures of network diversity -#' -#' @description -#' These functions offer ways to summarise the heterogeneity of an attribute -#' across a network, within groups of a network, or the distribution of ties -#' across this attribute: -#' -#' - `network_richness()` measures the number of unique categories -#' in a network attribute. -#' - `node_richness()` measures the number of unique categories -#' of an attribute to which each node is connected. -#' - `network_diversity()` measures the heterogeneity of ties across a network -#' or within clusters by node attributes. -#' - `node_diversity()` measures the heterogeneity of each node's -#' local neighbourhood. -#' - `network_heterophily()` measures how embedded nodes in the network -#' are within groups of nodes with the same attribute. -#' - `node_heterophily()` measures each node's embeddedness within groups -#' of nodes with the same attribute. -#' - `network_assortativity()` measures the degree assortativity in a network. -#' - `network_spatial()` measures the spatial association/autocorrelation ( -#' global Moran's I) in a network. -#' -#' @inheritParams cohesion -#' @param attribute Name of a nodal attribute or membership vector -#' to use as categories for the diversity measure. -#' @param clusters A nodal cluster membership vector or name of a vertex attribute. -#' @name heterogeneity -#' @family measures -NULL - -#' @rdname heterogeneity -#' @examples -#' network_richness(mpn_bristol) -#' @export -network_richness <- function(.data, attribute){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - make_network_measure(length(unique(manynet::node_attribute(.data, attribute))), - .data) -} - -#' @rdname heterogeneity -#' @examples -#' node_richness(mpn_bristol, "type") -#' @export -node_richness <- function(.data, attribute){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- vapply(manynet::to_egos(.data, min_dist = 1), - function(x) length(unique(manynet::node_attribute(x, attribute))), - FUN.VALUE = numeric(1)) - make_node_measure(out, .data) -} - -#' @rdname heterogeneity -#' @section network_diversity: -#' Blau's index (1977) uses a formula known also in other disciplines -#' by other names -#' (Gini-Simpson Index, Gini impurity, Gini's diversity index, -#' Gibbs-Martin index, and probability of interspecific encounter (PIE)): -#' \deqn{1 - \sum\limits_{i = 1}^k {p_i^2 }}, -#' where \eqn{p_i} is the proportion of group members in \eqn{i}th category -#' and \eqn{k} is the number of categories for an attribute of interest. -#' This index can be interpreted as the probability that two members -#' randomly selected from a group would be from different categories. -#' This index finds its minimum value (0) when there is no variety, -#' i.e. when all individuals are classified in the same category. -#' The maximum value depends on the number of categories and -#' whether nodes can be evenly distributed across categories. -#' @references -#' Blau, Peter M. (1977). -#' _Inequality and heterogeneity_. -#' New York: Free Press. -#' @examples -#' marvel_friends <- manynet::to_unsigned(manynet::ison_marvel_relationships, "positive") -#' network_diversity(marvel_friends, "Gender") -#' network_diversity(marvel_friends, "Attractive") -#' network_diversity(marvel_friends, "Gender", "Rich") -#' @export -network_diversity <- function(.data, attribute, clusters = NULL){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - blau <- function(features) { 1 - sum((table(features)/length(features))^2) } - attr <- manynet::node_attribute(.data, attribute) - if (is.null(clusters)) { - blauout <- blau(attr) - } else if (is.numeric(clusters) && is.vector(clusters)) { - blauout <- vapply(unique(clusters), - function(i) blau(attr[clusters == i]), - numeric(1)) - names(blauout) <- paste0("Cluster ", unique(clusters)) - } else if (is.character(clusters)) { - clu <- manynet::node_attribute(.data, clusters) - blauout <- vapply(unique(clu), - function(i) blau(attr[clu == i]), - numeric(1)) - names(blauout) <- paste0("Cluster ", unique(clu)) - blauout <- blauout[order(names(blauout))] - } else stop("`clusters` must be the name of a nodal variable in the object.") - make_network_measure(blauout, .data) -} - -#' @rdname heterogeneity -#' @examples -#' node_diversity(marvel_friends, "Gender") -#' node_diversity(marvel_friends, "Attractive") -#' @export -node_diversity <- function(.data, attribute){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- vapply(igraph::ego(manynet::as_igraph(.data)), - function(x) network_diversity( - igraph::induced_subgraph(manynet::as_igraph(.data), x), - attribute), - FUN.VALUE = numeric(1)) - make_node_measure(out, .data) -} - -#' @rdname heterogeneity -#' @section network_homophily: -#' Given a partition of a network into a number of mutually exclusive groups then -#' The E-I index is the number of ties between (or _external_) nodes -#' grouped in some mutually exclusive categories -#' minus the number of ties within (or _internal_) these groups -#' divided by the total number of ties. -#' This value can range from 1 to -1, -#' where 1 indicates ties only between categories/groups and -1 ties only within categories/groups. -#' @references -#' Krackhardt, David and Robert N. Stern (1988). -#' Informal networks and organizational crises: an experimental simulation. -#' _Social Psychology Quarterly_ 51(2), 123-140. -#' @examples -#' network_heterophily(marvel_friends, "Gender") -#' network_heterophily(marvel_friends, "Attractive") -#' @export -network_heterophily <- function(.data, attribute){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - m <- manynet::as_matrix(.data) - if (length(attribute) == 1 && is.character(attribute)) { - attribute <- manynet::node_attribute(.data, attribute) - } - if (is.character(attribute) | is.numeric(attribute)) { - attribute <- as.factor(attribute) - } - same <- outer(attribute, attribute, "==") - nInternal <- sum(m * same, na.rm = TRUE) - nExternal <- sum(m, na.rm = TRUE) - nInternal - ei <- (nExternal - nInternal) / sum(m, na.rm = TRUE) - make_network_measure(ei, .data) -} - -#' @rdname heterogeneity -#' @examples -#' node_heterophily(marvel_friends, "Gender") -#' node_heterophily(marvel_friends, "Attractive") -#' @export -node_heterophily <- function(.data, attribute){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - m <- manynet::as_matrix(.data) - if (length(attribute) == 1 && is.character(attribute)) { - attribute <- manynet::node_attribute(.data, attribute) - } - if (is.character(attribute) | is.numeric(attribute)) { - attribute <- as.factor(attribute) - } - if(anyNA(attribute)){ - m[is.na(attribute),] <- NA - m[,is.na(attribute)] <- NA - } - same <- outer(attribute, attribute, "==") - nInternal <- rowSums(m * same, na.rm = TRUE) - nInternal[is.na(attribute)] <- NA - nExternal <- rowSums(m, na.rm = TRUE) - nInternal - ei <- (nExternal - nInternal) / rowSums(m, na.rm = TRUE) - make_node_measure(ei, .data) -} - -#' @rdname heterogeneity -#' @importFrom igraph assortativity_degree -#' @examples -#' network_assortativity(mpn_elite_mex) -#' @export -network_assortativity <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - make_network_measure(igraph::assortativity_degree(manynet::as_igraph(.data), - directed = manynet::is_directed(.data)), - .data) -} - -#' @rdname heterogeneity -#' @references -#' Moran, Patrick Alfred Pierce. 1950. -#' "Notes on Continuous Stochastic Phenomena". -#' _Biometrika_ 37(1): 17-23. -#' \doi{10.2307/2332142} -#' @examples -#' network_spatial(ison_lawfirm, "age") -#' @export -network_spatial <- function(.data, attribute){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - N <- manynet::network_nodes(.data) - x <- manynet::node_attribute(.data, attribute) - stopifnot(is.numeric(x)) - x_bar <- mean(x, na.rm = TRUE) - w <- manynet::as_matrix(.data) - W <- sum(w, na.rm = TRUE) - I <- (N/W) * - (sum(w * matrix(x - x_bar, N, N) * matrix(x - x_bar, N, N, byrow = TRUE)) / - sum((x - x_bar)^2)) - make_network_measure(I, .data) -} diff --git a/man/heterogeneity.Rd b/man/heterogeneity.Rd deleted file mode 100644 index 69d0c891..00000000 --- a/man/heterogeneity.Rd +++ /dev/null @@ -1,141 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_heterogeneity.R -\name{heterogeneity} -\alias{heterogeneity} -\alias{network_richness} -\alias{node_richness} -\alias{network_diversity} -\alias{node_diversity} -\alias{network_heterophily} -\alias{node_heterophily} -\alias{network_assortativity} -\alias{network_spatial} -\title{Measures of network diversity} -\usage{ -network_richness(.data, attribute) - -node_richness(.data, attribute) - -network_diversity(.data, attribute, clusters = NULL) - -node_diversity(.data, attribute) - -network_heterophily(.data, attribute) - -node_heterophily(.data, attribute) - -network_assortativity(.data) - -network_spatial(.data, attribute) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{attribute}{Name of a nodal attribute or membership vector -to use as categories for the diversity measure.} - -\item{clusters}{A nodal cluster membership vector or name of a vertex attribute.} -} -\description{ -These functions offer ways to summarise the heterogeneity of an attribute -across a network, within groups of a network, or the distribution of ties -across this attribute: -\itemize{ -\item \code{network_richness()} measures the number of unique categories -in a network attribute. -\item \code{node_richness()} measures the number of unique categories -of an attribute to which each node is connected. -\item \code{network_diversity()} measures the heterogeneity of ties across a network -or within clusters by node attributes. -\item \code{node_diversity()} measures the heterogeneity of each node's -local neighbourhood. -\item \code{network_heterophily()} measures how embedded nodes in the network -are within groups of nodes with the same attribute. -\item \code{node_heterophily()} measures each node's embeddedness within groups -of nodes with the same attribute. -\item \code{network_assortativity()} measures the degree assortativity in a network. -\item \code{network_spatial()} measures the spatial association/autocorrelation ( -global Moran's I) in a network. -} -} -\section{network_diversity}{ - -Blau's index (1977) uses a formula known also in other disciplines -by other names -(Gini-Simpson Index, Gini impurity, Gini's diversity index, -Gibbs-Martin index, and probability of interspecific encounter (PIE)): -\deqn{1 - \sum\limits_{i = 1}^k {p_i^2 }}, -where \eqn{p_i} is the proportion of group members in \eqn{i}th category -and \eqn{k} is the number of categories for an attribute of interest. -This index can be interpreted as the probability that two members -randomly selected from a group would be from different categories. -This index finds its minimum value (0) when there is no variety, -i.e. when all individuals are classified in the same category. -The maximum value depends on the number of categories and -whether nodes can be evenly distributed across categories. -} - -\section{network_homophily}{ - -Given a partition of a network into a number of mutually exclusive groups then -The E-I index is the number of ties between (or \emph{external}) nodes -grouped in some mutually exclusive categories -minus the number of ties within (or \emph{internal}) these groups -divided by the total number of ties. -This value can range from 1 to -1, -where 1 indicates ties only between categories/groups and -1 ties only within categories/groups. -} - -\examples{ -network_richness(mpn_bristol) -node_richness(mpn_bristol, "type") -marvel_friends <- manynet::to_unsigned(manynet::ison_marvel_relationships, "positive") -network_diversity(marvel_friends, "Gender") -network_diversity(marvel_friends, "Attractive") -network_diversity(marvel_friends, "Gender", "Rich") -node_diversity(marvel_friends, "Gender") -node_diversity(marvel_friends, "Attractive") -network_heterophily(marvel_friends, "Gender") -network_heterophily(marvel_friends, "Attractive") -node_heterophily(marvel_friends, "Gender") -node_heterophily(marvel_friends, "Attractive") -network_assortativity(mpn_elite_mex) -network_spatial(ison_lawfirm, "age") -} -\references{ -Blau, Peter M. (1977). -\emph{Inequality and heterogeneity}. -New York: Free Press. - -Krackhardt, David and Robert N. Stern (1988). -Informal networks and organizational crises: an experimental simulation. -\emph{Social Psychology Quarterly} 51(2), 123-140. - -Moran, Patrick Alfred Pierce. 1950. -"Notes on Continuous Stochastic Phenomena". -\emph{Biometrika} 37(1): 17-23. -\doi{10.2307/2332142} -} -\seealso{ -Other measures: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{closure}}, -\code{\link{cohesion}()}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}}, -\code{\link{features}}, -\code{\link{hierarchy}}, -\code{\link{holes}}, -\code{\link{net_diffusion}}, -\code{\link{node_diffusion}}, -\code{\link{periods}} -} -\concept{measures} From 56f8ae318d0bc93e7bc1f2a671aa0b948745cb4f Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:19:31 +0200 Subject: [PATCH 61/97] Migrated hierarchy measures to manynet --- R/measure_hierarchy.R | 69 ------------------------------------------- man/hierarchy.Rd | 69 ------------------------------------------- 2 files changed, 138 deletions(-) delete mode 100644 R/measure_hierarchy.R delete mode 100644 man/hierarchy.Rd diff --git a/R/measure_hierarchy.R b/R/measure_hierarchy.R deleted file mode 100644 index f698ccfd..00000000 --- a/R/measure_hierarchy.R +++ /dev/null @@ -1,69 +0,0 @@ -#' Graph theoretic dimensions of hierarchy -#' -#' @description -#' These functions, together with `network_reciprocity()`, are used jointly to -#' measure how hierarchical a network is: -#' -#' - `network_connectedness()` measures the proportion of dyads in the network -#' that are reachable to one another, -#' or the degree to which network is a single component. -#' - `network_efficiency()` measures the Krackhardt efficiency score. -#' - `network_upperbound()` measures the Krackhardt (least) upper bound score. -#' -#' @inheritParams cohesion -#' @name hierarchy -#' @family measures -#' @references -#' Krackhardt, David. 1994. -#' Graph theoretical dimensions of informal organizations. -#' In Carley and Prietula (eds) _Computational Organizational Theory_, -#' Hillsdale, NJ: Lawrence Erlbaum Associates. Pp. 89-111. -#' -#' Everett, Martin, and David Krackhardt. 2012. -#' “A second look at Krackhardt's graph theoretical dimensions of informal organizations.” -#' _Social Networks_, 34: 159-163. -#' \doi{10.1016/j.socnet.2011.10.006} -#' @examples -#' network_connectedness(ison_networkers) -#' 1 - network_reciprocity(ison_networkers) -#' network_efficiency(ison_networkers) -#' network_upperbound(ison_networkers) -NULL - -#' @rdname hierarchy -#' @export -network_connectedness <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - dists <- igraph::distances(manynet::as_igraph(.data)) - make_network_measure(1 - sum(dists==Inf)/sum(dists!=0), - .data) -} - -#' @rdname hierarchy -#' @export -network_efficiency <- function(.data) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - degs <- node_indegree(.data, normalized = FALSE) - out <- (manynet::network_nodes(.data)-1)/sum(degs) - make_network_measure(out, .data) -} - -#' @rdname hierarchy -#' @export -network_upperbound <- function(.data) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - dists <- igraph::distances(.data, mode = "in") - dists[is.infinite(dists)] <- 0 - dists <- dists[order(rowSums(dists)), order(rowSums(dists))] - if (max(colSums(dists > 0)) / (manynet::network_nodes(.data)-1) == 1){ - out <- 1 - } else { - out <- apply(utils::combn(2:nrow(dists), 2), 2, - function(x){ - ubs <- dists[x,]>0 - any(ubs[1,]*ubs[2,]==1) - }) - out <- sum(out)/length(out) - } - make_network_measure(out, .data) -} \ No newline at end of file diff --git a/man/hierarchy.Rd b/man/hierarchy.Rd deleted file mode 100644 index a54247f8..00000000 --- a/man/hierarchy.Rd +++ /dev/null @@ -1,69 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_hierarchy.R -\name{hierarchy} -\alias{hierarchy} -\alias{network_connectedness} -\alias{network_efficiency} -\alias{network_upperbound} -\title{Graph theoretic dimensions of hierarchy} -\usage{ -network_connectedness(.data) - -network_efficiency(.data) - -network_upperbound(.data) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} -} -\description{ -These functions, together with \code{network_reciprocity()}, are used jointly to -measure how hierarchical a network is: -\itemize{ -\item \code{network_connectedness()} measures the proportion of dyads in the network -that are reachable to one another, -or the degree to which network is a single component. -\item \code{network_efficiency()} measures the Krackhardt efficiency score. -\item \code{network_upperbound()} measures the Krackhardt (least) upper bound score. -} -} -\examples{ -network_connectedness(ison_networkers) -1 - network_reciprocity(ison_networkers) -network_efficiency(ison_networkers) -network_upperbound(ison_networkers) -} -\references{ -Krackhardt, David. 1994. -Graph theoretical dimensions of informal organizations. -In Carley and Prietula (eds) \emph{Computational Organizational Theory}, -Hillsdale, NJ: Lawrence Erlbaum Associates. Pp. 89-111. - -Everett, Martin, and David Krackhardt. 2012. -“A second look at Krackhardt's graph theoretical dimensions of informal organizations.” -\emph{Social Networks}, 34: 159-163. -\doi{10.1016/j.socnet.2011.10.006} -} -\seealso{ -Other measures: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{closure}}, -\code{\link{cohesion}()}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}}, -\code{\link{features}}, -\code{\link{heterogeneity}}, -\code{\link{holes}}, -\code{\link{net_diffusion}}, -\code{\link{node_diffusion}}, -\code{\link{periods}} -} -\concept{measures} From 08369d728d38a8f8c4c424e3b0a96c9760bbcaa2 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:19:45 +0200 Subject: [PATCH 62/97] Migrated diffusion measures to manynet --- R/measure_diffusion.R | 406 ------------------------------------------ man/net_diffusion.Rd | 206 --------------------- man/node_diffusion.Rd | 155 ---------------- 3 files changed, 767 deletions(-) delete mode 100644 R/measure_diffusion.R delete mode 100644 man/net_diffusion.Rd delete mode 100644 man/node_diffusion.Rd diff --git a/R/measure_diffusion.R b/R/measure_diffusion.R deleted file mode 100644 index dc49f32a..00000000 --- a/R/measure_diffusion.R +++ /dev/null @@ -1,406 +0,0 @@ -# net_diffusion #### - -#' Measures of network diffusion -#' @description -#' These functions allow measurement of various features of -#' a diffusion process: -#' -#' - `network_transmissibility()` measures the average transmissibility observed -#' in a diffusion simulation, or the number of new infections over -#' the number of susceptible nodes. -#' - `network_infection_length()` measures the average number of time steps -#' nodes remain infected once they become infected. -#' - `network_reproduction()` measures the observed reproductive number -#' in a diffusion simulation as the network's transmissibility over -#' the network's average infection length. -#' - `network_immunity()` measures the proportion of nodes that would need -#' to be protected through vaccination, isolation, or recovery for herd immunity to be reached. -#' - `network_hazard()` measures the hazard rate or instantaneous probability that -#' nodes will adopt/become infected at that time -#' -#' @param diff_model A valid network diffusion model, -#' as created by `as_diffusion()` or `play_diffusion()`. -#' @family measures -#' @family diffusion -#' @name net_diffusion -#' @examples -#' smeg <- manynet::generate_smallworld(15, 0.025) -#' smeg_diff <- play_diffusion(smeg, recovery = 0.2) -#' plot(smeg_diff) -#' @references -#' Kermack, W. and McKendrick, A., 1927. "A contribution to the mathematical theory of epidemics". -#' _Proc. R. Soc. London A_ 115: 700-721. -NULL - -#' @rdname net_diffusion -#' @section Transmissibility: -#' `network_transmissibility()` measures how many directly susceptible nodes -#' each infected node will infect in each time period, on average. -#' That is: -#' \deqn{T = \frac{1}{n}\sum_{j=1}^n \frac{i_{j}}{s_{j}}} -#' where \eqn{i} is the number of new infections in each time period, \eqn{j \in n}, -#' and \eqn{s} is the number of nodes that could have been infected in that time period -#' (note that \eqn{s \neq S}, or -#' the number of nodes that are susceptible in the population). -#' \eqn{T} can be interpreted as the proportion of susceptible nodes that are -#' infected at each time period. -#' @examples -#' # To calculate the average transmissibility for a given diffusion model -#' network_transmissibility(smeg_diff) -#' @export -network_transmissibility <- function(diff_model){ - out <- diff_model$I_new/diff_model$s - out <- out[-1] - out <- out[!is.infinite(out)] - out <- out[!is.nan(out)] - make_network_measure(mean(out, na.rm = TRUE), - attr(diff_model, "network")) -} - -#' @rdname net_diffusion -#' @section Infection length: -#' `network_infection_length()` measures the average number of time steps that -#' nodes in a network remain infected. -#' Note that in a diffusion model without recovery, average infection length -#' will be infinite. -#' This will also be the case where there is right censoring. -#' The longer nodes remain infected, the longer they can infect others. -#' @examples -#' # To calculate the average infection length for a given diffusion model -#' network_infection_length(smeg_diff) -#' @export -network_infection_length <- function(diff_model){ - make_network_measure(mean(node_infection_length(diff_model), na.rm = TRUE), - attr(diff_model, "network")) -} - -#' @rdname net_diffusion -#' @section Reproduction number: -#' `network_reproduction()` measures a given diffusion's reproductive number. -#' Here it is calculated as: -#' \deqn{R = \min\left(\frac{T}{1/IL}, \bar{k}\right)} -#' where \eqn{T} is the observed transmissibility in a diffusion -#' and \eqn{IL} is the observed infection length in a diffusion. -#' Since \eqn{IL} can be infinite where there is no recovery -#' or there is right censoring, -#' and since network structure places an upper limit on how many -#' nodes each node may further infect (their degree), -#' this function returns the minimum of \eqn{R_0} -#' and the network's average degree. -#' -#' Interpretation of the reproduction number is oriented around R = 1. -#' Where \eqn{R > 1}, the 'disease' will 'infect' more and more -#' nodes in the network. -#' Where \eqn{R < 1}, the 'disease' will not sustain itself and eventually -#' die out. -#' Where \eqn{R = 1}, the 'disease' will continue as endemic, -#' if conditions allow. -#' @examples -#' # To calculate the reproduction number for a given diffusion model -#' network_reproduction(smeg_diff) -#' @export -network_reproduction <- function(diff_model){ - net <- attr(diff_model, "network") - out <- network_transmissibility(diff_model)/ - (1/network_infection_length(diff_model)) - out <- min(out, mean(node_degree(net, normalized = FALSE))) - make_network_measure(out, net) -} - -#' @rdname net_diffusion -#' @section Herd immunity: -#' `network_immunity()` estimates the proportion of a network -#' that need to be protected from infection for herd immunity -#' to be achieved. -#' This is known as the Herd Immunity Threshold or HIT: -#' \deqn{1 - \frac{1}{R}} -#' where \eqn{R} is the reproduction number from `network_reproduction()`. -#' The HIT indicates the threshold at which -#' the reduction of susceptible members of the network means -#' that infections will no longer keep increasing. -#' Note that there may still be more infections after this threshold has been reached, -#' but there should be fewer and fewer. -#' These excess infections are called the _overshoot_. -#' This function does _not_ take into account the structure -#' of the network, instead using the average degree. -#' -#' Interpretation is quite straightforward. -#' A HIT or immunity score of 0.75 would mean that 75% of the nodes in the network -#' would need to be vaccinated or otherwise protected to achieve herd immunity. -#' To identify how many nodes this would be, multiply this proportion with the number -#' of nodes in the network. -#' @examples -#' # Calculating the proportion required to achieve herd immunity -#' network_immunity(smeg_diff) -#' # To find the number of nodes to be vaccinated -#' ceiling(network_immunity(smeg_diff) * manynet::network_nodes(smeg)) -#' @export -network_immunity <- function(diff_model){ - net <- attr(diff_model, "network") - out <- 1 - 1/network_reproduction(diff_model) - make_network_measure(out, net) -} - -#' @rdname net_diffusion -#' @section Hazard rate: -#' The hazard rate is the instantaneous probability of adoption/infection at each time point (Allison 1984). -#' In survival analysis, hazard rate is formally defined as: -#' -#' \deqn{% -#' \lambda(t)=\lim_{h\to +0}\frac{F(t+h)-F(t)}{h}\frac{1}{1-F(t)} % -#' }{% -#' \lambda(t-1)= lim (t -> +0) [F(t+h)-F(t)]/h * 1/[1-F(t)] % -#' } -#' -#' By approximating \eqn{h=1}, we can rewrite the equation as -#' -#' \deqn{% -#' \lambda(t)=\frac{F(t+1)-F(t)}{1-F(t)} % -#' }{% -#' \lambda(t-1)= [F(t+1)-F(t)]/[1-F(t)] % -#' } -#' -#' If we estimate \eqn{F(t)}, -#' the probability of not having adopted the innovation in time \eqn{t}, -#' from the proportion of adopters in that time, -#' such that \eqn{F(t) \sim q_t/n}{F(t) ~ q(t)/n}, we now have (ultimately for \eqn{t>1}): -#' -#' \deqn{% -#' \lambda(t)=\frac{q_{t+1}/n-q_t/n}{1-q_t/n} = \frac{q_{t+1} - q_t}{n - q_t} = \frac{q_t - q_{t-1}}{n - q_{t-1}} % -#' }{% -#' \lambda(t-1)= [q(t+1)/n-q(t)/n]/[1-q(t)/n] = [q(t+1) - q(t)]/[n - q(t)] = [q(t) - q(t-1)]/[n - q(t-1)] % -#' } -#' -#' where \eqn{q_i}{q(i)} is the number of adopters in time \eqn{t}, -#' and \eqn{n} is the number of vertices in the graph. -#' -#' The shape of the hazard rate indicates the pattern of new adopters over time. -#' Rapid diffusion with convex cumulative adoption curves will have -#' hazard functions that peak early and decay over time. -#' Slow concave cumulative adoption curves will have -#' hazard functions that are low early and rise over time. -#' Smooth hazard curves indicate constant adoption whereas -#' those that oscillate indicate variability in adoption behavior over time. -#' @source `{netdiffuseR}` -#' @references -#' Allison, P. 1984. _Event history analysis regression for longitudinal event data_. -#' London: Sage Publications. -#' -#' Wooldridge, J. M. 2010. _Econometric Analysis of Cross Section and Panel Data_ (2nd ed.). -#' Cambridge: MIT Press. -#' @examples -#' # To calculate the hazard rates at each time point -#' network_hazard(play_diffusion(smeg, transmissibility = 0.3)) -#' @export -network_hazard <- function(diff_model){ - out <- (diff_model$I - dplyr::lag(diff_model$I)) / - (diff_model$n - dplyr::lag(diff_model$I)) - out -} - -# node_diffusion #### - -#' Measures of nodes in a diffusion -#' @description -#' These functions allow measurement of various features of -#' a diffusion process: -#' -#' - `node_adoption_time()`: Measures the number of time steps until -#' nodes adopt/become infected -#' - `node_adopter()`: Classifies membership of nodes into diffusion categories -#' - `node_thresholds()`: Measures nodes' thresholds from the amount -#' of exposure they had when they became infected -#' - `node_infection_length()`: Measures the average length nodes that become -#' infected remain infected in a compartmental model with recovery -#' - `node_exposure()`: Measures how many exposures nodes have to -#' a given mark -#' - `node_is_exposed()`: Marks the nodes that are susceptible, -#' i.e. are in the immediate neighbourhood of given mark vector -#' -#' @inheritParams cohesion -#' @inheritParams net_diffusion -#' @family measures -#' @family diffusion -#' @name node_diffusion -#' @examples -#' smeg <- manynet::generate_smallworld(15, 0.025) -#' smeg_diff <- play_diffusion(smeg, recovery = 0.2) -#' plot(smeg_diff) -#' @references -#' Valente, Tom W. 1995. _Network models of the diffusion of innovations_ -#' (2nd ed.). Cresskill N.J.: Hampton Press. -NULL - -#' @rdname node_diffusion -#' @section Adoption time: -#' `node_adoption_time()` measures the time units it took -#' until each node became infected. -#' Note that an adoption time of 0 indicates that this was a seed node. -#' @examples -#' # To measure when nodes adopted a diffusion/were infected -#' (times <- node_adoption_time(smeg_diff)) -#' @export -node_adoption_time <- function(diff_model){ - event <- nodes <- NULL - out <- summary(diff_model) |> dplyr::filter(event == "I") |> - dplyr::distinct(nodes, .keep_all = TRUE) |> - dplyr::select(nodes,t) - net <- attr(diff_model, "network") - if(!manynet::is_labelled(net)) - out <- dplyr::arrange(out, nodes) else if (is.numeric(out$nodes)) - out$nodes <- manynet::node_names(net)[out$nodes] - out <- stats::setNames(out$t, out$nodes) - if(length(out) != manynet::network_nodes(net)){ - full <- rep(Inf, manynet::network_nodes(net)) - names(full) <- `if`(manynet::is_labelled(net), - manynet::node_names(net), - as.character(seq_len(manynet::network_nodes(net)))) - full[match(names(out), names(full))] <- out - out <- `if`(manynet::is_labelled(net), full, unname(full)) - } - if(!manynet::is_labelled(net)) out <- unname(out) - make_node_measure(out, net) -} - -#' @rdname node_diffusion -#' @section Adopter class: -#' `node_adopter()` classifies the nodes involved in a diffusion -#' by where on the distribution of adopters they fell. -#' Valente (1995) defines five memberships: -#' -#' - _Early adopter_: those with an adoption time less than -#' the average adoption time minus one standard deviation of adoptions times -#' - _Early majority_: those with an adoption time between -#' the average adoption time and -#' the average adoption time minus one standard deviation of adoptions times -#' - _Late majority_: those with an adoption time between -#' the average adoption time and -#' the average adoption time plus one standard deviation of adoptions times -#' - _Laggard_: those with an adoption time greater than -#' the average adoption time plus one standard deviation of adoptions times -#' - _Non-adopter_: those without an adoption time, -#' i.e. never adopted -#' @examples -#' # To classify nodes by their position in the adoption curve -#' (adopts <- node_adopter(smeg_diff)) -#' summary(adopts) -#' summary(times, membership = adopts) -#' @export -node_adopter <- function(diff_model){ - toa <- node_adoption_time(diff_model) - toa[is.infinite(toa)] <- NA - avg <- mean(toa, na.rm = TRUE) - sdv <- stats::sd(toa, na.rm = TRUE) - out <- ifelse(toa < (avg - sdv) | toa == 0, "Early Adopter", - ifelse(toa > (avg + sdv), "Laggard", - ifelse((avg - sdv) < toa & toa <= avg, "Early Majority", - ifelse(avg < toa & toa <= avg + sdv, "Late Majority", - "Non-Adopter")))) - out[is.na(out)] <- "Non-Adopter" - make_node_member(out, attr(diff_model, "network")) -} - -#' @rdname node_diffusion -#' @section Thresholds: -#' `node_thresholds()` infers nodes' thresholds based on how much -#' exposure they had when they were infected. -#' This inference is of course imperfect, -#' especially where there is a sudden increase in exposure, -#' but it can be used heuristically. -#' @examples -#' # To infer nodes' thresholds -#' node_thresholds(smeg_diff) -#' @export -node_thresholds <- function(diff_model){ - event <- nodes <- NULL - exposure <- NULL - out <- summary(diff_model) - net <- attr(diff_model, "network") - if(!"exposure" %in% names(out)){ - out[,'exposure'] <- NA_integer_ - for(v in unique(out$t)){ - out$exposure[out$t == v] <- node_exposure(diff_model, time = v)[out$nodes[out$t == v]] - } - } - if(any(out$event == "E")) - out <- out |> dplyr::filter(event == "E") else - out <- out |> dplyr::filter(event == "I") - out <- out |> dplyr::distinct(nodes, .keep_all = TRUE) |> - dplyr::select(nodes, exposure) - out <- stats::setNames(out$exposure, out$nodes) - if(length(out) != manynet::network_nodes(net)){ - full <- stats::setNames(rep(Inf, manynet::network_nodes(net)), - manynet::node_names(net)) - full[match(names(out), names(full))] <- out - out <- full - } - make_node_measure(out, net) -} - -#' @rdname node_diffusion -#' @section Infection length: -#' `node_infection_length()` measures the average length of time that nodes -#' that become infected remain infected in a compartmental model with recovery. -#' Infections that are not concluded by the end of the study period are -#' calculated as infinite. -#' @examples -#' # To measure how long each node remains infected for -#' node_infection_length(smeg_diff) -#' @export -node_infection_length <- function(diff_model){ - nodes <- NULL - events <- attr(diff_model, "events") - out <- vapply(seq_len(diff_model$n[1]), - function(x) ifelse("I" %in% dplyr::filter(events, nodes == x)$event, - ifelse("R" %in% dplyr::filter(events, nodes == x)$event, - mean(diff(dplyr::filter(events, nodes == x)$t)), - Inf), - NA), - FUN.VALUE = numeric(1)) - make_node_measure(out, attr(diff_model, "network")) -} - -#' @rdname node_diffusion -#' @param mark A valid 'node_mark' object or -#' logical vector (TRUE/FALSE) of length equal to -#' the number of nodes in the network. -#' @param time A time point until which infections/adoptions should be -#' identified. By default `time = 0`. -#' @section Exposure: -#' `node_exposure()` calculates the number of infected/adopting nodes -#' to which each susceptible node is exposed. -#' It usually expects network data and -#' an index or mark (TRUE/FALSE) vector of those nodes which are currently infected, -#' but if a diff_model is supplied instead it will return -#' nodes exposure at \eqn{t = 0}. -#' @examples -#' # To measure how much exposure nodes have to a given mark -#' node_exposure(smeg, mark = c(1,3)) -#' node_exposure(smeg_diff) -#' @export -node_exposure <- function(.data, mark, time = 0){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(missing(mark) && inherits(.data, "diff_model")){ - mark <- manynet::node_is_infected(.data, time = time) - .data <- attr(.data, "network") - } - .data <- manynet::as_tidygraph(.data) - if(manynet::is_weighted(.data)){ - if(is.numeric(mark)){ - mk <- rep(FALSE, manynet::network_nodes(.data)) - mk[mark] <- TRUE - } - out <- manynet::as_matrix(.data) - out <- colSums(out * matrix(mk, nrow(out), ncol(out)) * - matrix(!mk, nrow(out), ncol(out), byrow = TRUE)) - } else { - if(is.logical(mark)) mark <- which(mark) - contacts <- unlist(lapply(igraph::neighborhood(.data, nodes = mark), - function(x) setdiff(x, mark))) - # count exposures for each node: - tabcontact <- table(contacts) - out <- rep(0, manynet::network_nodes(.data)) - out[as.numeric(names(tabcontact))] <- unname(tabcontact) - } - make_node_measure(out, .data) -} diff --git a/man/net_diffusion.Rd b/man/net_diffusion.Rd deleted file mode 100644 index 2f130e62..00000000 --- a/man/net_diffusion.Rd +++ /dev/null @@ -1,206 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_diffusion.R -\name{net_diffusion} -\alias{net_diffusion} -\alias{network_transmissibility} -\alias{network_infection_length} -\alias{network_reproduction} -\alias{network_immunity} -\alias{network_hazard} -\title{Measures of network diffusion} -\source{ -\code{{netdiffuseR}} -} -\usage{ -network_transmissibility(diff_model) - -network_infection_length(diff_model) - -network_reproduction(diff_model) - -network_immunity(diff_model) - -network_hazard(diff_model) -} -\arguments{ -\item{diff_model}{A valid network diffusion model, -as created by \code{as_diffusion()} or \code{play_diffusion()}.} -} -\description{ -These functions allow measurement of various features of -a diffusion process: -\itemize{ -\item \code{network_transmissibility()} measures the average transmissibility observed -in a diffusion simulation, or the number of new infections over -the number of susceptible nodes. -\item \code{network_infection_length()} measures the average number of time steps -nodes remain infected once they become infected. -\item \code{network_reproduction()} measures the observed reproductive number -in a diffusion simulation as the network's transmissibility over -the network's average infection length. -\item \code{network_immunity()} measures the proportion of nodes that would need -to be protected through vaccination, isolation, or recovery for herd immunity to be reached. -\item \code{network_hazard()} measures the hazard rate or instantaneous probability that -nodes will adopt/become infected at that time -} -} -\section{Transmissibility}{ - -\code{network_transmissibility()} measures how many directly susceptible nodes -each infected node will infect in each time period, on average. -That is: -\deqn{T = \frac{1}{n}\sum_{j=1}^n \frac{i_{j}}{s_{j}}} -where \eqn{i} is the number of new infections in each time period, \eqn{j \in n}, -and \eqn{s} is the number of nodes that could have been infected in that time period -(note that \eqn{s \neq S}, or -the number of nodes that are susceptible in the population). -\eqn{T} can be interpreted as the proportion of susceptible nodes that are -infected at each time period. -} - -\section{Infection length}{ - -\code{network_infection_length()} measures the average number of time steps that -nodes in a network remain infected. -Note that in a diffusion model without recovery, average infection length -will be infinite. -This will also be the case where there is right censoring. -The longer nodes remain infected, the longer they can infect others. -} - -\section{Reproduction number}{ - -\code{network_reproduction()} measures a given diffusion's reproductive number. -Here it is calculated as: -\deqn{R = \min\left(\frac{T}{1/IL}, \bar{k}\right)} -where \eqn{T} is the observed transmissibility in a diffusion -and \eqn{IL} is the observed infection length in a diffusion. -Since \eqn{IL} can be infinite where there is no recovery -or there is right censoring, -and since network structure places an upper limit on how many -nodes each node may further infect (their degree), -this function returns the minimum of \eqn{R_0} -and the network's average degree. - -Interpretation of the reproduction number is oriented around R = 1. -Where \eqn{R > 1}, the 'disease' will 'infect' more and more -nodes in the network. -Where \eqn{R < 1}, the 'disease' will not sustain itself and eventually -die out. -Where \eqn{R = 1}, the 'disease' will continue as endemic, -if conditions allow. -} - -\section{Herd immunity}{ - -\code{network_immunity()} estimates the proportion of a network -that need to be protected from infection for herd immunity -to be achieved. -This is known as the Herd Immunity Threshold or HIT: -\deqn{1 - \frac{1}{R}} -where \eqn{R} is the reproduction number from \code{network_reproduction()}. -The HIT indicates the threshold at which -the reduction of susceptible members of the network means -that infections will no longer keep increasing. -Note that there may still be more infections after this threshold has been reached, -but there should be fewer and fewer. -These excess infections are called the \emph{overshoot}. -This function does \emph{not} take into account the structure -of the network, instead using the average degree. - -Interpretation is quite straightforward. -A HIT or immunity score of 0.75 would mean that 75\% of the nodes in the network -would need to be vaccinated or otherwise protected to achieve herd immunity. -To identify how many nodes this would be, multiply this proportion with the number -of nodes in the network. -} - -\section{Hazard rate}{ - -The hazard rate is the instantaneous probability of adoption/infection at each time point (Allison 1984). -In survival analysis, hazard rate is formally defined as: - -\deqn{% -\lambda(t)=\lim_{h\to +0}\frac{F(t+h)-F(t)}{h}\frac{1}{1-F(t)} % -}{% -\lambda(t-1)= lim (t -> +0) [F(t+h)-F(t)]/h * 1/[1-F(t)] % -} - -By approximating \eqn{h=1}, we can rewrite the equation as - -\deqn{% -\lambda(t)=\frac{F(t+1)-F(t)}{1-F(t)} % -}{% -\lambda(t-1)= [F(t+1)-F(t)]/[1-F(t)] % -} - -If we estimate \eqn{F(t)}, -the probability of not having adopted the innovation in time \eqn{t}, -from the proportion of adopters in that time, -such that \eqn{F(t) \sim q_t/n}{F(t) ~ q(t)/n}, we now have (ultimately for \eqn{t>1}): - -\deqn{% -\lambda(t)=\frac{q_{t+1}/n-q_t/n}{1-q_t/n} = \frac{q_{t+1} - q_t}{n - q_t} = \frac{q_t - q_{t-1}}{n - q_{t-1}} % -}{% -\lambda(t-1)= [q(t+1)/n-q(t)/n]/[1-q(t)/n] = [q(t+1) - q(t)]/[n - q(t)] = [q(t) - q(t-1)]/[n - q(t-1)] % -} - -where \eqn{q_i}{q(i)} is the number of adopters in time \eqn{t}, -and \eqn{n} is the number of vertices in the graph. - -The shape of the hazard rate indicates the pattern of new adopters over time. -Rapid diffusion with convex cumulative adoption curves will have -hazard functions that peak early and decay over time. -Slow concave cumulative adoption curves will have -hazard functions that are low early and rise over time. -Smooth hazard curves indicate constant adoption whereas -those that oscillate indicate variability in adoption behavior over time. -} - -\examples{ - smeg <- manynet::generate_smallworld(15, 0.025) - smeg_diff <- play_diffusion(smeg, recovery = 0.2) - plot(smeg_diff) - # To calculate the average transmissibility for a given diffusion model - network_transmissibility(smeg_diff) - # To calculate the average infection length for a given diffusion model - network_infection_length(smeg_diff) - # To calculate the reproduction number for a given diffusion model - network_reproduction(smeg_diff) - # Calculating the proportion required to achieve herd immunity - network_immunity(smeg_diff) - # To find the number of nodes to be vaccinated - ceiling(network_immunity(smeg_diff) * manynet::network_nodes(smeg)) -# To calculate the hazard rates at each time point -network_hazard(play_diffusion(smeg, transmissibility = 0.3)) -} -\references{ -Kermack, W. and McKendrick, A., 1927. "A contribution to the mathematical theory of epidemics". -\emph{Proc. R. Soc. London A} 115: 700-721. - -Allison, P. 1984. \emph{Event history analysis regression for longitudinal event data}. -London: Sage Publications. - -Wooldridge, J. M. 2010. \emph{Econometric Analysis of Cross Section and Panel Data} (2nd ed.). -Cambridge: MIT Press. -} -\seealso{ -Other measures: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{closure}}, -\code{\link{cohesion}()}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}}, -\code{\link{features}}, -\code{\link{heterogeneity}}, -\code{\link{hierarchy}}, -\code{\link{holes}}, -\code{\link{node_diffusion}}, -\code{\link{periods}} - -Other diffusion: -\code{\link{node_diffusion}} -} -\concept{diffusion} -\concept{measures} diff --git a/man/node_diffusion.Rd b/man/node_diffusion.Rd deleted file mode 100644 index 2475f0af..00000000 --- a/man/node_diffusion.Rd +++ /dev/null @@ -1,155 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_diffusion.R -\name{node_diffusion} -\alias{node_diffusion} -\alias{node_adoption_time} -\alias{node_adopter} -\alias{node_thresholds} -\alias{node_infection_length} -\alias{node_exposure} -\title{Measures of nodes in a diffusion} -\usage{ -node_adoption_time(diff_model) - -node_adopter(diff_model) - -node_thresholds(diff_model) - -node_infection_length(diff_model) - -node_exposure(.data, mark, time = 0) -} -\arguments{ -\item{diff_model}{A valid network diffusion model, -as created by \code{as_diffusion()} or \code{play_diffusion()}.} - -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{mark}{A valid 'node_mark' object or -logical vector (TRUE/FALSE) of length equal to -the number of nodes in the network.} - -\item{time}{A time point until which infections/adoptions should be -identified. By default \code{time = 0}.} -} -\description{ -These functions allow measurement of various features of -a diffusion process: -\itemize{ -\item \code{node_adoption_time()}: Measures the number of time steps until -nodes adopt/become infected -\item \code{node_adopter()}: Classifies membership of nodes into diffusion categories -\item \code{node_thresholds()}: Measures nodes' thresholds from the amount -of exposure they had when they became infected -\item \code{node_infection_length()}: Measures the average length nodes that become -infected remain infected in a compartmental model with recovery -\item \code{node_exposure()}: Measures how many exposures nodes have to -a given mark -\item \code{node_is_exposed()}: Marks the nodes that are susceptible, -i.e. are in the immediate neighbourhood of given mark vector -} -} -\section{Adoption time}{ - -\code{node_adoption_time()} measures the time units it took -until each node became infected. -Note that an adoption time of 0 indicates that this was a seed node. -} - -\section{Adopter class}{ - -\code{node_adopter()} classifies the nodes involved in a diffusion -by where on the distribution of adopters they fell. -Valente (1995) defines five memberships: -\itemize{ -\item \emph{Early adopter}: those with an adoption time less than -the average adoption time minus one standard deviation of adoptions times -\item \emph{Early majority}: those with an adoption time between -the average adoption time and -the average adoption time minus one standard deviation of adoptions times -\item \emph{Late majority}: those with an adoption time between -the average adoption time and -the average adoption time plus one standard deviation of adoptions times -\item \emph{Laggard}: those with an adoption time greater than -the average adoption time plus one standard deviation of adoptions times -\item \emph{Non-adopter}: those without an adoption time, -i.e. never adopted -} -} - -\section{Thresholds}{ - -\code{node_thresholds()} infers nodes' thresholds based on how much -exposure they had when they were infected. -This inference is of course imperfect, -especially where there is a sudden increase in exposure, -but it can be used heuristically. -} - -\section{Infection length}{ - -\code{node_infection_length()} measures the average length of time that nodes -that become infected remain infected in a compartmental model with recovery. -Infections that are not concluded by the end of the study period are -calculated as infinite. -} - -\section{Exposure}{ - -\code{node_exposure()} calculates the number of infected/adopting nodes -to which each susceptible node is exposed. -It usually expects network data and -an index or mark (TRUE/FALSE) vector of those nodes which are currently infected, -but if a diff_model is supplied instead it will return -nodes exposure at \eqn{t = 0}. -} - -\examples{ - smeg <- manynet::generate_smallworld(15, 0.025) - smeg_diff <- play_diffusion(smeg, recovery = 0.2) - plot(smeg_diff) - # To measure when nodes adopted a diffusion/were infected - (times <- node_adoption_time(smeg_diff)) - # To classify nodes by their position in the adoption curve - (adopts <- node_adopter(smeg_diff)) - summary(adopts) - summary(times, membership = adopts) - # To infer nodes' thresholds - node_thresholds(smeg_diff) - # To measure how long each node remains infected for - node_infection_length(smeg_diff) - # To measure how much exposure nodes have to a given mark - node_exposure(smeg, mark = c(1,3)) - node_exposure(smeg_diff) -} -\references{ -Valente, Tom W. 1995. \emph{Network models of the diffusion of innovations} -(2nd ed.). Cresskill N.J.: Hampton Press. -} -\seealso{ -Other measures: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{closure}}, -\code{\link{cohesion}()}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}}, -\code{\link{features}}, -\code{\link{heterogeneity}}, -\code{\link{hierarchy}}, -\code{\link{holes}}, -\code{\link{net_diffusion}}, -\code{\link{periods}} - -Other diffusion: -\code{\link{net_diffusion}} -} -\concept{diffusion} -\concept{measures} From 7297417e0d23b7b2f0701373dc9ffc9496689c06 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:20:00 +0200 Subject: [PATCH 63/97] Migrated over_ to manynet --- R/measure_over.R | 40 --------------------------- man/over.Rd | 70 ------------------------------------------------ man/periods.Rd | 50 ---------------------------------- 3 files changed, 160 deletions(-) delete mode 100644 R/measure_over.R delete mode 100644 man/over.Rd delete mode 100644 man/periods.Rd diff --git a/R/measure_over.R b/R/measure_over.R deleted file mode 100644 index a66b2fbb..00000000 --- a/R/measure_over.R +++ /dev/null @@ -1,40 +0,0 @@ -#' Helper functions for measuring over splits of networks -#' @inheritParams regression -#' @param FUN A function to run over all splits. -#' @param ... Further arguments to be passed on to FUN. -#' @param attribute A string naming the attribute to be split upon. -#' @param slice Optionally, a vector of specific slices. -#' Otherwise all observed slices will be returned. -#' @name over -NULL - -#' @describeIn over Runs a function, e.g. a measure, -#' over waves of a panel network -#' @export -over_waves <- function(.data, FUN, ..., attribute = "wave", - strategy = "sequential", - verbose = FALSE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - oplan <- future::plan(strategy) - on.exit(future::plan(oplan), add = TRUE) - furrr::future_map_dbl(manynet::to_waves(.data, attribute), function(j) FUN(j, ...), - .progress = verbose, .options = furrr::furrr_options(seed = T)) -} - -#' @describeIn over Runs a function, e.g. a measure, -#' over time slices of a dynamic network -#' @export -over_time <- function(.data, FUN, ..., attribute = "time", - slice = NULL, - strategy = "sequential", - verbose = FALSE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - oplan <- future::plan(strategy) - on.exit(future::plan(oplan), add = TRUE) - out <- furrr::future_map_dbl(manynet::to_slices(.data, attribute, slice), - function(j) FUN(j, ...), - .progress = verbose, - .options = furrr::furrr_options(seed = T)) - make_network_measures(out, .data) -} - diff --git a/man/over.Rd b/man/over.Rd deleted file mode 100644 index fe5727c6..00000000 --- a/man/over.Rd +++ /dev/null @@ -1,70 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_over.R -\name{over} -\alias{over} -\alias{over_waves} -\alias{over_time} -\title{Helper functions for measuring over splits of networks} -\usage{ -over_waves( - .data, - FUN, - ..., - attribute = "wave", - strategy = "sequential", - verbose = FALSE -) - -over_time( - .data, - FUN, - ..., - attribute = "time", - slice = NULL, - strategy = "sequential", - verbose = FALSE -) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{FUN}{A function to run over all splits.} - -\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"}, -but if multiple cores available, -then \code{"multisession"} or \code{"multicore"} may be useful. -Generally this is useful only when \code{times} > 1000. -See \href{https://furrr.futureverse.org}{\code{{furrr}}} for more.} - -\item{verbose}{Whether the function should report on its progress. -By default FALSE. -See \href{https://progressr.futureverse.org}{\code{{progressr}}} for more.} - -\item{slice}{Optionally, a vector of specific slices. -Otherwise all observed slices will be returned.} -} -\description{ -Helper functions for measuring over splits of networks -} -\section{Functions}{ -\itemize{ -\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, -over time slices of a dynamic network - -}} diff --git a/man/periods.Rd b/man/periods.Rd deleted file mode 100644 index af0a08d9..00000000 --- a/man/periods.Rd +++ /dev/null @@ -1,50 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_features.R -\name{periods} -\alias{periods} -\alias{network_change} -\alias{network_stability} -\title{Measures of network change} -\usage{ -network_change(.data, object2) - -network_stability(.data, object2) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{object2}{A network object.} -} -\description{ -These functions measure certain topological features of networks: -\itemize{ -\item \code{network_change()} measures the Hamming distance between two or more networks. -\item \code{network_stability()} measures the Jaccard index of stability between two or more networks. -} - -These \verb{network_*()} functions return a numeric vector the length of the number -of networks minus one. E.g., the periods between waves. -} -\seealso{ -Other measures: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{closure}}, -\code{\link{cohesion}()}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}}, -\code{\link{features}}, -\code{\link{heterogeneity}}, -\code{\link{hierarchy}}, -\code{\link{holes}}, -\code{\link{net_diffusion}}, -\code{\link{node_diffusion}} -} -\concept{measures} From e756c77d3b5d5a71abb903bb9e6e3a5f49ca8ca5 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:20:14 +0200 Subject: [PATCH 64/97] Migrated holes measures to manynet --- R/measure_holes.R | 261 ---------------------------------------------- man/holes.Rd | 132 ----------------------- 2 files changed, 393 deletions(-) delete mode 100644 R/measure_holes.R delete mode 100644 man/holes.Rd diff --git a/R/measure_holes.R b/R/measure_holes.R deleted file mode 100644 index 093ed556..00000000 --- a/R/measure_holes.R +++ /dev/null @@ -1,261 +0,0 @@ -#' Measures of structural holes -#' -#' @description -#' These function provide different measures of the degree to which nodes -#' fill structural holes, as outlined in Burt (1992): -#' -#' - `node_bridges()` measures the sum of bridges to which each node -#' is adjacent. -#' - `node_redundancy()` measures the redundancy of each nodes' contacts. -#' - `node_effsize()` measures nodes' effective size. -#' - `node_efficiency()` measures nodes' efficiency. -#' - `node_constraint()` measures nodes' constraint scores for one-mode networks -#' according to Burt (1992) and for two-mode networks according to Hollway et al (2020). -#' - `node_hierarchy()` measures nodes' exposure to hierarchy, -#' where only one or two contacts are the source of closure. -#' - `node_eccentricity()` measures nodes' eccentricity or Koenig number, -#' a measure of farness based on number of links needed to reach -#' most distant node in the network. -#' - `node_neighbours_degree()` measures nodes' average nearest neighbors degree, -#' or \eqn{knn}, a measure of the type of local environment a node finds itself in -#' - `tie_cohesion()` measures the ratio between common neighbors to ties' -#' adjacent nodes and the total number of adjacent nodes, -#' where high values indicate ties' embeddedness in dense local environments -#' -#' Burt's theory holds that while those nodes embedded in dense clusters -#' of close connections are likely exposed to the same or similar ideas and information, -#' those who fill structural holes between two otherwise disconnected groups -#' can gain some comparative advantage from that position. -#' @details -#' A number of different ways of measuring these structural holes are available. -#' Note that we use Borgatti's reformulation for unweighted networks in -#' `node_redundancy()` and `node_effsize()`. -#' Redundancy is thus \eqn{\frac{2t}{n}}, -#' where \eqn{t} is the sum of ties and \eqn{n} the sum of nodes in each node's neighbourhood, -#' and effective size is calculated as \eqn{n - \frac{2t}{n}}. -#' Node efficiency is the node's effective size divided by its degree. -#' @name holes -#' @family measures -#' @references -#' Burt, Ronald S. 1992. -#' _Structural Holes: The Social Structure of Competition_. -#' Cambridge, MA: Harvard University Press. -#' @inheritParams cohesion -NULL - -#' @rdname holes -#' @examples -#' node_bridges(ison_adolescents) -#' node_bridges(ison_southern_women) -#' @export -node_bridges <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - g <- manynet::as_igraph(.data) - .inc <- NULL - out <- vapply(igraph::V(g), function(ego){ - length(igraph::E(g)[.inc(ego) & manynet::tie_is_bridge(g)==1]) - }, FUN.VALUE = numeric(1)) - make_node_measure(out, .data) -} - -#' @rdname holes -#' @references -#' Borgatti, Steven. 1997. -#' “\href{http://www.analytictech.com/connections/v20(1)/holes.htm}{Structural Holes: Unpacking Burt’s Redundancy Measures}” -#' _Connections_ 20(1):35-38. -#' -#' Burchard, Jake, and Benjamin Cornwell. 2018. -#' “Structural Holes and Bridging in Two-Mode Networks.” -#' _Social Networks_ 55:11–20. -#' \doi{10.1016/j.socnet.2018.04.001} -#' @examples -#' node_redundancy(ison_adolescents) -#' node_redundancy(ison_southern_women) -#' @export -node_redundancy <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(manynet::is_twomode(.data)){ - mat <- manynet::as_matrix(.data) - out <- c(.redund2(mat), .redund2(t(mat))) - } else { - out <- .redund(manynet::as_matrix(.data)) - } - make_node_measure(out, .data) -} - -.redund <- function(.mat){ - n <- nrow(.mat) - qs <- .twopath_matrix(.mat > 0) - piq <- .mat/rowSums(.mat) - mjq <- .mat/matrix(do.call("pmax",data.frame(.mat)),n,n) - out <- rowSums(qs * piq * mjq) - out -} - -.redund2 <- function(.mat){ - sigi <- .mat %*% t(.mat) - diag(sigi) <- 0 - vapply(seq.int(nrow(sigi)), - function(x){ - xvec <- sigi[x,] #> 0 - if(manynet::is_weighted(.mat)){ - wt <- colMeans((.mat[x,] > 0 * t(.mat[xvec > 0,])) * t(.mat[xvec > 0,]) + .mat[x,]) * 2 - } else wt <- 1 - sum(colSums(xvec > 0 & t(sigi[xvec > 0,])) * xvec[xvec > 0] / - (sum(xvec) * wt)) - }, FUN.VALUE = numeric(1)) -} - -#' @rdname holes -#' @examples -#' node_effsize(ison_adolescents) -#' node_effsize(ison_southern_women) -#' @export -node_effsize <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(manynet::is_twomode(.data)){ - mat <- manynet::as_matrix(.data) - out <- c(rowSums(manynet::as_matrix(manynet::to_mode1(.data))>0), - rowSums(manynet::as_matrix(manynet::to_mode2(.data))>0)) - node_redundancy(.data) - } else { - mat <- manynet::as_matrix(.data) - out <- rowSums(mat>0) - .redund(mat) - } - make_node_measure(out, .data) -} - -.twopath_matrix <- function(.data){ - .data <- manynet::as_matrix(.data) - qs <- .data %*% t(.data) - diag(qs) <- 0 - qs -} - - -#' @rdname holes -#' @examples -#' node_efficiency(ison_adolescents) -#' node_efficiency(ison_southern_women) -#' @export -node_efficiency <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- node_effsize(.data) / node_degree(.data, normalized = FALSE) - make_node_measure(as.numeric(out), .data) -} - -#' @rdname holes -#' @references -#' Hollway, James, Jean-Frédéric Morin, and Joost Pauwelyn. 2020. -#' "Structural conditions for novelty: the introduction of new environmental clauses to the trade regime complex." -#' _International Environmental Agreements: Politics, Law and Economics_ 20 (1): 61–83. -#' \doi{10.1007/s10784-019-09464-5}. -#' @examples -#' node_constraint(ison_southern_women) -#' @export -node_constraint <- function(.data) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - if (manynet::is_twomode(.data)) { - get_constraint_scores <- function(mat) { - inst <- colnames(mat) - rowp <- mat * matrix(1 / rowSums(mat), nrow(mat), ncol(mat)) - colp <- mat * matrix(1 / colSums(mat), nrow(mat), ncol(mat), byrow = T) - res <- vector() - for (i in inst) { - ci <- 0 - membs <- names(which(mat[, i] > 0)) - for (a in membs) { - pia <- colp[a, i] - oth <- membs[membs != a] - pbj <- 0 - if (length(oth) == 1) { - for (j in inst[mat[oth, ] > 0 & inst != i]) { - pbj <- sum(pbj, sum(colp[oth, i] * rowp[oth, j] * colp[a, j])) - } - } else { - for (j in inst[colSums(mat[oth, ]) > 0 & inst != i]) { - pbj <- sum(pbj, sum(colp[oth, i] * rowp[oth, j] * colp[a, j])) - } - } - cia <- (pia + pbj)^2 - ci <- sum(ci, cia) - } - res <- c(res, ci) - } - names(res) <- inst - res - } - inst.res <- get_constraint_scores(manynet::as_matrix(.data)) - actr.res <- get_constraint_scores(t(manynet::as_matrix(.data))) - res <- c(actr.res, inst.res) - } else { - res <- igraph::constraint(manynet::as_igraph(.data), - nodes = igraph::V(.data), - weights = NULL) - } - res <- make_node_measure(res, .data) - res -} - -#' @rdname holes -#' @examples -#' node_hierarchy(ison_adolescents) -#' node_hierarchy(ison_southern_women) -#' @export -node_hierarchy <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - cs <- node_constraint(.data) - g <- manynet::as_igraph(.data) - out <- vapply(igraph::V(g), function(ego){ - n = igraph::neighbors(g, ego) - N <- length(n) - css <- cs[n] - CN <- mean(css) - rj <- css/CN - sum(rj*log(rj)) / (N * log(N)) - }, FUN.VALUE = numeric(1)) - out[is.nan(out)] <- 0 - make_node_measure(out, .data) -} - -#' @rdname holes -#' @importFrom igraph eccentricity -#' @export -node_eccentricity <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- igraph::eccentricity(manynet::as_igraph(.data), - mode = "out") - make_node_measure(out, .data) -} - -#' @rdname holes -#' @importFrom igraph knn -#' @references -#' Barrat, Alain, Marc Barthelemy, Romualdo Pastor-Satorras, and Alessandro Vespignani. 2004. -#' "The architecture of complex weighted networks", -#' _Proc. Natl. Acad. Sci._ 101: 3747. -#' @export -node_neighbours_degree <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- igraph::knn(manynet::as_igraph(.data), - mode = "out")$knn - make_node_measure(out, .data) -} - -#' @rdname holes -#' @export -tie_cohesion <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - ties <- igraph::E(.data) - coins <- data.frame(heads = igraph::head_of(.data, ties), - tails = igraph::tail_of(.data, ties)) - out <- apply(coins, 1, - function(x){ - neigh1 <- igraph::neighbors(.data, x[1]) - neigh2 <- igraph::neighbors(.data, x[2]) - shared_nodes <- sum(c(neigh1 %in% neigh2, - neigh2 %in% neigh1))/2 - neigh_nodes <- length(unique(c(neigh1, neigh2)))-2 - shared_nodes / neigh_nodes - } ) - make_node_measure(out, .data) -} diff --git a/man/holes.Rd b/man/holes.Rd deleted file mode 100644 index 7b8e6676..00000000 --- a/man/holes.Rd +++ /dev/null @@ -1,132 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_holes.R -\name{holes} -\alias{holes} -\alias{node_bridges} -\alias{node_redundancy} -\alias{node_effsize} -\alias{node_efficiency} -\alias{node_constraint} -\alias{node_hierarchy} -\alias{node_eccentricity} -\alias{node_neighbours_degree} -\alias{tie_cohesion} -\title{Measures of structural holes} -\usage{ -node_bridges(.data) - -node_redundancy(.data) - -node_effsize(.data) - -node_efficiency(.data) - -node_constraint(.data) - -node_hierarchy(.data) - -node_eccentricity(.data) - -node_neighbours_degree(.data) - -tie_cohesion(.data) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} -} -\description{ -These function provide different measures of the degree to which nodes -fill structural holes, as outlined in Burt (1992): -\itemize{ -\item \code{node_bridges()} measures the sum of bridges to which each node -is adjacent. -\item \code{node_redundancy()} measures the redundancy of each nodes' contacts. -\item \code{node_effsize()} measures nodes' effective size. -\item \code{node_efficiency()} measures nodes' efficiency. -\item \code{node_constraint()} measures nodes' constraint scores for one-mode networks -according to Burt (1992) and for two-mode networks according to Hollway et al (2020). -\item \code{node_hierarchy()} measures nodes' exposure to hierarchy, -where only one or two contacts are the source of closure. -\item \code{node_eccentricity()} measures nodes' eccentricity or Koenig number, -a measure of farness based on number of links needed to reach -most distant node in the network. -\item \code{node_neighbours_degree()} measures nodes' average nearest neighbors degree, -or \eqn{knn}, a measure of the type of local environment a node finds itself in -\item \code{tie_cohesion()} measures the ratio between common neighbors to ties' -adjacent nodes and the total number of adjacent nodes, -where high values indicate ties' embeddedness in dense local environments -} - -Burt's theory holds that while those nodes embedded in dense clusters -of close connections are likely exposed to the same or similar ideas and information, -those who fill structural holes between two otherwise disconnected groups -can gain some comparative advantage from that position. -} -\details{ -A number of different ways of measuring these structural holes are available. -Note that we use Borgatti's reformulation for unweighted networks in -\code{node_redundancy()} and \code{node_effsize()}. -Redundancy is thus \eqn{\frac{2t}{n}}, -where \eqn{t} is the sum of ties and \eqn{n} the sum of nodes in each node's neighbourhood, -and effective size is calculated as \eqn{n - \frac{2t}{n}}. -Node efficiency is the node's effective size divided by its degree. -} -\examples{ -node_bridges(ison_adolescents) -node_bridges(ison_southern_women) -node_redundancy(ison_adolescents) -node_redundancy(ison_southern_women) -node_effsize(ison_adolescents) -node_effsize(ison_southern_women) -node_efficiency(ison_adolescents) -node_efficiency(ison_southern_women) -node_constraint(ison_southern_women) -node_hierarchy(ison_adolescents) -node_hierarchy(ison_southern_women) -} -\references{ -Burt, Ronald S. 1992. -\emph{Structural Holes: The Social Structure of Competition}. -Cambridge, MA: Harvard University Press. - -Borgatti, Steven. 1997. -“\href{http://www.analytictech.com/connections/v20(1)/holes.htm}{Structural Holes: Unpacking Burt’s Redundancy Measures}” -\emph{Connections} 20(1):35-38. - -Burchard, Jake, and Benjamin Cornwell. 2018. -“Structural Holes and Bridging in Two-Mode Networks.” -\emph{Social Networks} 55:11–20. -\doi{10.1016/j.socnet.2018.04.001} - -Hollway, James, Jean-Frédéric Morin, and Joost Pauwelyn. 2020. -"Structural conditions for novelty: the introduction of new environmental clauses to the trade regime complex." -\emph{International Environmental Agreements: Politics, Law and Economics} 20 (1): 61–83. -\doi{10.1007/s10784-019-09464-5}. - -Barrat, Alain, Marc Barthelemy, Romualdo Pastor-Satorras, and Alessandro Vespignani. 2004. -"The architecture of complex weighted networks", -\emph{Proc. Natl. Acad. Sci.} 101: 3747. -} -\seealso{ -Other measures: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{closure}}, -\code{\link{cohesion}()}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}}, -\code{\link{features}}, -\code{\link{heterogeneity}}, -\code{\link{hierarchy}}, -\code{\link{net_diffusion}}, -\code{\link{node_diffusion}}, -\code{\link{periods}} -} -\concept{measures} From cf23995520b2ca3300860c7460dfd0898abefadd Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:20:27 +0200 Subject: [PATCH 65/97] Migrated feature measures to manynet --- R/measure_features.R | 387 ------------------------------------------- man/features.Rd | 181 -------------------- 2 files changed, 568 deletions(-) delete mode 100644 R/measure_features.R delete mode 100644 man/features.Rd diff --git a/R/measure_features.R b/R/measure_features.R deleted file mode 100644 index 2f32f1b5..00000000 --- a/R/measure_features.R +++ /dev/null @@ -1,387 +0,0 @@ -# Topological features #### - -#' Measures of network topological features -#' @description -#' These functions measure certain topological features of networks: -#' -#' - `network_core()` measures the correlation between a network -#' and a core-periphery model with the same dimensions. -#' - `network_richclub()` measures the rich-club coefficient of a network. -#' - `network_factions()` measures the correlation between a network -#' and a component model with the same dimensions. -#' If no 'membership' vector is given for the data, -#' `node_kernighanlin()` is used to partition nodes into two groups. -#' - `network_modularity()` measures the modularity of a network -#' based on nodes' membership in defined clusters. -#' - `network_smallworld()` measures the small-world coefficient for one- or -#' two-mode networks. Small-world networks can be highly clustered and yet -#' have short path lengths. -#' - `network_scalefree()` measures the exponent of a fitted -#' power-law distribution. An exponent between 2 and 3 usually indicates -#' a power-law distribution. -#' - `network_balance()` measures the structural balance index on -#' the proportion of balanced triangles, -#' ranging between `0` if all triangles are imbalanced and -#' `1` if all triangles are balanced. -#' - `network_change()` measures the Hamming distance between two or more networks. -#' - `network_stability()` measures the Jaccard index of stability between two or more networks. -#' -#' These `network_*()` functions return a single numeric scalar or value. -#' @inheritParams cohesion -#' @param membership A vector of partition membership. -#' @name features -#' @family measures -NULL - -#' @rdname features -#' @examples -#' network_core(ison_adolescents) -#' network_core(ison_southern_women) -#' @references -#' Borgatti, Stephen P., and Martin G. Everett. 2000. -#' “Models of Core/Periphery Structures.” -#' _Social Networks_ 21(4):375–95. -#' \doi{10.1016/S0378-8733(99)00019-2} -#' @export -network_core <- function(.data, - membership = NULL){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(is.null(membership)) membership <- node_in_core(.data) - out <- stats::cor(c(manynet::as_matrix(.data)), - c(manynet::as_matrix(manynet::create_core(.data, - membership = membership)))) - make_network_measure(out, .data) -} - -#' @rdname features -#' @examples -#' network_richclub(ison_adolescents) -#' @export -network_richclub <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - coefs <- vector() - temp <- .data - for(k in seq_len(max(node_degree(temp, normalized = FALSE)))){ - richclub <- manynet::to_subgraph(temp, node_degree(temp, normalized = FALSE) >= k) - nk <- manynet::network_nodes(richclub) - ek <- ifelse(manynet::is_directed(temp), - manynet::network_ties(richclub), - 2*manynet::network_ties(richclub)) - coefs <- c(coefs, (ek)/(nk*(nk-1))) - } - - elbow_finder <- function(x_values, y_values) { - # Max values to create line - # if(min(x_values)==1) x_values <- x_values[2:length(x_values)] - # if(min(y_values)==0) y_values <- y_values[2:length(y_values)] - max_df <- data.frame(x = c(1, min(which(y_values == 1))), - y = c(min(y_values), max(y_values))) - # Creating straight line between the max values - fit <- stats::lm(max_df$y ~ max_df$x) - # Distance from point to line - distances <- vector() - for (i in seq_len(length(x_values))) { - distances <- c(distances, - abs(stats::coef(fit)[2]*x_values[i] - - y_values[i] + - coef(fit)[1]) / - sqrt(stats::coef(fit)[2]^2 + 1^2)) - } - # Max distance point - x_max_dist <- x_values[which.max(distances)] - x_max_dist - } - - coefs[is.nan(coefs)] <- 1 - out <- coefs[elbow_finder(seq_along(coefs), coefs)] - # max(coefs, na.rm = TRUE) - make_network_measure(out, .data) -} - -#' @rdname features -#' @examples -#' network_factions(mpn_elite_mex) -#' network_factions(ison_southern_women) -#' @export -network_factions <- function(.data, - membership = NULL){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(is.null(membership)) - membership <- node_in_partition(.data) - out <- stats::cor(c(manynet::as_matrix(.data)), - c(manynet::as_matrix(manynet::create_components(.data, - membership = membership)))) - make_network_measure(out, .data) -} - -#' @rdname features -#' @section Modularity: -#' Modularity measures the difference between the number of ties within each community -#' from the number of ties expected within each community in a random graph -#' with the same degrees, and ranges between -1 and +1. -#' Modularity scores of +1 mean that ties only appear within communities, -#' while -1 would mean that ties only appear between communities. -#' A score of 0 would mean that ties are half within and half between communities, -#' as one would expect in a random graph. -#' -#' Modularity faces a difficult problem known as the resolution limit -#' (Fortunato and Barthélemy 2007). -#' This problem appears when optimising modularity, -#' particularly with large networks or depending on the degree of interconnectedness, -#' can miss small clusters that 'hide' inside larger clusters. -#' In the extreme case, this can be where they are only connected -#' to the rest of the network through a single tie. -#' @param resolution A proportion indicating the resolution scale. -#' By default 1. -#' @examples -#' network_modularity(ison_adolescents, -#' node_kernighanlin(ison_adolescents)) -#' network_modularity(ison_southern_women, -#' node_kernighanlin(ison_southern_women)) -#' @references -#' Murata, Tsuyoshi. 2010. Modularity for Bipartite Networks. -#' In: Memon, N., Xu, J., Hicks, D., Chen, H. (eds) -#' _Data Mining for Social Network Data. Annals of Information Systems_, Vol 12. -#' Springer, Boston, MA. -#' \doi{10.1007/978-1-4419-6287-4_7} -#' @export -network_modularity <- function(.data, - membership = NULL, - resolution = 1){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(is.null(membership)) - membership <- node_in_partition(.data) - if(!is.numeric(membership)) membership <- as.numeric(as.factor(membership)) - if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) - if(manynet::is_twomode(.data)){ - make_network_measure(igraph::modularity(manynet::to_multilevel(.data), - membership = membership, - resolution = resolution), .data) - } else make_network_measure(igraph::modularity(.data, - membership = membership, - resolution = resolution), - .data) -} - -#' @rdname features -#' @param times Integer of number of simulations. -#' @param method There are three small-world measures implemented: -#' - "sigma" is the original equation from Watts and Strogatz (1998), -#' \deqn{\frac{\frac{C}{C_r}}{\frac{L}{L_r}}}, -#' where \eqn{C} and \eqn{L} are the observed -#' clustering coefficient and path length, respectively, -#' and \eqn{C_r} and \eqn{L_r} are the averages obtained from -#' random networks of the same dimensions and density. -#' A \eqn{\sigma > 1} is considered to be small-world, -#' but this measure is highly sensitive to network size. -#' - "omega" (the default) is an update from Telesford et al. (2011), -#' \deqn{\frac{L_r}{L} - \frac{C}{C_l}}, -#' where \eqn{C_l} is the clustering coefficient for a lattice graph -#' with the same dimensions. -#' \eqn{\omega} ranges between 0 and 1, -#' where 1 is as close to a small-world as possible. -#' - "SWI" is an alternative proposed by Neal (2017), -#' \deqn{\frac{L - L_l}{L_r - L_l} \times \frac{C - C_r}{C_l - C_r}}, -#' where \eqn{L_l} is the average path length for a lattice graph -#' with the same dimensions. -#' \eqn{SWI} also ranges between 0 and 1 with the same interpretation, -#' but where there may not be a network for which \eqn{SWI = 1}. -#' @seealso [network_transitivity()] and [network_equivalency()] -#' for how clustering is calculated -#' @references -#' Watts, Duncan J., and Steven H. Strogatz. 1998. -#' “Collective Dynamics of ‘Small-World’ Networks.” -#' _Nature_ 393(6684):440–42. -#' \doi{10.1038/30918}. -#' -#' Telesford QK, Joyce KE, Hayasaka S, Burdette JH, Laurienti PJ. 2011. -#' "The ubiquity of small-world networks". -#' _Brain Connectivity_ 1(5): 367–75. -#' \doi{10.1089/brain.2011.0038}. -#' -#' Neal Zachary P. 2017. -#' "How small is it? Comparing indices of small worldliness". -#' _Network Science_. 5 (1): 30–44. -#' \doi{10.1017/nws.2017.5}. -#' @examples -#' network_smallworld(ison_brandes) -#' network_smallworld(ison_southern_women) -#' @export -network_smallworld <- function(.data, - method = c("omega", "sigma", "SWI"), - times = 100) { - - if(missing(.data)) {expect_nodes(); .data <- .G()} - method <- match.arg(method) - - if(manynet::is_twomode(.data)){ - co <- network_equivalency(.data) - cr <- mean(vapply(1:times, - function(x) network_equivalency(manynet::generate_random(.data)), - FUN.VALUE = numeric(1))) - if(method %in% c("omega", "SWI")){ - cl <- network_equivalency(manynet::create_ring(.data)) - } - } else { - co <- network_transitivity(.data) - cr <- mean(vapply(1:times, - function(x) network_transitivity(manynet::generate_random(.data)), - FUN.VALUE = numeric(1))) - if(method %in% c("omega", "SWI")){ - cl <- network_transitivity(manynet::create_lattice(.data)) - } - } - - lo <- network_length(.data) - lr <- mean(vapply(1:times, - function(x) network_length(manynet::generate_random(.data)), - FUN.VALUE = numeric(1))) - if(method == "SWI"){ - ll <- network_length(manynet::create_ring(.data)) - } - - out <- switch(method, - "omega" = (lr/lo - co/cl), - "sigma" = (co/cr)/(lo/lr), - "SWI" = ((lo - ll)/(lr - ll))*((co - cr)/(cl - cr))) - make_network_measure(out, - .data) -} - -#' @rdname features -#' @importFrom igraph fit_power_law -#' @examples -#' network_scalefree(ison_adolescents) -#' network_scalefree(generate_scalefree(50, 1.5)) -#' network_scalefree(create_lattice(100)) -#' @export -network_scalefree <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- igraph::fit_power_law(node_degree(.data, normalized = FALSE)) - if ("KS.p" %in% names(out)) { - if(out$KS.p < 0.05) - cat(paste("Note: Kolgomorov-Smirnov test that data", - "could have been drawn from a power-law", - "distribution rejected.\n")) - } - make_network_measure(out$alpha, .data) -} - -#' @rdname features -#' @source `{signnet}` by David Schoch -#' @examples -#' network_balance(ison_marvel_relationships) -#' @export -network_balance <- function(.data) { - - if(missing(.data)) {expect_nodes(); .data <- .G()} - count_signed_triangles <- function(.data){ - g <- manynet::as_igraph(.data) - if (!"sign" %in% igraph::edge_attr_names(g)) { - stop("network does not have a sign edge attribute") - } - if (igraph::is_directed(g)) { - stop("g must be undirected") - } - eattrV <- igraph::edge_attr(g, "sign") - if (!all(eattrV %in% c(-1, 1))) { - stop("sign may only contain -1 and 1") - } - tmat <- t(matrix(igraph::triangles(g), nrow = 3)) - if (nrow(tmat) == 0) { - warning("g does not contain any triangles") - return(c(`+++` = 0, `++-` = 0, `+--` = 0, `---` = 0)) - } - emat <- t(apply(tmat, 1, function(x) c(igraph::get.edge.ids(g, - x[1:2]), igraph::get.edge.ids(g, x[2:3]), igraph::get.edge.ids(g, - x[c(3, 1)])))) - emat[, 1] <- eattrV[emat[, 1]] - emat[, 2] <- eattrV[emat[, 2]] - emat[, 3] <- eattrV[emat[, 3]] - emat <- t(apply(emat, 1, sort)) - emat_df <- as.data.frame(emat) - res <- stats::aggregate(list(count = rep(1, nrow(emat_df))), - emat_df, length) - tri_counts <- c(`+++` = 0, `++-` = 0, `+--` = 0, `---` = 0) - tmp_counts <- res[, 4] - if (nrow(res) == 1) { - names(tmp_counts) <- paste0(c("+", "-")[(rev(res[1:3]) == - -1) + 1], collapse = "") - } - else { - names(tmp_counts) <- apply(res[, 1:3], 1, function(x) paste0(c("+", - "-")[(rev(x) == -1) + 1], collapse = "")) - } - tri_counts[match(names(tmp_counts), names(tri_counts))] <- tmp_counts - tri_counts - } - - if (!manynet::is_signed(.data)) { - stop("network does not have a sign edge attribute") - } - if (manynet::is_directed(.data)) { - stop("object must be undirected") - } - g <- manynet::as_igraph(.data) - eattrV <- igraph::edge_attr(g, "sign") - if (!all(eattrV %in% c(-1, 1))) { - stop("sign may only contain -1 and 1") - } - tria_count <- count_signed_triangles(g) - make_network_measure(unname((tria_count["+++"] + tria_count["+--"])/sum(tria_count)), - .data) -} - -# Change #### - -#' Measures of network change -#' @description -#' These functions measure certain topological features of networks: -#' -#' - `network_change()` measures the Hamming distance between two or more networks. -#' - `network_stability()` measures the Jaccard index of stability between two or more networks. -#' -#' These `network_*()` functions return a numeric vector the length of the number -#' of networks minus one. E.g., the periods between waves. -#' @inheritParams cohesion -#' @name periods -#' @family measures -NULL - -#' @rdname periods -#' @param object2 A network object. -#' @export -network_change <- function(.data, object2){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(manynet::is_list(.data)){ - - } else if(!missing(object2)){ - .data <- list(.data, object2) - } else stop("`.data` must be a list of networks or a second network must be provided.") - periods <- length(.data)-1 - vapply(seq.int(periods), function(x){ - net1 <- manynet::as_matrix(.data[[x]]) - net2 <- manynet::as_matrix(.data[[x+1]]) - sum(net1 != net2) - }, FUN.VALUE = numeric(1)) -} - -#' @rdname periods -#' @export -network_stability <- function(.data, object2){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(manynet::is_list(.data)){ - - } else if(!missing(object2)){ - .data <- list(.data, object2) - } else stop("`.data` must be a list of networks or a second network must be provided.") - periods <- length(.data)-1 - vapply(seq.int(periods), function(x){ - net1 <- manynet::as_matrix(.data[[x]]) - net2 <- manynet::as_matrix(.data[[x+1]]) - n11 <- sum(net1 * net2) - n01 <- sum(net1==0 * net2) - n10 <- sum(net1 * net2==0) - n11 / (n01 + n10 + n11) - }, FUN.VALUE = numeric(1)) -} diff --git a/man/features.Rd b/man/features.Rd deleted file mode 100644 index f7657c76..00000000 --- a/man/features.Rd +++ /dev/null @@ -1,181 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/measure_features.R -\name{features} -\alias{features} -\alias{network_core} -\alias{network_richclub} -\alias{network_factions} -\alias{network_modularity} -\alias{network_smallworld} -\alias{network_scalefree} -\alias{network_balance} -\title{Measures of network topological features} -\source{ -\code{{signnet}} by David Schoch -} -\usage{ -network_core(.data, membership = NULL) - -network_richclub(.data) - -network_factions(.data, membership = NULL) - -network_modularity(.data, membership = NULL, resolution = 1) - -network_smallworld(.data, method = c("omega", "sigma", "SWI"), times = 100) - -network_scalefree(.data) - -network_balance(.data) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{membership}{A vector of partition membership.} - -\item{resolution}{A proportion indicating the resolution scale. -By default 1.} - -\item{method}{There are three small-world measures implemented: -\itemize{ -\item "sigma" is the original equation from Watts and Strogatz (1998), -\deqn{\frac{\frac{C}{C_r}}{\frac{L}{L_r}}}, -where \eqn{C} and \eqn{L} are the observed -clustering coefficient and path length, respectively, -and \eqn{C_r} and \eqn{L_r} are the averages obtained from -random networks of the same dimensions and density. -A \eqn{\sigma > 1} is considered to be small-world, -but this measure is highly sensitive to network size. -\item "omega" (the default) is an update from Telesford et al. (2011), -\deqn{\frac{L_r}{L} - \frac{C}{C_l}}, -where \eqn{C_l} is the clustering coefficient for a lattice graph -with the same dimensions. -\eqn{\omega} ranges between 0 and 1, -where 1 is as close to a small-world as possible. -\item "SWI" is an alternative proposed by Neal (2017), -\deqn{\frac{L - L_l}{L_r - L_l} \times \frac{C - C_r}{C_l - C_r}}, -where \eqn{L_l} is the average path length for a lattice graph -with the same dimensions. -\eqn{SWI} also ranges between 0 and 1 with the same interpretation, -but where there may not be a network for which \eqn{SWI = 1}. -}} - -\item{times}{Integer of number of simulations.} -} -\description{ -These functions measure certain topological features of networks: -\itemize{ -\item \code{network_core()} measures the correlation between a network -and a core-periphery model with the same dimensions. -\item \code{network_richclub()} measures the rich-club coefficient of a network. -\item \code{network_factions()} measures the correlation between a network -and a component model with the same dimensions. -If no 'membership' vector is given for the data, -\code{node_kernighanlin()} is used to partition nodes into two groups. -\item \code{network_modularity()} measures the modularity of a network -based on nodes' membership in defined clusters. -\item \code{network_smallworld()} measures the small-world coefficient for one- or -two-mode networks. Small-world networks can be highly clustered and yet -have short path lengths. -\item \code{network_scalefree()} measures the exponent of a fitted -power-law distribution. An exponent between 2 and 3 usually indicates -a power-law distribution. -\item \code{network_balance()} measures the structural balance index on -the proportion of balanced triangles, -ranging between \code{0} if all triangles are imbalanced and -\code{1} if all triangles are balanced. -\item \code{network_change()} measures the Hamming distance between two or more networks. -\item \code{network_stability()} measures the Jaccard index of stability between two or more networks. -} - -These \verb{network_*()} functions return a single numeric scalar or value. -} -\section{Modularity}{ - -Modularity measures the difference between the number of ties within each community -from the number of ties expected within each community in a random graph -with the same degrees, and ranges between -1 and +1. -Modularity scores of +1 mean that ties only appear within communities, -while -1 would mean that ties only appear between communities. -A score of 0 would mean that ties are half within and half between communities, -as one would expect in a random graph. - -Modularity faces a difficult problem known as the resolution limit -(Fortunato and Barthélemy 2007). -This problem appears when optimising modularity, -particularly with large networks or depending on the degree of interconnectedness, -can miss small clusters that 'hide' inside larger clusters. -In the extreme case, this can be where they are only connected -to the rest of the network through a single tie. -} - -\examples{ -network_core(ison_adolescents) -network_core(ison_southern_women) -network_richclub(ison_adolescents) - network_factions(mpn_elite_mex) - network_factions(ison_southern_women) -network_modularity(ison_adolescents, - node_kernighanlin(ison_adolescents)) -network_modularity(ison_southern_women, - node_kernighanlin(ison_southern_women)) -network_smallworld(ison_brandes) -network_smallworld(ison_southern_women) -network_scalefree(ison_adolescents) -network_scalefree(generate_scalefree(50, 1.5)) -network_scalefree(create_lattice(100)) -network_balance(ison_marvel_relationships) -} -\references{ -Borgatti, Stephen P., and Martin G. Everett. 2000. -“Models of Core/Periphery Structures.” -\emph{Social Networks} 21(4):375–95. -\doi{10.1016/S0378-8733(99)00019-2} - -Murata, Tsuyoshi. 2010. Modularity for Bipartite Networks. -In: Memon, N., Xu, J., Hicks, D., Chen, H. (eds) -\emph{Data Mining for Social Network Data. Annals of Information Systems}, Vol 12. -Springer, Boston, MA. -\doi{10.1007/978-1-4419-6287-4_7} - -Watts, Duncan J., and Steven H. Strogatz. 1998. -“Collective Dynamics of ‘Small-World’ Networks.” -\emph{Nature} 393(6684):440–42. -\doi{10.1038/30918}. - -Telesford QK, Joyce KE, Hayasaka S, Burdette JH, Laurienti PJ. 2011. -"The ubiquity of small-world networks". -\emph{Brain Connectivity} 1(5): 367–75. -\doi{10.1089/brain.2011.0038}. - -Neal Zachary P. 2017. -"How small is it? Comparing indices of small worldliness". -\emph{Network Science}. 5 (1): 30–44. -\doi{10.1017/nws.2017.5}. -} -\seealso{ -\code{\link[=network_transitivity]{network_transitivity()}} and \code{\link[=network_equivalency]{network_equivalency()}} -for how clustering is calculated - -Other measures: -\code{\link{between_centrality}}, -\code{\link{close_centrality}}, -\code{\link{closure}}, -\code{\link{cohesion}()}, -\code{\link{degree_centrality}}, -\code{\link{eigenv_centrality}}, -\code{\link{heterogeneity}}, -\code{\link{hierarchy}}, -\code{\link{holes}}, -\code{\link{net_diffusion}}, -\code{\link{node_diffusion}}, -\code{\link{periods}} -} -\concept{measures} From 80b2d74e4743fa31ddd68cc7adc11da8fabed042 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:20:43 +0200 Subject: [PATCH 66/97] Migrated census/motifs to manynet --- R/motif_census.R | 492 ------------------------------------------ man/network_census.Rd | 61 ------ man/node_census.Rd | 105 --------- 3 files changed, 658 deletions(-) delete mode 100644 R/motif_census.R delete mode 100644 man/network_census.Rd delete mode 100644 man/node_census.Rd diff --git a/R/motif_census.R b/R/motif_census.R deleted file mode 100644 index 2fca8942..00000000 --- a/R/motif_census.R +++ /dev/null @@ -1,492 +0,0 @@ -# Node censuses #### - -#' Censuses of nodes' motifs -#' -#' @description -#' These functions include ways to take a census of the positions of nodes -#' in a network: -#' -#' - `node_tie_census()` returns a census of the ties in a network. -#' For directed networks, out-ties and in-ties are bound together. -#' for multiplex networks, the various types of ties are bound together. -#' - `node_triad_census()` returns a census of the triad configurations -#' nodes are embedded in. -#' - `node_quad_census()` returns a census of nodes' positions -#' in motifs of four nodes. -#' - `node_path_census()` returns the shortest path lengths -#' of each node to every other node in the network. -#' -#' @name node_census -#' @family motifs -#' @inheritParams cohesion -#' @importFrom igraph vcount make_ego_graph delete_vertices triad_census -NULL - -#' @rdname node_census -#' @examples -#' task_eg <- manynet::to_named(manynet::to_uniplex(manynet::ison_algebra, "tasks")) -#' (tie_cen <- node_tie_census(task_eg)) -#' @export -node_tie_census <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - object <- manynet::as_igraph(.data) - # edge_names <- manynet::network_tie_attributes(object) - if (manynet::is_directed(object)) { - if (manynet::is_multiplex(.data)) { - mat <- do.call(rbind, lapply(unique(manynet::tie_attribute(object, "type")), - function(x){ - rc <- manynet::as_matrix(manynet::to_uniplex(object, x)) - rbind(rc, t(rc)) - })) - } else if (manynet::is_longitudinal(object)){ - mat <- do.call(rbind, lapply(unique(manynet::tie_attribute(object, "wave")), - function(x){ - rc <- manynet::as_matrix(manynet::to_waves(object)[[x]]) - rbind(rc, t(rc)) - })) - - } else { - rc <- manynet::as_matrix(object) - mat <- rbind(rc, t(rc)) - } - } else { - if (manynet::is_multiplex(.data)) { - mat <- do.call(rbind, lapply(unique(manynet::tie_attribute(object, "type")), - function(x){ - manynet::as_matrix(manynet::to_uniplex(object, x)) - })) - } else if (manynet::is_longitudinal(object)){ - mat <- do.call(rbind, lapply(unique(manynet::tie_attribute(object, "wave")), - function(x){ - manynet::as_matrix(manynet::to_waves(object)[[x]]) - })) - } else if (manynet::is_twomode(.data)) { - mat <- manynet::as_matrix(manynet::to_multilevel(object)) - } else { - mat <- manynet::as_matrix(object) - } - } - if(manynet::is_labelled(object) & manynet::is_directed(object)) - if(manynet::is_multiplex(.data)){ - rownames(mat) <- apply(expand.grid(c(paste0("from", manynet::node_names(object)), - paste0("to", manynet::node_names(object))), - unique(manynet::tie_attribute(object, "type"))), - 1, paste, collapse = "_") - } else if (manynet::is_longitudinal(object)){ - rownames(mat) <- apply(expand.grid(c(paste0("from", manynet::node_names(object)), - paste0("to", manynet::node_names(object))), - unique(manynet::tie_attribute(object, "wave"))), - 1, paste, collapse = "_wave") - } else { - rownames(mat) <- rep(c(paste0("from", manynet::node_names(object)), - paste0("to", manynet::node_names(object)))) - } - make_node_motif(t(mat), object) -} - -#' @rdname node_census -#' @references -#' Davis, James A., and Samuel Leinhardt. 1967. -#' “\href{https://files.eric.ed.gov/fulltext/ED024086.pdf}{The Structure of Positive Interpersonal Relations in Small Groups}.” 55. -#' @examples -#' (triad_cen <- node_triad_census(task_eg)) -#' @export -node_triad_census <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - out <- t(sapply(seq.int(manynet::network_nodes(.data)), - function(x) network_triad_census(.data) - network_triad_census(manynet::delete_nodes(.data, x)))) - rownames(out) <- manynet::node_names(.data) - make_node_motif(out, .data) -} - -#' @rdname node_census -#' @section Quad census: -#' The quad census uses the `{oaqc}` package to do -#' the heavy lifting of counting the number of each orbits. -#' See `vignette('oaqc')`. -#' However, our function relabels some of the motifs -#' to avoid conflicts and improve some consistency with -#' other census-labelling practices. -#' The letter-number pairing of these labels indicate -#' the number and configuration of ties. -#' For now, we offer a rough translation: -#' -#' | migraph | Ortmann and Brandes -#' | ------------- |------------- | -#' | E4 | co-K4 -#' | I40, I41 | co-diamond -#' | H4 | co-C4 -#' | L42, L41, L40 | co-paw -#' | D42, D40 | co-claw -#' | U42, U41 | P4 -#' | Y43, Y41 | claw -#' | P43, P42, P41 | paw -#' | 04 | C4 -#' | Z42, Z43 | diamond -#' | X4 | K4 -#' -#' See also [this list of graph classes](https://www.graphclasses.org/smallgraphs.html#nodes4). -#' @importFrom tidygraph %E>% -#' @references -#' Ortmann, Mark, and Ulrik Brandes. 2017. -#' “Efficient Orbit-Aware Triad and Quad Census in Directed and Undirected Graphs.” -#' \emph{Applied Network Science} 2(1):13. -#' \doi{10.1007/s41109-017-0027-2}. -#' @examples -#' node_quad_census(manynet::ison_southern_women) -#' @export -node_quad_census <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - thisRequires("oaqc") - graph <- .data %>% manynet::as_tidygraph() %E>% - as.data.frame() - out <- oaqc::oaqc(graph)[[1]] - out <- out[-1,] - rownames(out) <- manynet::node_names(.data) - colnames(out) <- c("E4", # co-K4 - "I41","I40", # co-diamond - "H4", # co-C4 - "L42","L41","L40", # co-paw - "D42","D40", # co-claw - "U42","U41", # P4 - "Y43","Y41", # claw - "P43","P42","P41", # paw - "04", # C4 - "Z42","Z43", # diamond - "X4") # K4 - if(manynet::is_twomode(.data)) out <- out[,-c(8,9,14,15,16,18,19,20)] - make_node_motif(out, .data) -} - -# #' @export -# node_bmotif_census <- function(.data, normalized = FALSE){ -# if (!("bmotif" %in% rownames(utils::installed.packages()))) { -# message("Please install package `{bmotif}`.") -# out <- bmotif::node_positions(manynet::as_matrix(.data), -# weights_method = ifelse(manynet::is_weighted(.data), -# 'mean_motifweights', 'none'), -# normalisation = ifelse(normalized, -# 'levelsize_NAzero', 'none')) -# make_node_motif(out, .data) -# } -# } -# -# #' @export -# node_igraph_census <- function(.data, normalized = FALSE){ -# out <- igraph::motifs(manynet::as_igraph(.data), 4) -# if(manynet::is_labelled(.data)) -# rownames(out) <- manynet::node_names(.data) -# colnames(out) <- c("co-K4", -# "co-diamond", -# "co-C4", -# "co-paw", -# "co-claw", -# "P4", -# "claw", -# "paw", -# "C4", -# "diamond", -# "K4") -# make_node_motif(out, .data) -# } - -#' @rdname node_census -#' @importFrom igraph distances -#' @references -#' Dijkstra, Edsger W. 1959. -#' "A note on two problems in connexion with graphs". -#' _Numerische Mathematik_ 1, 269-71. -#' \doi{10.1007/BF01386390}. -#' -#' Opsahl, Tore, Filip Agneessens, and John Skvoretz. 2010. -#' "Node centrality in weighted networks: Generalizing degree and shortest paths". -#' _Social Networks_ 32(3): 245-51. -#' \doi{10.1016/j.socnet.2010.03.006}. -#' @examples -#' node_path_census(manynet::ison_adolescents) -#' node_path_census(manynet::ison_southern_women) -#' @export -node_path_census <- function(.data){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(manynet::is_weighted(.data)){ - tore <- manynet::as_matrix(.data)/mean(manynet::as_matrix(.data)) - out <- 1/tore - } else out <- igraph::distances(manynet::as_igraph(.data)) - diag(out) <- 0 - make_node_motif(out, .data) -} - -# Network censuses #### - -#' Censuses of motifs at the network level -#' -#' @description -#' These functions include ways to take a census of the positions of nodes -#' in a network: -#' -#' - `network_dyad_census()` returns a census of dyad motifs in a network. -#' - `network_triad_census()` returns a census of triad motifs in a network. -#' - `network_mixed_census()` returns a census of triad motifs that span -#' a one-mode and a two-mode network. -#' -#' @name network_census -#' @family motifs -#' @inheritParams node_census -#' @param object2 A second, two-mode migraph-consistent object. -NULL - -#' @rdname network_census -#' @examples -#' network_dyad_census(manynet::ison_algebra) -#' @export -network_dyad_census <- function(.data) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - if (manynet::is_twomode(.data)) { - stop("A twomode or multilevel option for a dyad census is not yet implemented.") - } else { - out <- suppressWarnings(igraph::dyad_census(manynet::as_igraph(.data))) - out <- unlist(out) - names(out) <- c("Mutual", "Asymmetric", "Null") - if (!manynet::is_directed(.data)) out <- out[c(1, 3)] - make_network_motif(out, .data) - } -} - -#' @rdname network_census -#' @references -#' Davis, James A., and Samuel Leinhardt. 1967. -#' “\href{https://files.eric.ed.gov/fulltext/ED024086.pdf}{The Structure of Positive Interpersonal Relations in Small Groups}.” 55. -#' @examples -#' network_triad_census(manynet::ison_adolescents) -#' @export -network_triad_census <- function(.data) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - if (manynet::is_twomode(.data)) { - stop("A twomode or multilevel option for a triad census is not yet implemented.") - } else { - out <- suppressWarnings(igraph::triad_census(as_igraph(.data))) - names(out) <- c("003", "012", "102", "021D", - "021U", "021C", "111D", "111U", - "030T", "030C", "201", "120D", - "120U", "120C", "210", "300") - if (!manynet::is_directed(.data)) out <- out[c(1, 2, 3, 11, 15, 16)] - make_network_motif(out, .data) - } -} - -#' @rdname network_census -#' @source Alejandro Espinosa 'netmem' -#' @references -#' Hollway, James, Alessandro Lomi, Francesca Pallotti, and Christoph Stadtfeld. 2017. -#' “Multilevel Social Spaces: The Network Dynamics of Organizational Fields.” -#' _Network Science_ 5(2): 187–212. -#' \doi{10.1017/nws.2017.8} -#' @examples -#' marvel_friends <- manynet::to_unsigned(manynet::ison_marvel_relationships, "positive") -#' (mixed_cen <- network_mixed_census(marvel_friends, manynet::ison_marvel_teams)) -#' @export -network_mixed_census <- function (.data, object2) { - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(manynet::is_twomode(.data)) - stop("First object should be a one-mode network") - if(!manynet::is_twomode(object2)) - stop("Second object should be a two-mode network") - if(manynet::network_dims(.data)[1] != manynet::network_dims(object2)[1]) - stop("Non-conformable arrays") - m1 <- manynet::as_matrix(.data) - m2 <- manynet::as_matrix(object2) - cp <- function(m) (-m + 1) - onemode.reciprocal <- m1 * t(m1) - onemode.forward <- m1 * cp(t(m1)) - onemode.backward <- cp(m1) * t(m1) - onemode.null <- cp(m1) * cp(t(m1)) - diag(onemode.forward) <- 0 - diag(onemode.backward) <- 0 - diag(onemode.null) <- 0 - bipartite.twopath <- m2 %*% t(m2) - bipartite.null <- cp(m2) %*% cp(t(m2)) - bipartite.onestep1 <- m2 %*% cp(t(m2)) - bipartite.onestep2 <- cp(m2) %*% t(m2) - diag(bipartite.twopath) <- 0 - diag(bipartite.null) <- 0 - diag(bipartite.onestep1) <- 0 - diag(bipartite.onestep2) <- 0 - res <- c("22" = sum(onemode.reciprocal * bipartite.twopath) / 2, - "21" = sum(onemode.forward * bipartite.twopath) / 2 + sum(onemode.backward * bipartite.twopath) / 2, - "20" = sum(onemode.null * bipartite.twopath) / 2, - "12" = sum(onemode.reciprocal * bipartite.onestep1) / 2 + sum(onemode.reciprocal * bipartite.onestep2) / 2, - "11D" = sum(onemode.forward * bipartite.onestep1) / 2 + sum(onemode.backward * bipartite.onestep2) / 2, - "11U" = sum(onemode.forward * bipartite.onestep2) / 2 + sum(onemode.backward * bipartite.onestep1) / 2, - "10" = sum(onemode.null * bipartite.onestep2) / 2 + sum(onemode.null * bipartite.onestep1) / 2, - "02" = sum(onemode.reciprocal * bipartite.null) / 2, - "01" = sum(onemode.forward * bipartite.null) / 2 + sum(onemode.backward * bipartite.null) / 2, - "00" = sum(onemode.null * bipartite.null) / 2) - make_network_motif(res, .data) -} - -# Brokerage #### - -#' Censuses of brokerage motifs -#' -#' @description -#' These functions include ways to take a census of the brokerage positions of nodes -#' in a network: -#' -#' - `node_brokerage_census()` returns the Gould-Fernandez brokerage -#' roles played by nodes in a network. -#' - `network_brokerage_census()` returns the Gould-Fernandez brokerage -#' roles in a network. -#' -#' @name brokerage_census -#' @family motifs -#' @inheritParams node_census -#' @param membership A vector of partition membership as integers. -#' @param standardized Whether the score should be standardized -#' into a _z_-score indicating how many standard deviations above -#' or below the average the score lies. -NULL - -#' @rdname brokerage_census -#' @importFrom sna brokerage -#' @references -#' Gould, R.V. and Fernandez, R.M. 1989. -#' “Structures of Mediation: A Formal Approach to Brokerage in Transaction Networks.” -#' _Sociological Methodology_, 19: 89-126. -#' -#' Jasny, Lorien, and Mark Lubell. 2015. -#' “Two-Mode Brokerage in Policy Networks.” -#' _Social Networks_ 41:36–47. -#' \doi{10.1016/j.socnet.2014.11.005}. -#' @examples -#' node_brokerage_census(manynet::ison_networkers, "Discipline") -#' @export -node_brokerage_census <- function(.data, membership, standardized = FALSE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(!manynet::is_twomode(.data)){ - out <- sna::brokerage(manynet::as_network(.data), - manynet::node_attribute(.data, membership)) - out <- if(standardized) out$z.nli else out$raw.nli - colnames(out) <- c("Coordinator", "Itinerant", "Gatekeeper", - "Representative", "Liaison", "Total") - } else { - out <- suppressWarnings(sna::brokerage(manynet::as_network(manynet::to_mode1(.data)), - manynet::node_attribute(.data, membership))) - out <- if(standardized) out$z.nli else out$raw.nli - out <- out[,-4] - colnames(out) <- c("Coordinator", "Itinerant", "Gatekeeper", - "Liaison", "Total") - } - make_node_motif(out, .data) -} - -#' @rdname brokerage_census -#' @examples -#' network_brokerage_census(manynet::ison_networkers, "Discipline") -#' @export -network_brokerage_census <- function(.data, membership, standardized = FALSE){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - if(!manynet::is_twomode(.data)){ - out <- sna::brokerage(manynet::as_network(.data), - manynet::node_attribute(.data, membership)) - out <- if(standardized) out$z.gli else out$raw.gli - names(out) <- c("Coordinator", "Itinerant", "Gatekeeper", - "Representative", "Liaison", "Total") - } else { - out <- suppressWarnings(sna::brokerage(manynet::as_network(manynet::to_mode1(.data)), - manynet::node_attribute(.data, membership))) - out <- if(standardized) out$z.gli else out$raw.gli - names(out) <- c("Coordinator", "Itinerant", "Gatekeeper", - "Representative", "Liaison", "Total") - } - make_network_motif(out, .data) -} - -#' @rdname brokerage_census -#' @references -#' Hamilton, Matthew, Jacob Hileman, and Orjan Bodin. 2020. -#' "Evaluating heterogeneous brokerage: New conceptual and methodological approaches -#' and their application to multi-level environmental governance networks" -#' _Social Networks_ 61: 1-10. -#' \doi{10.1016/j.socnet.2019.08.002} -#' @export -node_brokering_activity <- function(.data, membership){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - from <- to.y <- to_memb <- from_memb <- NULL - twopaths <- .to_twopaths(.data) - if(!missing(membership)){ - twopaths$from_memb <- manynet::node_attribute(.data, membership)[`if`(manynet::is_labelled(.data), - match(twopaths$from, manynet::node_names(.data)), - twopaths$from)] - twopaths$to_memb <- manynet::node_attribute(.data, membership)[`if`(manynet::is_labelled(.data), - match(twopaths$to.y, manynet::node_names(.data)), - twopaths$to.y)] - twopaths <- dplyr::filter(twopaths, from_memb != to_memb) - } - # tabulate brokerage - out <- c(table(twopaths$to)) - # correct ordering for named data - if(manynet::is_labelled(.data)) out <- out[match(manynet::node_names(.data), names(out))] - # missings should be none - out[is.na(out)] <- 0 - make_node_measure(out, .data) -} - -#' @rdname brokerage_census -#' @examples -#' node_brokering_exclusivity(ison_networkers, "Discipline") -#' @export -node_brokering_exclusivity <- function(.data, membership){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - from <- to.y <- to_memb <- from_memb <- NULL - twopaths <- .to_twopaths(.data) - if(!missing(membership)){ - twopaths$from_memb <- manynet::node_attribute(.data, membership)[`if`(manynet::is_labelled(.data), - match(twopaths$from, manynet::node_names(.data)), - twopaths$from)] - twopaths$to_memb <- manynet::node_attribute(.data, membership)[`if`(manynet::is_labelled(.data), - match(twopaths$to.y, manynet::node_names(.data)), - twopaths$to.y)] - twopaths <- dplyr::filter(twopaths, from_memb != to_memb) - } - # get only exclusive paths - out <- twopaths %>% dplyr::group_by(from, to.y) %>% dplyr::filter(dplyr::n()==1) - # tabulate brokerage - out <- c(table(out$to)) - # correct ordering for named data - if(manynet::is_labelled(.data)) out <- out[match(manynet::node_names(.data), names(out))] - # missings should be none - out[is.na(out)] <- 0 - make_node_measure(out, .data) -} - -#' @rdname brokerage_census -#' @export -node_brokering <- function(.data, membership){ - if(missing(.data)) {expect_nodes(); .data <- .G()} - activ <- node_brokering_activity(.data, membership) - exclusiv <- node_brokering_exclusivity(.data, membership) - activ <- activ - mean(activ) - exclusiv <- exclusiv - mean(exclusiv) - out <- dplyr::case_when(activ > 0 & exclusiv > 0 ~ "Powerhouse", - activ > 0 & exclusiv < 0 ~ "Connectors", - activ < 0 & exclusiv > 0 ~ "Linchpins", - activ < 0 & exclusiv < 0 ~ "Sideliners") - make_node_member(out, .data) -} - -.to_twopaths <- function(.data){ - to <- from <- to.y <- NULL - if(!manynet::is_directed(.data)){ - el <- manynet::as_edgelist(manynet::to_reciprocated(.data)) - } else el <- manynet::as_edgelist(.data) - twopaths <- dplyr::full_join(el, el, - by = dplyr::join_by(to == from), - relationship = "many-to-many") - # remove non two-paths - twopaths <- dplyr::filter(twopaths, !(is.na(from) | is.na(to.y))) - # remove reciprocated paths - twopaths <- dplyr::filter(twopaths, from != to.y) - # remove triads - twopaths <- dplyr::filter(twopaths, !paste(from, to.y) %in% paste(from, to)) - twopaths -} diff --git a/man/network_census.Rd b/man/network_census.Rd deleted file mode 100644 index 3f6eeaf0..00000000 --- a/man/network_census.Rd +++ /dev/null @@ -1,61 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/motif_census.R -\name{network_census} -\alias{network_census} -\alias{network_dyad_census} -\alias{network_triad_census} -\alias{network_mixed_census} -\title{Censuses of motifs at the network level} -\source{ -Alejandro Espinosa 'netmem' -} -\usage{ -network_dyad_census(.data) - -network_triad_census(.data) - -network_mixed_census(.data, object2) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{object2}{A second, two-mode migraph-consistent object.} -} -\description{ -These functions include ways to take a census of the positions of nodes -in a network: -\itemize{ -\item \code{network_dyad_census()} returns a census of dyad motifs in a network. -\item \code{network_triad_census()} returns a census of triad motifs in a network. -\item \code{network_mixed_census()} returns a census of triad motifs that span -a one-mode and a two-mode network. -} -} -\examples{ -network_dyad_census(manynet::ison_algebra) -network_triad_census(manynet::ison_adolescents) -marvel_friends <- manynet::to_unsigned(manynet::ison_marvel_relationships, "positive") -(mixed_cen <- network_mixed_census(marvel_friends, manynet::ison_marvel_teams)) -} -\references{ -Davis, James A., and Samuel Leinhardt. 1967. -“\href{https://files.eric.ed.gov/fulltext/ED024086.pdf}{The Structure of Positive Interpersonal Relations in Small Groups}.” 55. - -Hollway, James, Alessandro Lomi, Francesca Pallotti, and Christoph Stadtfeld. 2017. -“Multilevel Social Spaces: The Network Dynamics of Organizational Fields.” -\emph{Network Science} 5(2): 187–212. -\doi{10.1017/nws.2017.8} -} -\seealso{ -Other motifs: -\code{\link{brokerage_census}}, -\code{\link{node_census}} -} -\concept{motifs} diff --git a/man/node_census.Rd b/man/node_census.Rd deleted file mode 100644 index a9841eda..00000000 --- a/man/node_census.Rd +++ /dev/null @@ -1,105 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/motif_census.R -\name{node_census} -\alias{node_census} -\alias{node_tie_census} -\alias{node_triad_census} -\alias{node_quad_census} -\alias{node_path_census} -\title{Censuses of nodes' motifs} -\usage{ -node_tie_census(.data) - -node_triad_census(.data) - -node_quad_census(.data) - -node_path_census(.data) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} -} -\description{ -These functions include ways to take a census of the positions of nodes -in a network: -\itemize{ -\item \code{node_tie_census()} returns a census of the ties in a network. -For directed networks, out-ties and in-ties are bound together. -for multiplex networks, the various types of ties are bound together. -\item \code{node_triad_census()} returns a census of the triad configurations -nodes are embedded in. -\item \code{node_quad_census()} returns a census of nodes' positions -in motifs of four nodes. -\item \code{node_path_census()} returns the shortest path lengths -of each node to every other node in the network. -} -} -\section{Quad census}{ - -The quad census uses the \code{{oaqc}} package to do -the heavy lifting of counting the number of each orbits. -See \code{vignette('oaqc')}. -However, our function relabels some of the motifs -to avoid conflicts and improve some consistency with -other census-labelling practices. -The letter-number pairing of these labels indicate -the number and configuration of ties. -For now, we offer a rough translation:\tabular{ll}{ - migraph \tab Ortmann and Brandes \cr - E4 \tab co-K4 \cr - I40, I41 \tab co-diamond \cr - H4 \tab co-C4 \cr - L42, L41, L40 \tab co-paw \cr - D42, D40 \tab co-claw \cr - U42, U41 \tab P4 \cr - Y43, Y41 \tab claw \cr - P43, P42, P41 \tab paw \cr - 04 \tab C4 \cr - Z42, Z43 \tab diamond \cr - X4 \tab K4 \cr -} - - -See also \href{https://www.graphclasses.org/smallgraphs.html#nodes4}{this list of graph classes}. -} - -\examples{ -task_eg <- manynet::to_named(manynet::to_uniplex(manynet::ison_algebra, "tasks")) -(tie_cen <- node_tie_census(task_eg)) -(triad_cen <- node_triad_census(task_eg)) -node_quad_census(manynet::ison_southern_women) -node_path_census(manynet::ison_adolescents) -node_path_census(manynet::ison_southern_women) -} -\references{ -Davis, James A., and Samuel Leinhardt. 1967. -“\href{https://files.eric.ed.gov/fulltext/ED024086.pdf}{The Structure of Positive Interpersonal Relations in Small Groups}.” 55. - -Ortmann, Mark, and Ulrik Brandes. 2017. -“Efficient Orbit-Aware Triad and Quad Census in Directed and Undirected Graphs.” -\emph{Applied Network Science} 2(1):13. -\doi{10.1007/s41109-017-0027-2}. - -Dijkstra, Edsger W. 1959. -"A note on two problems in connexion with graphs". -\emph{Numerische Mathematik} 1, 269-71. -\doi{10.1007/BF01386390}. - -Opsahl, Tore, Filip Agneessens, and John Skvoretz. 2010. -"Node centrality in weighted networks: Generalizing degree and shortest paths". -\emph{Social Networks} 32(3): 245-51. -\doi{10.1016/j.socnet.2010.03.006}. -} -\seealso{ -Other motifs: -\code{\link{brokerage_census}}, -\code{\link{network_census}} -} -\concept{motifs} From 6fb85db13872f24dac6ca3cca87a219264d7948c Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:21:08 +0200 Subject: [PATCH 67/97] Migrated residual classes to manynet --- NAMESPACE | 208 ---------------------------------------- R/class_measures.R | 173 --------------------------------- R/class_members.R | 185 ----------------------------------- R/class_motifs.R | 50 ---------- man/brokerage_census.Rd | 74 -------------- 5 files changed, 690 deletions(-) delete mode 100644 R/class_measures.R delete mode 100644 R/class_members.R delete mode 100644 R/class_motifs.R delete mode 100644 man/brokerage_census.Rd diff --git a/NAMESPACE b/NAMESPACE index 6b3b3fc4..dc641af1 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,27 +3,13 @@ S3method(glance,netlm) S3method(glance,netlogit) S3method(plot,graph_test) -S3method(plot,matrix) S3method(plot,netlm) S3method(plot,netlogit) -S3method(plot,network_measures) S3method(plot,network_test) -S3method(plot,node_measure) -S3method(plot,node_member) -S3method(plot,tie_measure) S3method(print,graph_measure) S3method(print,graph_motif) S3method(print,graph_test) -S3method(print,network_measure) -S3method(print,network_motif) S3method(print,network_test) -S3method(print,node_measure) -S3method(print,node_member) -S3method(print,node_motif) -S3method(print,tie_measure) -S3method(summary,node_measure) -S3method(summary,node_member) -S3method(summary,node_motif) S3method(tidy,netlm) S3method(tidy,netlogit) export("%>%") @@ -33,8 +19,6 @@ export(.N) export(aes) export(as.network) export(bind_edges) -export(cluster_concor) -export(cluster_hierarchical) export(edge_betweenness) export(edge_bridges) export(edge_closeness) @@ -78,146 +62,13 @@ export(guides) export(is.network) export(is.tbl_graph) export(is_igraph) -export(k_elbow) -export(k_silhouette) -export(k_strict) export(labs) export(mutate) -export(network_adhesion) -export(network_assortativity) -export(network_balance) -export(network_betweenness) -export(network_brokerage_census) -export(network_change) -export(network_closeness) -export(network_cohesion) -export(network_components) -export(network_congruency) -export(network_connectedness) -export(network_core) -export(network_degree) -export(network_density) -export(network_diameter) -export(network_diversity) -export(network_dyad_census) -export(network_efficiency) -export(network_eigenvector) -export(network_equivalency) -export(network_factions) -export(network_harmonic) -export(network_hazard) -export(network_heterophily) export(network_homophily) -export(network_immunity) -export(network_indegree) -export(network_independence) -export(network_infection_length) -export(network_length) -export(network_mixed_census) -export(network_modularity) -export(network_outdegree) -export(network_reach) -export(network_reciprocity) export(network_reg) -export(network_reproduction) -export(network_richclub) -export(network_richness) -export(network_scalefree) -export(network_smallworld) -export(network_spatial) -export(network_stability) -export(network_transitivity) -export(network_transmissibility) -export(network_triad_census) -export(network_upperbound) export(node_adopter) -export(node_adoption_time) -export(node_alpha) -export(node_automorphic_equivalence) -export(node_betweenness) -export(node_bridges) -export(node_brokerage_census) -export(node_brokering) -export(node_brokering_activity) -export(node_brokering_exclusivity) -export(node_closeness) -export(node_components) -export(node_constraint) -export(node_core) -export(node_coreness) export(node_cuts) -export(node_deg) -export(node_degree) -export(node_diversity) -export(node_eccentricity) -export(node_edge_betweenness) -export(node_efficiency) -export(node_effsize) -export(node_eigenvector) -export(node_equivalence) -export(node_exposure) -export(node_fast_greedy) -export(node_flow) -export(node_fluid) -export(node_harmonic) -export(node_heterophily) -export(node_hierarchy) export(node_homophily) -export(node_in_automorphic) -export(node_in_betweenness) -export(node_in_component) -export(node_in_core) -export(node_in_eigen) -export(node_in_equivalence) -export(node_in_fluid) -export(node_in_greedy) -export(node_in_infomap) -export(node_in_leiden) -export(node_in_louvain) -export(node_in_optimal) -export(node_in_partition) -export(node_in_regular) -export(node_in_roulette) -export(node_in_spinglass) -export(node_in_strong) -export(node_in_structural) -export(node_in_walktrap) -export(node_in_weak) -export(node_indegree) -export(node_induced) -export(node_infection_length) -export(node_infomap) -export(node_information) -export(node_kernighanlin) -export(node_leading_eigen) -export(node_leiden) -export(node_louvain) -export(node_multidegree) -export(node_neighbours_degree) -export(node_optimal) -export(node_outdegree) -export(node_pagerank) -export(node_path_census) -export(node_posneg) -export(node_power) -export(node_quad_census) -export(node_reach) -export(node_reciprocity) -export(node_redundancy) -export(node_regular_equivalence) -export(node_richness) -export(node_roulette) -export(node_spinglass) -export(node_strong_components) -export(node_structural_equivalence) -export(node_thresholds) -export(node_tie_census) -export(node_transitivity) -export(node_triad_census) -export(node_walktrap) -export(node_weak_components) -export(over_time) -export(over_waves) export(rename) export(test_distribution) export(test_fit) @@ -225,15 +76,9 @@ export(test_gof) export(test_permutation) export(test_random) export(tidy) -export(tie_betweenness) -export(tie_closeness) -export(tie_cohesion) -export(tie_degree) -export(tie_eigenvector) export(with_graph) export(xlab) export(ylab) -import(tidygraph) importFrom(dplyr,"%>%") importFrom(dplyr,bind_cols) importFrom(dplyr,left_join) @@ -243,75 +88,23 @@ importFrom(future,plan) importFrom(generics,glance) importFrom(generics,tidy) importFrom(ggplot2,aes) -importFrom(ggplot2,element_blank) -importFrom(ggplot2,element_text) -importFrom(ggplot2,geom_hline) -importFrom(ggplot2,geom_tile) -importFrom(ggplot2,geom_vline) importFrom(ggplot2,ggplot) importFrom(ggplot2,ggsave) importFrom(ggplot2,ggtitle) importFrom(ggplot2,guides) importFrom(ggplot2,labs) -importFrom(ggplot2,scale_fill_gradient) -importFrom(ggplot2,scale_x_discrete) -importFrom(ggplot2,scale_y_discrete) -importFrom(ggplot2,theme) -importFrom(ggplot2,theme_grey) importFrom(ggplot2,xlab) importFrom(ggplot2,ylab) -importFrom(igraph,V) -importFrom(igraph,adhesion) -importFrom(igraph,alpha_centrality) -importFrom(igraph,assortativity_degree) -importFrom(igraph,cohesion) -importFrom(igraph,components) -importFrom(igraph,degree) -importFrom(igraph,delete_vertices) -importFrom(igraph,diameter) -importFrom(igraph,distances) -importFrom(igraph,eccentricity) -importFrom(igraph,edge_betweenness) -importFrom(igraph,edge_density) -importFrom(igraph,fit_power_law) -importFrom(igraph,graph_from_incidence_matrix) -importFrom(igraph,is_bipartite) importFrom(igraph,is_igraph) -importFrom(igraph,ivs_size) -importFrom(igraph,knn) -importFrom(igraph,make_ego_graph) -importFrom(igraph,mean_distance) -importFrom(igraph,power_centrality) -importFrom(igraph,reciprocity) -importFrom(igraph,transitivity) -importFrom(igraph,triad_census) -importFrom(igraph,vcount) -importFrom(manynet,as_igraph) importFrom(network,as.network) importFrom(network,is.network) importFrom(purrr,flatten) -importFrom(rlang,"%||%") -importFrom(rlang,.data) -importFrom(rlang,enquo) -importFrom(rlang,eval_tidy) -importFrom(sna,brokerage) -importFrom(sna,flowbet) -importFrom(sna,gcor) -importFrom(sna,infocent) -importFrom(stats,as.dist) importFrom(stats,as.formula) importFrom(stats,binomial) -importFrom(stats,coef) -importFrom(stats,complete.cases) -importFrom(stats,cor) -importFrom(stats,cutree) importFrom(stats,df.residual) importFrom(stats,glm.fit) -importFrom(stats,hclust) -importFrom(stats,median) importFrom(stats,pchisq) importFrom(stats,quantile) -importFrom(tidygraph,"%E>%") importFrom(tidygraph,.E) importFrom(tidygraph,.G) importFrom(tidygraph,.N) @@ -320,4 +113,3 @@ importFrom(tidygraph,is.tbl_graph) importFrom(tidygraph,mutate) importFrom(tidygraph,rename) importFrom(tidygraph,with_graph) -importFrom(tidyr,pivot_longer) diff --git a/R/class_measures.R b/R/class_measures.R deleted file mode 100644 index 64a245c4..00000000 --- a/R/class_measures.R +++ /dev/null @@ -1,173 +0,0 @@ -make_node_measure <- function(out, .data) { - if(manynet::is_labelled(.data)) names(out) <- manynet::node_names(.data) - class(out) <- c("node_measure", class(out)) - attr(out, "mode") <- manynet::node_mode(.data) - out -} - -make_tie_measure <- function(out, .data) { - class(out) <- c("tie_measure", class(out)) - out -} - -make_network_measure <- function(out, .data) { - class(out) <- c("network_measure", class(out)) - attr(out, "mode") <- manynet::network_dims(.data) - out -} - -make_network_measures <- function(out, .data) { - time <- value <- NULL - out <- dplyr::as_tibble(out) %>% - dplyr::mutate(time = as.numeric(names(out))) %>% - dplyr::select(time, value) - class(out) <- c("network_measures", class(out)) - attr(out, "mode") <- manynet::network_dims(.data) - out -} - -# Printing #### -#' @export -print.node_measure <- function(x, ..., - n = NULL, digits = 3){ - if (any(attr(x, "mode"))) { - for(m in c(FALSE, TRUE)){ - print_tblvec(y = round(as.numeric(x)[attr(x, "mode") == m], - digits = digits), - names = list(names(x)[attr(x, "mode") == m]), - n = n) - if(!m) cat("\n") - } - } else { - print_tblvec(y = round(as.numeric(x), - digits = digits), - names = list(names(x)), - n = n) - } -} - -#' @export -print.tie_measure <- function(x, ..., - n = NULL, - digits = 3) { - print_tblvec(y = round(as.numeric(x), digits = digits), - names = list(names(x)), n = n) -} - -#' @export -print.network_measure <- function(x, ..., - digits = 3) { - if (length(attr(x, "mode")) == 1) { - print(as.numeric(x), digits = digits) - } else { - y <- as.numeric(x) - if (length(y) == 2) - names(y) <- paste("Mode", seq_len(length(attr(x, "mode")))) - print(y, digits = digits) - } -} - -# @param FUN A function by which the values should be aggregated -# or summarised when a membership vector is given. By default `mean()`. -# summary(node_degree(mpn_elite_mex), -# membership = node_structural_equivalence(mpn_elite_mex, k = "elbow")) -#' @export -summary.node_measure <- function(object, ..., - membership, - FUN = mean) { - if(missing(membership)){ - out <- c(Minimum = min(object, na.rm = TRUE), - Maximum = max(object, na.rm = TRUE), - Mean = mean(object, na.rm = TRUE), - StdDev = stats::sd(object, na.rm = TRUE), - Missing = sum(is.na(object)) - ) - } else { - out <- vapply(unique(membership), - function(x) FUN(object[membership == x]), FUN.VALUE = 1) - names(out) <- unique(membership) - } - out -} - -# Plotting #### -#' @export -plot.node_measure <- function(x, type = c("h", "d"), ...) { - #type <- match.arg(type) - density <- NULL - if (is.null(attr(x, "mode"))) attr(x, "mode") <- rep(FALSE, length(x)) - data <- data.frame(Score = x, Mode = attr(x, "mode")) - if (length(type) == 2) { - p <- ggplot2::ggplot(data = data, ggplot2::aes(x = .data$Score)) + - ggplot2::geom_histogram(ggplot2::aes(y = ggplot2::after_stat(density)), - binwidth = ifelse(max(data$Score) > 1, 1, - ifelse(max(data$Score) > - .1, .1, .01))) + - ggplot2::geom_density(col = 2) + - ggplot2::scale_y_continuous("Frequency", sec.axis = - ggplot2::sec_axis(~ ., breaks = c(0,1), - name = "Density")) - } else if (length(type) == 1 & type == "h") { - p <- ggplot2::ggplot(data = data, ggplot2::aes(x = .data$Score)) + - ggplot2::geom_histogram(ggplot2::aes(y = ggplot2::after_stat(density)), - binwidth = ifelse(max(data$Score) > 1, 1, - ifelse(max(data$Score) > - .1, .1, .01))) + - ggplot2::labs(x = "Density", y = "Frequency") - } else if (length(type) == 1 & type == "d") { - p <- ggplot2::ggplot(data = data, ggplot2::aes(x = .data$Score)) + - ggplot2::geom_density(col = 2) + - ggplot2::ylab("Density") - } - p + - ggplot2::theme_classic() + - ggplot2::theme(panel.grid.major = ggplot2::element_line(colour = "grey90")) -} - -#' @export -plot.tie_measure <- function(x, type = c("h", "d"), ...) { - type <- match.arg(type) - data <- data.frame(Score = x) - if (type == "h") { - p <- ggplot2::ggplot(data = data) + - ggplot2::geom_histogram(ggplot2::aes(x = .data$Score), - binwidth = ifelse(max(data$Score) > 1, 1, - ifelse(max(data$Score) > .1, - .1, - .01))) + - ggplot2::ylab("Frequency") - } else { - p <- ggplot2::ggplot(data = data) + - ggplot2::geom_density(ggplot2::aes(x = .data$Score)) + - ggplot2::ylab("Density") - } - p + ggplot2::theme_classic() + - ggplot2::theme(panel.grid.major = ggplot2::element_line(colour = "grey90")) -} - -#' @export -plot.network_measures <- function(x, ...) { - ggplot2::ggplot(data = x, ggplot2::aes(x = .data$time, y = .data$value)) + - ggplot2::geom_line() + - ggplot2::theme_minimal() + - ggplot2::xlab("Time") + - ggplot2::ylab("Value") -} - - -# make tblvec #### -print_tblvec <- function(y, names, n){ - mat <- matrix(y, dimnames = names) - mat <- t(mat) - out <- as.data.frame(mat) - tibs <- dplyr::tibble(out, .name_repair = "unique") - setup <- pillar::tbl_format_setup(tibs, width = n) - body <- pillar::tbl_format_body(tibs, setup)[c(TRUE, FALSE, TRUE)] - if(setup$extra_cols_total > 0){ - print(body) - cat(pillar::style_subtle(paste("# ... with", - setup$extra_cols_total, - "more values from this nodeset unprinted.", - "Use `print(..., n = Inf)` to print all values."))) - } else print(body) -} diff --git a/R/class_members.R b/R/class_members.R deleted file mode 100644 index 2335a1d3..00000000 --- a/R/class_members.R +++ /dev/null @@ -1,185 +0,0 @@ -make_node_member <- function(out, .data) { - if(is.numeric(out)) - out <- MORELETTERS[out] - if (manynet::is_labelled(.data)) names(out) <- manynet::node_names(.data) - class(out) <- c("node_member", class(out)) - attr(out, "mode") <- manynet::node_mode(.data) - out -} - -MORELETTERS <- c(LETTERS, sapply(LETTERS, function(x) paste0(x, LETTERS))) - -#' @export -print.node_member <- function(x, ..., n = NULL) { - cat(pillar::style_subtle(paste(length(unique(x)), "groups\n"))) - if (any(attr(x, "mode"))) { - for(m in c(FALSE, TRUE)){ - suppressWarnings(print_tblvec(y = x[attr(x, "mode") == m], - names = list(names(x)[attr(x, "mode") == m]), - n = n)) - if(!m) cat("\n") - } - } else { - suppressWarnings(print_tblvec(y = x, - names = list(names(x)), - n = n)) - } -} - -#' @export -summary.node_member <- function(object, ..., - n = 6, - digits = 3) { - if (any(attr(object, "mode"))) { - for (i in names(table(object))) { - if (i == names(table(object))[1]) cat(i, "\n") - else cat("\n", i, "\n") - if (!is.null(names(object))) { - y <- paste(names(object[object == i & attr(object, "mode")]), collapse = ", ") - z <- paste(names(object[object == i & !attr(object, "mode")]), collapse = ", ") - } else { - y <- paste(which(object == i & attr(object, "mode")), collapse = ", ") - z <- paste(which(object == i & !attr(object, "mode")), collapse = ", ") - } - cat(" ", y, "\n") - cat(" ", z) - } - } else { - for (i in names(table(object))) { - cat(pillar::style_subtle(paste0("Class ", i, ":"))) - if (!is.null(names(object))) - y <- paste(names(object[object == i]), collapse = ", ") - else - y <- paste(which(object == i), collapse = ", ") - cat(" ", y) - if (i != names(table(object))[length(table(object))]) cat("\n") - } - } -} - -#' @importFrom stats cutree -#' @export -plot.node_member <- function(x, ...) { - thisRequires("ggdendro") - hc <- attr(x, "hc") - k <- attr(x, "k") - memb <- x[hc$order] - clust <- memb[!duplicated(memb)] - colors <- ifelse(match(memb, clust) %% 2, - "#000000", "#E20020") - ggdendro::ggdendrogram(hc, rotate = TRUE) + - ggplot2::geom_hline(yintercept = hc$height[length(hc$order) - k], - linetype = 2, - color = "#E20020") + - ggplot2::theme(axis.text.x = ggplot2::element_text(colour = "#5c666f"), - axis.text.y = suppressWarnings( - ggplot2::element_text(colour = colors))) -} - -# plot(as_matrix(ison_adolescents), -# membership = node_regular_equivalence(ison_adolescents, "e")) -# plot(as_matrix(ison_southern_women), -# membership = node_regular_equivalence(ison_southern_women, "e")) -#' @importFrom tidyr pivot_longer -#' @importFrom ggplot2 ggplot geom_tile aes scale_fill_gradient theme_grey labs theme scale_x_discrete scale_y_discrete geom_vline geom_hline element_blank element_text -#' @importFrom rlang .data -#' @export -plot.matrix <- function(x, ..., membership = NULL) { - - if (!manynet::is_twomode(x)) { - blocked_data <- manynet::as_matrix(x) - if (!is.null(membership)) blocked_data <- blocked_data[order(membership), - order(membership)] - } else if (manynet::is_twomode(x) && - length(intersect(membership[!manynet::node_mode(x)], - membership[!manynet::node_mode(x)])) > 0) { - blocked_data <- manynet::as_matrix(manynet::to_multilevel(x)) - if (!is.null(membership)) blocked_data <- blocked_data[order(membership), - order(membership)] - } else { - blocked_data <- manynet::as_matrix(x) - } - - plot_data <- as.data.frame(blocked_data) %>% - dplyr::mutate(Var1 = rownames(blocked_data)) %>% - tidyr::pivot_longer(!.data[["Var1"]], names_to = "Var2", values_to = "value") - g <- ggplot2::ggplot(plot_data, ggplot2::aes(.data[["Var2"]], .data[["Var1"]])) + - ggplot2::theme_grey(base_size = 9) + - ggplot2::labs(x = "", y = "") + - ggplot2::theme( - legend.position = "none", - axis.ticks = ggplot2::element_blank(), - axis.text.y = ggplot2::element_text( - size = 9 * 0.8, - colour = "grey50" - ), - axis.text.x = ggplot2::element_text( - size = 9 * 0.8, - angle = 30, hjust = 0, - colour = "grey50" - ) - ) + - ggplot2::geom_tile(ggplot2::aes(fill = .data[["value"]]), - colour = "white" - ) - - # Color for signed networks - if (manynet::is_signed(x)) { - g <- g + - ggplot2::scale_fill_gradient2(high = "#003049", - mid = "white", - low = "#d62828") - } else { - g <- g + - ggplot2::scale_fill_gradient( - low = "white", - high = "black" - ) - } - - # Structure for multimodal networks - if (!manynet::is_twomode(x)) { - g <- g + - ggplot2::scale_x_discrete(expand = c(0, 0), position = "top", - limits = colnames(blocked_data) - ) + - ggplot2::scale_y_discrete(expand = c(0, 0), - limits = rev(rownames(blocked_data)) - ) - if (!is.null(membership)) - g <- g + ggplot2::geom_vline( - xintercept = c(1 + which(diff(membership[order(membership)]) != 0)) - - .5, - colour = "red" - ) + - ggplot2::geom_hline( - yintercept = nrow(blocked_data) - - c(1 + which(diff(membership[order(membership)]) != 0)) + - 1.5, - colour = "red" - ) - } else { - g <- g + - ggplot2::scale_y_discrete(expand = c(0, 0), - limits = rev(rownames(x[["blocked.data"]])[x[["order.vector"]][["nodes1"]]]) - ) + - ggplot2::scale_x_discrete(expand = c(0, 0), position = "top", - limits = colnames(x[["blocked.data"]])[x[["order.vector"]][["nodes2"]]] - ) + - ggplot2::geom_vline( - xintercept = - c(1 + which(diff(x[["block.membership"]][["nodes2"]]) != 0)) - - .5, - colour = "blue" - ) + - ggplot2::geom_hline( - yintercept = nrow(x[["blocked.data"]]) - - c(1 + which(diff(x[["block.membership"]][["nodes1"]]) != 0)) - + 1.5, - colour = "red" - ) - } - g -} - -elementwise.all.equal <- Vectorize(function(x, y) {isTRUE(all.equal(x, y))}) diff --git a/R/class_motifs.R b/R/class_motifs.R deleted file mode 100644 index 75d7fc42..00000000 --- a/R/class_motifs.R +++ /dev/null @@ -1,50 +0,0 @@ -make_node_motif <- function(out, .data) { - class(out) <- c("node_motif", class(out)) - attr(out, "mode") <- manynet::node_mode(.data) - out -} - -make_network_motif <- function(out, .data) { - class(out) <- c("network_motif", class(out)) - attr(out, "mode") <- manynet::network_dims(.data) - out -} - -#' @export -print.node_motif <- function(x, ..., - n = 6, - digits = 3) { - if(!is.null(attr(x, "dimnames")[[1]])){ - x <- data.frame(names = attr(x, "dimnames")[[1]], x) - } - if (any(attr(x, "mode"))) { - print(dplyr::tibble(as.data.frame(x)[!attr(x, "mode")]), n = n) - print(dplyr::tibble(as.data.frame(x)[attr(x, "mode")]), n = n) - } else { - print(dplyr::tibble(as.data.frame(x)), n = n) - } -} - -# summary(node_triad_census(mpn_elite_mex), -# membership = node_regular_equivalence(mpn_elite_mex, "elbow")) -#' @export -summary.node_motif <- function(object, ..., - membership, - FUN = mean) { - out <- t(sapply(unique(membership), function(x) { - if (sum(membership==x)==1) object[membership==x,] - else apply(object[membership == x, ], 2, FUN) - })) - rownames(out) <- paste("Block", unique(membership)) - dplyr::tibble(as.data.frame(out)) -} - -#' @export -print.network_motif <- function(x, ...) { - names <- list(names(x)) - x <- as.numeric(x) - mat <- matrix(x, dimnames = names) - mat <- t(mat) - out <- as.data.frame(mat) - print(dplyr::tibble(out)) -} diff --git a/man/brokerage_census.Rd b/man/brokerage_census.Rd deleted file mode 100644 index 75daea70..00000000 --- a/man/brokerage_census.Rd +++ /dev/null @@ -1,74 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/motif_census.R -\name{brokerage_census} -\alias{brokerage_census} -\alias{node_brokerage_census} -\alias{network_brokerage_census} -\alias{node_brokering_activity} -\alias{node_brokering_exclusivity} -\alias{node_brokering} -\title{Censuses of brokerage motifs} -\usage{ -node_brokerage_census(.data, membership, standardized = FALSE) - -network_brokerage_census(.data, membership, standardized = FALSE) - -node_brokering_activity(.data, membership) - -node_brokering_exclusivity(.data, membership) - -node_brokering(.data, membership) -} -\arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - -\item{membership}{A vector of partition membership as integers.} - -\item{standardized}{Whether the score should be standardized -into a \emph{z}-score indicating how many standard deviations above -or below the average the score lies.} -} -\description{ -These functions include ways to take a census of the brokerage positions of nodes -in a network: -\itemize{ -\item \code{node_brokerage_census()} returns the Gould-Fernandez brokerage -roles played by nodes in a network. -\item \code{network_brokerage_census()} returns the Gould-Fernandez brokerage -roles in a network. -} -} -\examples{ -node_brokerage_census(manynet::ison_networkers, "Discipline") -network_brokerage_census(manynet::ison_networkers, "Discipline") -node_brokering_exclusivity(ison_networkers, "Discipline") -} -\references{ -Gould, R.V. and Fernandez, R.M. 1989. -“Structures of Mediation: A Formal Approach to Brokerage in Transaction Networks.” -\emph{Sociological Methodology}, 19: 89-126. - -Jasny, Lorien, and Mark Lubell. 2015. -“Two-Mode Brokerage in Policy Networks.” -\emph{Social Networks} 41:36–47. -\doi{10.1016/j.socnet.2014.11.005}. - -Hamilton, Matthew, Jacob Hileman, and Orjan Bodin. 2020. -"Evaluating heterogeneous brokerage: New conceptual and methodological approaches -and their application to multi-level environmental governance networks" -\emph{Social Networks} 61: 1-10. -\doi{10.1016/j.socnet.2019.08.002} -} -\seealso{ -Other motifs: -\code{\link{network_census}}, -\code{\link{node_census}} -} -\concept{motifs} From 607c7ec66dfb8d123a32884d38c6639982a93ce1 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:21:30 +0200 Subject: [PATCH 68/97] Migrated community tutorial to manynet --- inst/tutorials/tutorial4/community.Rmd | 772 -------- inst/tutorials/tutorial4/community.html | 2176 ----------------------- 2 files changed, 2948 deletions(-) delete mode 100644 inst/tutorials/tutorial4/community.Rmd delete mode 100644 inst/tutorials/tutorial4/community.html diff --git a/inst/tutorials/tutorial4/community.Rmd b/inst/tutorials/tutorial4/community.Rmd deleted file mode 100644 index 0889068c..00000000 --- a/inst/tutorials/tutorial4/community.Rmd +++ /dev/null @@ -1,772 +0,0 @@ ---- -title: "Community" -author: "by James Hollway" -output: - learnr::tutorial: - theme: journal -runtime: shiny_prerendered -description: > - This tutorial aims to teach you how to calculate various cohesion measures, - as well as detect communities using a variety of algorithms. ---- - -```{r setup, include=FALSE} -library(learnr) -library(patchwork) -library(manynet) -library(migraph) -knitr::opts_chunk$set(echo = FALSE) - -friends <- to_uniplex(ison_algebra, "friends") -social <- to_uniplex(ison_algebra, "social") -tasks <- to_uniplex(ison_algebra, "tasks") -``` - - -## Setting up - -The data we're going to use here, "ison_algebra", is included in the `{manynet}` package. -Do you remember how to call the data? -Can you find out some more information about it? - -```{r data, exercise = TRUE, purl = FALSE} - -``` - -```{r data-hint-1, purl = FALSE} -# Let's call and load the 'ison_algebra' dataset -data("ison_algebra", package = "manynet") -# Or you can retrieve like this: -ison_algebra <- manynet::ison_algebra -``` - -```{r data-hint-2, purl = FALSE} -# If you want to learn more about the 'ison_algebra' dataset, use the following function (below) -?manynet::ison_algebra -``` - -```{r data-solution} -data("ison_algebra", package = "manynet") -?manynet::ison_algebra -# If you want to see the network object, you can run the name of the object -ison_algebra -# or print the code with brackets at the front and end of the code -(ison_algebra <- manynet::ison_algebra) -``` - -We can see after printing the object that the dataset is multiplex, -meaning that it contains several different types of ties: -friendship (friends), social (social) and task interactions (tasks). - -### Adding names - -The network is also anonymous, but I think it would be nice to add some names, -even if it's just pretend. -Luckily, `{manynet}` has a function for this, `to_named()`. -This makes plotting the network just a wee bit more accessible and interpretable. -Let's try adding names and graphing the network now: - -```{r addingnames, exercise=TRUE, exercise.setup = "data", purl = FALSE} - -``` - -```{r addingnames-hint-1, purl = FALSE} -ison_algebra <- to_named(ison_algebra) -``` - -```{r addingnames-hint-2, purl = FALSE} -graphr(ison_algebra) -``` - -```{r addingnames-solution} -ison_algebra <- to_named(ison_algebra) -graphr(ison_algebra) -``` - -Note that you will likely get a different set of names, -as they are assigned randomly from a pool of (American) first names. - -### Separating multiplex networks - -As a multiplex network, -there are actually three different types of ties (friends, social, and tasks) -in this network. -We can extract them and graph them separately using `to_uniplex()`: - -```{r separatingnets, exercise=TRUE, exercise.setup = "data", purl = FALSE} - -``` - -```{r separatingnets-hint-1, purl = FALSE} -# to_uniplex extracts ties of a single type, -# focusing on the 'friends' tie attribute here -friends <- to_uniplex(ison_algebra, "friends") -gfriend <- graphr(friends) + ggtitle("Friendship") -``` - -```{r separatingnets-hint-2, purl = FALSE} -# now let's focus on the 'social' tie attribute -social <- to_uniplex(ison_algebra, "social") -gsocial <- graphr(social) + ggtitle("Social") -``` - -```{r separatingnets-hint-3, purl = FALSE} -# and the 'tasks' tie attribute -tasks <- to_uniplex(ison_algebra, "tasks") -gtask <- graphr(tasks) + ggtitle("Task") -``` - -```{r separatingnets-hint-4, purl = FALSE} -# now, let's compare each attribute's graph, side-by-side -gfriend + gsocial + gtask -# if you get an error here, you may need to install and load -# the package 'patchwork'. -# It's highly recommended for assembling multiple plots together. -# Otherwise you can just plot them separately on different lines. -``` - -```{r separatingnets-solution} -friends <- to_uniplex(ison_algebra, "friends") -gfriend <- graphr(friends) + ggtitle("Friendship") - -social <- to_uniplex(ison_algebra, "social") -gsocial <- graphr(social) + ggtitle("Social") - -tasks <- to_uniplex(ison_algebra, "tasks") -gtask <- graphr(tasks) + ggtitle("Task") - -# We now have three separate networks depicting each type of tie from the ison_algebra network: -gfriend + gsocial + gtask -``` - -Note also that these are weighted networks. -`graphr()` automatically recognises these different weights and plots them. -Where useful (less dense directed networks), -`graphr()` also bends reciprocated arcs. -What (else) can we say about these three networks? - -## Cohesion - -Let's concentrate on the task network for now and calculate a few basic -measures of cohesion: -density, reciprocity, transitivity, and components. - -### Density - -Because this is a directed network, we can calculate the density as: - -```{r dens-explicit, exercise=TRUE, exercise.setup = "separatingnets", purl = FALSE} - -``` - -```{r dens-explicit-solution} -# calculating network density manually according to equation -network_ties(tasks)/(network_nodes(tasks)*(network_nodes(tasks)-1)) -``` - -but we can also just use the `{migraph}` function... - -```{r dens, exercise=TRUE, exercise.setup = "separatingnets", purl = FALSE} - -``` - -```{r dens-solution} -network_density(tasks) -``` - -Note that the various measures in `{migraph}` print results to three decimal points -by default, but the underlying result retains the same recurrence. -So same result... - -```{r dens-qa, echo=FALSE, purl = FALSE} -question("Is this network's density high or low?", - answer("High", - message = "The closer the value is to 1, the more dense the network and the more cohesive the network is as a whole."), - answer("Low", - correct = TRUE, - message = "The closer the value is to 0, the sparser the network and the less cohesive the network is as a whole.") -) -``` - -### Closure - -Next let's calculate _reciprocity_ in the task network. -While one could do this by hand, -it's more efficient to do this using the `{migraph}` package. -Can you guess the correct name of the function? - -```{r recip, exercise=TRUE, exercise.setup = "separatingnets", purl = FALSE} - -``` - -```{r recip-solution} -network_reciprocity(tasks) -# this function calculates the amount of reciprocity in the whole network -``` - -And let's calculate _transitivity_ in the task network. -Again, can you guess the correct name of this function? - -```{r trans, exercise=TRUE, exercise.setup = "separatingnets", purl = FALSE} - -``` - -```{r trans-solution} -network_transitivity(tasks) -# this function calculates the amount of transitivity in the whole network -``` - -We have collected measures of the task network's reciprocity -and transitivity, but we still need to interpret these measures. -These measures do not speak for themselves. - -```{r trans-interp, echo=FALSE, purl = FALSE} -question("What can we say about task closure in this network? Choose all that apply.", - answer("Transitivity for the task network is 0.568", - correct = TRUE), - answer("Transitivity for the task network is -0.568", - message = "Transivitity must be between 0 and 1."), - answer("Transitivity is quite low in this network", - message = "Transitivity is usually around 0.3 in most social networks."), - answer("Transitivity is quite high in this network", - correct = TRUE), - answer("Transitivity is likely higher in the task network than the friendship network", - correct = TRUE), - random_answer_order = TRUE, - allow_retry = TRUE -) -``` - -### Components - -Now let's look at the friendship network, 'friends'. -We're interested here in how many _components_ there are. -By default, the `network_components()` function will -return the number of _strong_ components for directed networks. -For _weak_ components, you will need to first make the network undirected. -Remember the difference between weak and strong components? - -```{r weak-strong, echo = FALSE, purl = FALSE} -question("Weak components...", - answer("don't care about tie direction when establishing components.", - correct = TRUE), - answer("care about tie direction when establishing components."), - allow_retry = TRUE -) -``` - -```{r comp-no, exercise=TRUE, exercise.setup = "separatingnets", purl = FALSE} - -``` - -```{r comp-no-hint-1, purl = FALSE} -network_components(friends) -# note that friends is a directed network -# you can see this by calling the object 'friends' -# or by running `manynet::is_directed(friends)` -``` - -```{r comp-no-hint-2, purl = FALSE} -# Now let's look at the number of components for objects connected by an undirected edge -# Note: to_undirected() returns an object with all tie direction removed, -# so any pair of nodes with at least one directed edge -# will be connected by an undirected edge in the new network. -network_components(to_undirected(friends)) -``` - -```{r comp-no-solution} -# note that friends is a directed network -network_components(friends) -network_components(to_undirected(friends)) -``` - -```{r comp-interp, echo = FALSE, purl = FALSE} -question("How many components are there?", - answer("2", - message = "There are more than 2 components."), - answer("3", - message = "There are 3 _weak_ components.", - correct = TRUE), - answer("4", - message = "There are 4 _strong_ components.", - correct = TRUE), - answer("5", - message = "There are fewer than 5 components."), - allow_retry = TRUE -) -``` - -So we know how many components there are, -but maybe we're also interested in which nodes are members of which components? -`node_components()` returns a membership vector -that can be used to color nodes in `graphr()`: - -```{r comp-memb, exercise=TRUE, exercise.setup = "separatingnets", purl = FALSE} - -``` - -```{r comp-memb-hint-1, purl = FALSE} -friends <- friends %>% - mutate(weak_comp = node_components(to_undirected(friends)), - strong_comp = node_components(friends)) -# node_components returns a vector of nodes' memberships to components in the network -# here, we are adding the nodes' membership to components as an attribute in the network -# alternatively, we can also use the function `add_node_attribute()` -# eg. `add_node_attribute(friends, "weak_comp", node_components(to_undirected(friends)))` -``` - -```{r comp-memb-hint-2, purl = FALSE} -graphr(friends, node_color = "weak_comp") + ggtitle("Weak components") + -graphr(friends, node_color = "strong_comp") + ggtitle("Strong components") -# by using the 'node_color' argument, we are telling graphr to colour -# the nodes in the graph according to the values of the 'weak_comp' attribute in the network -``` - -```{r comp-memb-solution} -friends <- friends %>% - mutate(weak_comp = node_components(to_undirected(friends)), - strong_comp = node_components(friends)) -graphr(friends, node_color = "weak_comp") + ggtitle("Weak components") + -graphr(friends, node_color = "strong_comp") + ggtitle("Strong components") -``` - -```{r node-comp-interp, echo = FALSE, purl = FALSE} -question("Why is there a difference between the weak and strong components results?", - answer("Because one node has only incoming ties.", - correct = TRUE), - answer("Because three nodes cannot reach any other nodes.", - correct = TRUE), - answer("Because there is an extra isolate."), - answer("Because the tie strength matters."), - random_answer_order = TRUE, - allow_retry = TRUE -) -``` - -## Community Detection - -Ok, the friendship network has 3-4 components, but how many 'groups' are there? -Just visually, it looks like there are two denser clusters within the main component. - -Today we'll use the 'friends' subgraph for exploring community detection methods. -For clarity and simplicity, -we will concentrate on the main component (the so-called 'giant' component) -and consider friendship undirected. -Can you guess how to make these changes to the 'friends' network? - -```{r manip-fri, exercise=TRUE, exercise.setup = "separatingnets", purl = FALSE} - -``` - -```{r manip-fri-hint-1, purl = FALSE} -# to_giant() returns an object that includes only the main component without any smaller components or isolates -(friends <- to_giant(friends)) -``` - -```{r manip-fri-hint-2, purl = FALSE} -(friends <- to_undirected(friends)) -``` - -```{r manip-fri-hint-3, purl = FALSE} -# now, let's graph the new network -graphr(friends) -``` - -```{r manip-fri-solution} -(friends <- to_giant(friends)) -(friends <- to_undirected(friends)) -graphr(friends) -``` - -Comparing `friends` before and after these operations, -you'll notice the number of ties decreases as reciprocated directed ties -are consolidated into single undirected ties, -and the number of nodes decreases as two isolates are removed. - -There is no one single best community detection algorithm. -Instead there are several, each with their strengths and weaknesses. -Since this is a rather small network, we'll focus on the following methods: -walktrap, edge betweenness, and fast greedy. -(Others are included in `{migraph}`/`{igraph}`) -As you use them, consider how they portray communities and consider which one(s) -afford a sensible view of the social world as cohesively organized. - -### Walktrap - -This algorithm detects communities through a series of short random walks, -with the idea that nodes encountered on any given random walk -are more likely to be within a community than not. -It was proposed by Pons and Latapy (2005). - -The algorithm initially treats all nodes as communities of their own, then -merges them into larger communities, still larger communities, and so on. -In each step a new community is created from two other communities, -and its ID will be one larger than the largest community ID so far. -This means that before the first merge we have n communities -(the number of vertices in the graph) numbered from zero to n-1. -The first merge creates community n, the second community n+1, etc. -This merge history is returned by the function: -` # ?igraph::cluster_walktrap` - -Note the "steps=" argument that specifies the length of the random walks. -While `{igraph}` sets this to 4 by default, -which is what is recommended by Pons and Latapy, -Waugh et al (2009) found that for many groups (Congresses), -these lengths did not provide the maximum modularity score. -To be thorough in their attempts to optimize modularity, they ran the walktrap -algorithm 50 times for each group (using random walks of lengths 1–50) and -selected the network partition with the highest modularity value from those 50. -They call this the "maximum modularity partition" and insert the parenthetical -"(though, strictly speaking, this cannot be proven to be the optimum without -computationally-prohibitive exhaustive enumeration (Brandes et al. 2008))." - -So let's try and get a community classification using the walktrap algorithm -with path lengths of the random walks specified to be 50. - -```{r walk, exercise=TRUE, exercise.setup = "separatingnets", purl = FALSE} - -``` - -```{r walk-hint-1, purl = FALSE} -# let's use the node_walktrap()function to create a hierarchical, -# agglomerative algorithm based on random walks, and assign it to -# an object - -friend_wt <- node_in_walktrap(friends, times=50) -friend_wt # note that it prints pretty, but underlying its just a vector: -``` - -```{r walk-hint-2, purl = FALSE} -c(friend_wt) - -# This says that dividing the graph into 2 communities maximises modularity, -# one with the nodes -which(friend_wt == 1) -# and the other -which(friend_wt == 2) -``` - -```{r walk-hint-3, purl = FALSE} -# resulting in a modularity of -network_modularity(friends, friend_wt) -``` - -```{r walk-solution} -friend_wt <- node_in_walktrap(friends, times=50) -friend_wt # note that it prints pretty, but underlying it is just a vector: -# c(friend_wt) - -# This says that dividing the graph into 2 communities maximises modularity, -# one with the nodes -which(friend_wt == 1) -# and the other -which(friend_wt == 2) -# resulting in a modularity of -network_modularity(friends, friend_wt) -``` - -We can also visualise the clusters on the original network -How does the following look? Plausible? - -```{r walkplot, exercise=TRUE, exercise.setup = "walk", purl = FALSE} -``` - -```{r walkplot-hint-1, purl = FALSE} -# plot 1: groups by node color - -friends <- friends %>% - mutate(walk_comm = friend_wt) -graphr(friends, node_color = "walk_comm") -``` - -```{r walkplot-hint-2, purl = FALSE} -#plot 2: groups by borders - -# to be fancy, we could even draw the group borders around the nodes using the node_group argument -graphr(friends, node_group = "walk_comm") -``` - -```{r walkplot-hint-3, purl = FALSE} -# plot 3: group and node colors - -# or both! -graphr(friends, - node_color = "walk_comm", - node_group = "walk_comm") + - ggtitle("Walktrap", - subtitle = round(network_modularity(friends, friend_wt), 3)) -# the function `round()` rounds the values to a specified number of decimal places -# here, we are telling it to round the network_modularity score to 3 decimal places, -# but the score is exactly 0.27 so only two decimal places are printed. -``` - -```{r walkplot-solution} -friends <- friends %>% - mutate(walk_comm = friend_wt) -graphr(friends, node_color = "walk_comm") -# to be fancy, we could even draw the group borders around the nodes using the node_group argument -graphr(friends, node_group = "walk_comm") -# or both! -graphr(friends, - node_color = "walk_comm", - node_group = "walk_comm") + - ggtitle("Walktrap", - subtitle = round(network_modularity(friends, friend_wt), 3)) -``` - -This can be helpful when polygons overlap to better identify membership -Or you can use node color and size to indicate other attributes... - -### Edge Betweenness - -Edge betweenness is like betweenness centrality but for ties not nodes. -The edge-betweenness score of an edge measures the number of -shortest paths from one vertex to another that go through it. - -The idea of the edge-betweenness based community structure detection is that -it is likely that edges connecting separate clusters have high edge-betweenness, -as all the shortest paths from one cluster to another must traverse through them. -So if we iteratively remove the edge with the highest edge-betweenness score -we will get a hierarchical map (dendrogram) of the communities in the graph. - -The following works similarly to walktrap, but no need to set a step length. - -```{r eb, exercise=TRUE, exercise.setup = "separatingnets", purl = FALSE} -``` - -```{r eb-solution} -friend_eb <- node_in_betweenness(friends) -friend_eb -``` - -How does community membership differ here from that found by walktrap? - -We can see how the edge betweenness community detection method works -here: http://jfaganuk.github.io/2015/01/24/basic-network-analysis/ - -To visualise the result: - -```{r ebplot, exercise=TRUE, exercise.setup = "eb", purl = FALSE} - -``` - -```{r ebplot-hint-1, purl = FALSE} -# create an object - -friends <- friends %>% - mutate(eb_comm = friend_eb) -``` - -```{r ebplot-hint-2, purl = FALSE} -# create a graph with a title and subtitle returning the modularity score - -graphr(friends, - node_color = "eb_comm", - node_group = "eb_comm") + - ggtitle("Edge-betweenness", - subtitle = round(network_modularity(friends, friend_eb), 3)) -``` - -```{r ebplot-solution} -friends <- friends %>% - mutate(eb_comm = friend_eb) -graphr(friends, - node_color = "eb_comm", - node_group = "eb_comm") + - ggtitle("Edge-betweenness", - subtitle = round(network_modularity(friends, friend_eb), 3)) -``` - -For more on this algorithm, see M Newman and M Girvan: Finding and -evaluating community structure in networks, Physical Review E 69, 026113 -(2004), https://arxiv.org/abs/cond-mat/0308217. - -### Fast Greedy - -This algorithm is the Clauset-Newman-Moore algorithm. -Whereas edge betweenness was divisive (top-down), -the fast greedy algorithm is agglomerative (bottom-up). - -At each step, the algorithm seeks a merge that would most increase modularity. -This is very fast, but has the disadvantage of being a greedy algorithm, -so it might not produce the best overall community partitioning, -although I personally find it both useful and in many cases quite "accurate". - -```{r fg, exercise=TRUE, exercise.setup = "separatingnets", purl = FALSE} - -``` - -```{r fg-hint-1, purl = FALSE} -friend_fg <- node_in_greedy(friends) -friend_fg # Does this result in a different community partition? -network_modularity(friends, friend_fg) # Compare this to the edge betweenness procedure -``` - -```{r fg-hint-2, purl = FALSE} -# Again, we can visualise these communities in different ways: -friends <- friends %>% - mutate(fg_comm = friend_fg) -graphr(friends, - node_color = "fg_comm", - node_group = "fg_comm") + - ggtitle("Fast-greedy", - subtitle = round(network_modularity(friends, friend_fg), 3)) -# -``` - -```{r fg-solution} -friend_fg <- node_in_greedy(friends) -friend_fg # Does this result in a different community partition? -network_modularity(friends, friend_fg) # Compare this to the edge betweenness procedure - -# Again, we can visualise these communities in different ways: -friends <- friends %>% - mutate(fg_comm = friend_fg) -graphr(friends, - node_color = "fg_comm", - node_group = "fg_comm") + - ggtitle("Fast-greedy", - subtitle = round(network_modularity(friends, friend_fg), 3)) -``` - -See A Clauset, MEJ Newman, C Moore: -Finding community structure in very large networks, -https://arxiv.org/abs/cond-mat/0408187 - -```{r comm-comp, echo=FALSE, purl = FALSE} -question("What is the difference between communities and components?", - answer("Communities and components are just different terms for the same thing"), - answer("Communities are a stricter form of component"), - answer("Components are about paths whereas communities are about the relationship between within-group and between-group ties", - correct = TRUE), - random_answer_order = TRUE, - allow_retry = TRUE) -``` - -## Two-mode network: Southern women - -The next dataset, 'ison_southern_women', is also available in `{manynet}`. -Let's load and graph the data. - -```{r setup-women, exercise=TRUE, exercise.setup = "data", purl = FALSE} - -``` - -```{r setup-women-hint-1, purl = FALSE} -# let's load the data and analyze it -data("ison_southern_women") -ison_southern_women -``` - -```{r setup-women-hint-2, purl = FALSE} -graphr(ison_southern_women, node_color = "type") -graphr(ison_southern_women, "railway", node_color = "type") -``` - -```{r setup-women-solution} -data("ison_southern_women") -ison_southern_women -graphr(ison_southern_women, node_color = "type") -``` - -### Project two-mode network into two one-mode networks - -Now what if we are only interested in one part of the network? -For that, we can obtain a 'projection' of the two-mode network. -There are two ways of doing this. -The hard way... - -```{r hardway, exercise=TRUE, exercise.setup = "setup-women", purl = FALSE} - -``` - -```{r hardway-solution} -twomode_matrix <- as_matrix(ison_southern_women) -women_matrix <- twomode_matrix %*% t(twomode_matrix) -event_matrix <- t(twomode_matrix) %*% twomode_matrix -``` - -Or the easy way: - -```{r easyway, exercise=TRUE, exercise.setup = "setup-women", purl = FALSE} - -``` - -```{r easyway-hint-1, purl = FALSE} -# women-graph -# to_mode1(): Results in a weighted one-mode object that retains the row nodes from -# a two-mode object, and weights the ties between them on the basis of their joint -# ties to nodes in the second mode (columns) - -women_graph <- to_mode1(ison_southern_women) -graphr(women_graph) - -# note that projection `to_mode1` involves keeping one type of nodes -# this is different from to_uniplex above, which keeps one type of ties in the network -``` - -```{r easyway-hint-2, purl = FALSE} -# event-graph -# to_mode2(): Results in a weighted one-mode object that retains the column nodes from -# a two-mode object, and weights the ties between them on the basis of their joint ties -# to nodes in the first mode (rows) - -event_graph <- to_mode2(ison_southern_women) -graphr(event_graph) -``` - -```{r easyway-solution} -women_graph <- to_mode1(ison_southern_women) -graphr(women_graph) -event_graph <- to_mode2(ison_southern_women) -graphr(event_graph) -``` - -`{manynet}` also includes several other options for how to construct the projection. -Please see the help file for more details. - -```{r otherway, exercise=TRUE, exercise.setup = "setup-women", purl = FALSE} - -``` - -```{r otherway-solution} -graphr(to_mode2(ison_southern_women, similarity = "jaccard")) + ggtitle("Jaccard") + -graphr(to_mode2(ison_southern_women, similarity = "rand")) + ggtitle("Rand") + -graphr(to_mode2(ison_southern_women, similarity = "pearson")) + ggtitle("Pearson") + -graphr(to_mode2(ison_southern_women, similarity = "yule")) + ggtitle("Yule's Q") -``` - -Which women/events 'bind' which events/women? -Let's return to the question of cohesion. - -```{r twomode-cohesion, exercise=TRUE, exercise.setup = "setup-women", purl = FALSE} - -``` - -```{r twomode-cohesion-hint-1, purl = FALSE} -# network_equivalency(): Calculate equivalence or reinforcement in a (usually two-mode) network - -network_equivalency(ison_southern_women) -``` - -```{r twomode-cohesion-hint-2, purl = FALSE} -# network_transitivity(): Calculate transitivity in a network - -network_transitivity(women_graph) -network_transitivity(event_graph) -``` - -```{r twomode-cohesion-solution} -network_equivalency(ison_southern_women) -network_transitivity(women_graph) -network_transitivity(event_graph) -``` - -What do we learn from this? - -## Task/Unit Test - -1. Produce a plot comparing 3 community detection procedures used here on a -(women) projection of the 'ison_southern_women' dataset. Identify which you prefer, and explain why. -2. Explain in no more than a paragraph why projection can lead to misleading transitivity measures. -3. Explain in no more than a paragraph how structural balance might lead to group identity. diff --git a/inst/tutorials/tutorial4/community.html b/inst/tutorials/tutorial4/community.html deleted file mode 100644 index b2f88d0b..00000000 --- a/inst/tutorials/tutorial4/community.html +++ /dev/null @@ -1,2176 +0,0 @@ - - - - - - - - - - - - - - - - - -Community - - - - - - - - - - - - - - - - - - - - - -
    Skip to Tutorial Content - - - -
    -
    - -
    - -
    -

    Setting up

    -

    The data we’re going to use here, “ison_algebra”, is included in the -{manynet} package. Do you remember how to call the data? -Can you find out some more information about it?

    -
    - -
    -
    -
    # Let's call and load the 'ison_algebra' dataset
    -data("ison_algebra", package = "manynet")
    -# Or you can retrieve like this:
    -ison_algebra <- manynet::ison_algebra
    -
    -
    -
    # If you want to learn more about the 'ison_algebra' dataset, use the following function (below)
    -?manynet::ison_algebra
    -
    -
    -
    data("ison_algebra", package = "manynet")
    -?manynet::ison_algebra
    -# If you want to see the network object, you can run the name of the object
    -ison_algebra
    -# or print the code with brackets at the front and end of the code
    -(ison_algebra <- manynet::ison_algebra)
    -
    -

    We can see after printing the object that the dataset is multiplex, -meaning that it contains several different types of ties: friendship -(friends), social (social) and task interactions (tasks).

    -
    -

    Adding names

    -

    The network is also anonymous, but I think it would be nice to add -some names, even if it’s just pretend. Luckily, {manynet} -has a function for this, to_named(). This makes plotting -the network just a wee bit more accessible and interpretable. Let’s try -adding names and graphing the network now:

    -
    - -
    -
    -
    ison_algebra <- to_named(ison_algebra)
    -
    -
    -
    graphr(ison_algebra)
    -
    -
    -
    ison_algebra <- to_named(ison_algebra)
    -graphr(ison_algebra)
    -
    -

    Note that you will likely get a different set of names, as they are -assigned randomly from a pool of (American) first names.

    -
    -
    -

    Separating multiplex networks

    -

    As a multiplex network, there are actually three different types of -ties (friends, social, and tasks) in this network. We can extract them -and graph them separately using to_uniplex():

    -
    - -
    -
    -
    # to_uniplex extracts ties of a single type,
    -# focusing on the 'friends' tie attribute here
    -friends <- to_uniplex(ison_algebra, "friends")
    -gfriend <- graphr(friends) + ggtitle("Friendship")
    -
    -
    -
    # now let's focus on the 'social' tie attribute
    -social <- to_uniplex(ison_algebra, "social")
    -gsocial <- graphr(social) + ggtitle("Social")
    -
    -
    -
    # and the 'tasks' tie attribute
    -tasks <- to_uniplex(ison_algebra, "tasks")
    -gtask <- graphr(tasks) + ggtitle("Task")
    -
    -
    -
    # now, let's compare each attribute's graph, side-by-side
    -gfriend + gsocial + gtask
    -# if you get an error here, you may need to install and load
    -# the package 'patchwork'.
    -# It's highly recommended for assembling multiple plots together.
    -# Otherwise you can just plot them separately on different lines.
    -
    -
    -
    friends <- to_uniplex(ison_algebra, "friends")
    -gfriend <- graphr(friends) + ggtitle("Friendship")
    -
    -social <- to_uniplex(ison_algebra, "social")
    -gsocial <- graphr(social) + ggtitle("Social")
    -
    -tasks <- to_uniplex(ison_algebra, "tasks")
    -gtask <- graphr(tasks) + ggtitle("Task")
    -
    -# We now have three separate networks depicting each type of tie from the ison_algebra network:
    -gfriend + gsocial + gtask
    -
    -

    Note also that these are weighted networks. graphr() -automatically recognises these different weights and plots them. Where -useful (less dense directed networks), graphr() also bends -reciprocated arcs. What (else) can we say about these three -networks?

    -
    -
    -
    -

    Cohesion

    -

    Let’s concentrate on the task network for now and calculate a few -basic measures of cohesion: density, reciprocity, transitivity, and -components.

    -
    -

    Density

    -

    Because this is a directed network, we can calculate the density -as:

    -
    - -
    -
    -
    # calculating network density manually according to equation
    -network_ties(tasks)/(network_nodes(tasks)*(network_nodes(tasks)-1))
    -
    -

    but we can also just use the {migraph} function…

    -
    - -
    -
    -
    network_density(tasks)
    -
    -

    Note that the various measures in {migraph} print -results to three decimal points by default, but the underlying result -retains the same recurrence. So same result…

    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -

    Closure

    -

    Next let’s calculate reciprocity in the task network. While -one could do this by hand, it’s more efficient to do this using the -{migraph} package. Can you guess the correct name of the -function?

    -
    - -
    -
    -
    network_reciprocity(tasks)
    -# this function calculates the amount of reciprocity in the whole network
    -
    -

    And let’s calculate transitivity in the task network. Again, -can you guess the correct name of this function?

    -
    - -
    -
    -
    network_transitivity(tasks)
    -# this function calculates the amount of transitivity in the whole network
    -
    -

    We have collected measures of the task network’s reciprocity and -transitivity, but we still need to interpret these measures. These -measures do not speak for themselves.

    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -

    Components

    -

    Now let’s look at the friendship network, ‘friends’. We’re interested -here in how many components there are. By default, the -network_components() function will return the number of -strong components for directed networks. For weak -components, you will need to first make the network undirected. Remember -the difference between weak and strong components?

    -
    -
    -
    -
    -
    - -
    -
    -
    - -
    -
    -
    network_components(friends)
    -# note that friends is a directed network
    -# you can see this by calling the object 'friends'
    -# or by running `manynet::is_directed(friends)`
    -
    -
    -
    # Now let's look at the number of components for objects connected by an undirected edge
    -# Note: to_undirected() returns an object with all tie direction removed, 
    -# so any pair of nodes with at least one directed edge 
    -# will be connected by an undirected edge in the new network.
    -network_components(to_undirected(friends))
    -
    -
    -
    # note that friends is a directed network
    -network_components(friends)
    -network_components(to_undirected(friends))
    -
    -
    -
    -
    -
    -
    - -
    -
    -

    So we know how many components there are, but maybe we’re also -interested in which nodes are members of which components? -node_components() returns a membership vector that can be -used to color nodes in graphr():

    -
    - -
    -
    -
    friends <- friends %>% 
    -  mutate(weak_comp = node_components(to_undirected(friends)),
    -         strong_comp = node_components(friends))
    -# node_components returns a vector of nodes' memberships to components in the network
    -# here, we are adding the nodes' membership to components as an attribute in the network
    -# alternatively, we can also use the function `add_node_attribute()`
    -# eg. `add_node_attribute(friends, "weak_comp", node_components(to_undirected(friends)))`
    -
    -
    -
    graphr(friends, node_color = "weak_comp") + ggtitle("Weak components") +
    -graphr(friends, node_color = "strong_comp") + ggtitle("Strong components")
    -# by using the 'node_color' argument, we are telling graphr to colour 
    -# the nodes in the graph according to the values of the 'weak_comp' attribute in the network 
    -
    -
    -
    friends <- friends %>% 
    -  mutate(weak_comp = node_components(to_undirected(friends)),
    -         strong_comp = node_components(friends))
    -graphr(friends, node_color = "weak_comp") + ggtitle("Weak components") +
    -graphr(friends, node_color = "strong_comp") + ggtitle("Strong components")
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -

    Community Detection

    -

    Ok, the friendship network has 3-4 components, but how many ‘groups’ -are there? Just visually, it looks like there are two denser clusters -within the main component.

    -

    Today we’ll use the ‘friends’ subgraph for exploring community -detection methods. For clarity and simplicity, we will concentrate on -the main component (the so-called ‘giant’ component) and consider -friendship undirected. Can you guess how to make these changes to the -‘friends’ network?

    -
    - -
    -
    -
    # to_giant() returns an object that includes only the main component without any smaller components or isolates
    -(friends <- to_giant(friends))
    -
    -
    -
    (friends <- to_undirected(friends))
    -
    -
    -
    # now, let's graph the new network
    -graphr(friends)
    -
    -
    -
    (friends <- to_giant(friends))
    -(friends <- to_undirected(friends))
    -graphr(friends)
    -
    -

    Comparing friends before and after these operations, -you’ll notice the number of ties decreases as reciprocated directed ties -are consolidated into single undirected ties, and the number of nodes -decreases as two isolates are removed.

    -

    There is no one single best community detection algorithm. Instead -there are several, each with their strengths and weaknesses. Since this -is a rather small network, we’ll focus on the following methods: -walktrap, edge betweenness, and fast greedy. (Others are included in -{migraph}/{igraph}) As you use them, consider -how they portray communities and consider which one(s) afford a sensible -view of the social world as cohesively organized.

    -
    -

    Walktrap

    -

    This algorithm detects communities through a series of short random -walks, with the idea that nodes encountered on any given random walk are -more likely to be within a community than not. It was proposed by Pons -and Latapy (2005).

    -

    The algorithm initially treats all nodes as communities of their own, -then merges them into larger communities, still larger communities, and -so on. In each step a new community is created from two other -communities, and its ID will be one larger than the largest community ID -so far. This means that before the first merge we have n communities -(the number of vertices in the graph) numbered from zero to n-1. The -first merge creates community n, the second community n+1, etc. This -merge history is returned by the function: -# ?igraph::cluster_walktrap

    -

    Note the “steps=” argument that specifies the length of the random -walks. While {igraph} sets this to 4 by default, which is -what is recommended by Pons and Latapy, Waugh et al (2009) found that -for many groups (Congresses), these lengths did not provide the maximum -modularity score. To be thorough in their attempts to optimize -modularity, they ran the walktrap algorithm 50 times for each group -(using random walks of lengths 1–50) and selected the network partition -with the highest modularity value from those 50. They call this the -“maximum modularity partition” and insert the parenthetical “(though, -strictly speaking, this cannot be proven to be the optimum without -computationally-prohibitive exhaustive enumeration (Brandes et -al. 2008)).”

    -

    So let’s try and get a community classification using the walktrap -algorithm with path lengths of the random walks specified to be 50.

    -
    - -
    -
    -
    # let's use the node_walktrap()function to create a hierarchical, 
    -# agglomerative algorithm based on random walks, and assign it to
    -# an object
    -
    -friend_wt <- node_in_walktrap(friends, times=50)
    -friend_wt # note that it prints pretty, but underlying its just a vector:
    -
    -
    -
    c(friend_wt)
    -
    -# This says that dividing the graph into 2 communities maximises modularity,
    -# one with the nodes 
    -which(friend_wt == 1)
    -# and the other 
    -which(friend_wt == 2)
    -
    -
    -
    # resulting in a modularity of 
    -network_modularity(friends, friend_wt)
    -
    -
    -
    friend_wt <- node_in_walktrap(friends, times=50)
    -friend_wt # note that it prints pretty, but underlying it is just a vector:
    -# c(friend_wt)
    -
    -# This says that dividing the graph into 2 communities maximises modularity,
    -# one with the nodes 
    -which(friend_wt == 1)
    -# and the other 
    -which(friend_wt == 2)
    -# resulting in a modularity of 
    -network_modularity(friends, friend_wt)
    -
    -

    We can also visualise the clusters on the original network How does -the following look? Plausible?

    -
    - -
    -
    -
    # plot 1: groups by node color
    -
    -friends <- friends %>% 
    -  mutate(walk_comm = friend_wt)
    -graphr(friends, node_color = "walk_comm")
    -
    -
    -
    #plot 2: groups by borders
    -
    -# to be fancy, we could even draw the group borders around the nodes using the node_group argument
    -graphr(friends, node_group = "walk_comm")
    -
    -
    -
    # plot 3: group and node colors
    -
    -# or both!
    -graphr(friends,
    -       node_color = "walk_comm",
    -       node_group = "walk_comm") +
    -  ggtitle("Walktrap",
    -    subtitle = round(network_modularity(friends, friend_wt), 3))
    -# the function `round()` rounds the values to a specified number of decimal places
    -# here, we are telling it to round the network_modularity score to 3 decimal places,
    -# but the score is exactly 0.27 so only two decimal places are printed.
    -
    -
    -
    friends <- friends %>% 
    -  mutate(walk_comm = friend_wt)
    -graphr(friends, node_color = "walk_comm")
    -# to be fancy, we could even draw the group borders around the nodes using the node_group argument
    -graphr(friends, node_group = "walk_comm")
    -# or both!
    -graphr(friends,
    -       node_color = "walk_comm",
    -       node_group = "walk_comm") +
    -  ggtitle("Walktrap",
    -    subtitle = round(network_modularity(friends, friend_wt), 3))
    -
    -

    This can be helpful when polygons overlap to better identify -membership Or you can use node color and size to indicate other -attributes…

    -
    -
    -

    Edge Betweenness

    -

    Edge betweenness is like betweenness centrality but for ties not -nodes. The edge-betweenness score of an edge measures the number of -shortest paths from one vertex to another that go through it.

    -

    The idea of the edge-betweenness based community structure detection -is that it is likely that edges connecting separate clusters have high -edge-betweenness, as all the shortest paths from one cluster to another -must traverse through them. So if we iteratively remove the edge with -the highest edge-betweenness score we will get a hierarchical map -(dendrogram) of the communities in the graph.

    -

    The following works similarly to walktrap, but no need to set a step -length.

    -
    - -
    -
    -
    friend_eb <- node_in_betweenness(friends)
    -friend_eb
    -
    -

    How does community membership differ here from that found by -walktrap?

    -

    We can see how the edge betweenness community detection method works -here: http://jfaganuk.github.io/2015/01/24/basic-network-analysis/

    -

    To visualise the result:

    -
    - -
    -
    -
    # create an object
    -
    -friends <- friends %>% 
    -  mutate(eb_comm = friend_eb)
    -
    -
    -
    # create a graph with a title and subtitle returning the modularity score
    -
    -graphr(friends,
    -       node_color = "eb_comm",
    -       node_group = "eb_comm") +
    -  ggtitle("Edge-betweenness",
    -    subtitle = round(network_modularity(friends, friend_eb), 3))
    -
    -
    -
    friends <- friends %>% 
    -  mutate(eb_comm = friend_eb)
    -graphr(friends,
    -       node_color = "eb_comm",
    -       node_group = "eb_comm") +
    -  ggtitle("Edge-betweenness",
    -    subtitle = round(network_modularity(friends, friend_eb), 3))
    -
    -

    For more on this algorithm, see M Newman and M Girvan: Finding and -evaluating community structure in networks, Physical Review E 69, 026113 -(2004), https://arxiv.org/abs/cond-mat/0308217.

    -
    -
    -

    Fast Greedy

    -

    This algorithm is the Clauset-Newman-Moore algorithm. Whereas edge -betweenness was divisive (top-down), the fast greedy algorithm is -agglomerative (bottom-up).

    -

    At each step, the algorithm seeks a merge that would most increase -modularity. This is very fast, but has the disadvantage of being a -greedy algorithm, so it might not produce the best overall community -partitioning, although I personally find it both useful and in many -cases quite “accurate”.

    -
    - -
    -
    -
    friend_fg <- node_in_greedy(friends)
    -friend_fg # Does this result in a different community partition?
    -network_modularity(friends, friend_fg) # Compare this to the edge betweenness procedure
    -
    -
    -
    # Again, we can visualise these communities in different ways:
    -friends <- friends %>% 
    -  mutate(fg_comm = friend_fg)
    -graphr(friends,
    -       node_color = "fg_comm",
    -       node_group = "fg_comm") +
    -  ggtitle("Fast-greedy",
    -    subtitle = round(network_modularity(friends, friend_fg), 3))
    -# 
    -
    -
    -
    friend_fg <- node_in_greedy(friends)
    -friend_fg # Does this result in a different community partition?
    -network_modularity(friends, friend_fg) # Compare this to the edge betweenness procedure
    -
    -# Again, we can visualise these communities in different ways:
    -friends <- friends %>% 
    -  mutate(fg_comm = friend_fg)
    -graphr(friends,
    -       node_color = "fg_comm",
    -       node_group = "fg_comm") +
    -  ggtitle("Fast-greedy",
    -    subtitle = round(network_modularity(friends, friend_fg), 3))
    -
    -

    See A Clauset, MEJ Newman, C Moore: Finding community structure in -very large networks, https://arxiv.org/abs/cond-mat/0408187

    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -

    Two-mode network: Southern women

    -

    The next dataset, ‘ison_southern_women’, is also available in -{manynet}. Let’s load and graph the data.

    -
    - -
    -
    -
    # let's load the data and analyze it
    -data("ison_southern_women")
    -ison_southern_women
    -
    -
    -
    graphr(ison_southern_women, node_color = "type")
    -graphr(ison_southern_women, "railway", node_color = "type")
    -
    -
    -
    data("ison_southern_women")
    -ison_southern_women
    -graphr(ison_southern_women, node_color = "type")
    -
    -
    -

    Project two-mode network into two one-mode networks

    -

    Now what if we are only interested in one part of the network? For -that, we can obtain a ‘projection’ of the two-mode network. There are -two ways of doing this. The hard way…

    -
    - -
    -
    -
    twomode_matrix <- as_matrix(ison_southern_women)
    -women_matrix <- twomode_matrix %*% t(twomode_matrix)
    -event_matrix <- t(twomode_matrix) %*% twomode_matrix
    -
    -

    Or the easy way:

    -
    - -
    -
    -
    # women-graph
    -# to_mode1(): Results in a weighted one-mode object that retains the row nodes from
    -# a two-mode object, and weights the ties between them on the basis of their joint
    -# ties to nodes in the second mode (columns)
    -
    -women_graph <- to_mode1(ison_southern_women)
    -graphr(women_graph)
    -
    -# note that projection `to_mode1` involves keeping one type of nodes
    -# this is different from to_uniplex above, which keeps one type of ties in the network
    -
    -
    -
    # event-graph
    -# to_mode2(): Results in a weighted one-mode object that retains the column nodes from
    -# a two-mode object, and weights the ties between them on the basis of their joint ties
    -# to nodes in the first mode (rows)
    -
    -event_graph <- to_mode2(ison_southern_women)
    -graphr(event_graph)
    -
    -
    -
    women_graph <- to_mode1(ison_southern_women)
    -graphr(women_graph)
    -event_graph <- to_mode2(ison_southern_women)
    -graphr(event_graph)
    -
    -

    {manynet} also includes several other options for how to -construct the projection. Please see the help file for more details.

    -
    - -
    -
    -
    graphr(to_mode2(ison_southern_women, similarity = "jaccard")) + ggtitle("Jaccard") +
    -graphr(to_mode2(ison_southern_women, similarity = "rand")) + ggtitle("Rand") +
    -graphr(to_mode2(ison_southern_women, similarity = "pearson")) + ggtitle("Pearson") +
    -graphr(to_mode2(ison_southern_women, similarity = "yule")) + ggtitle("Yule's Q")
    -
    -

    Which women/events ‘bind’ which events/women? Let’s return to the -question of cohesion.

    -
    - -
    -
    -
    # network_equivalency(): Calculate equivalence or reinforcement in a (usually two-mode) network
    -
    -network_equivalency(ison_southern_women)
    -
    -
    -
    # network_transitivity(): Calculate transitivity in a network
    -
    -network_transitivity(women_graph)
    -network_transitivity(event_graph)
    -
    -
    -
    network_equivalency(ison_southern_women)
    -network_transitivity(women_graph)
    -network_transitivity(event_graph)
    -
    -

    What do we learn from this?

    -
    -
    -
    -

    Task/Unit Test

    -
      -
    1. Produce a plot comparing 3 community detection procedures used here -on a (women) projection of the ‘ison_southern_women’ dataset. Identify -which you prefer, and explain why.
    2. -
    3. Explain in no more than a paragraph why projection can lead to -misleading transitivity measures.
    4. -
    5. Explain in no more than a paragraph how structural balance might -lead to group identity. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    6. -
    - - - - - - -
    - -
    - -
    -
    -
    -
    - - -
    -

    Community

    -

    by James Hollway

    -
    - - -
    -
    -
    -
    - - -
    -
    - - - - - - - - - - - - - - - - From 68c7fbd47feefe9a125b3ac2ec414b30f3f2ebca Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:21:41 +0200 Subject: [PATCH 69/97] Migrated position tutorial to manynet --- inst/tutorials/tutorial5/position.Rmd | 605 ------ inst/tutorials/tutorial5/position.html | 1660 ----------------- .../position_data/data_chunks_index.txt | 1 - 3 files changed, 2266 deletions(-) delete mode 100644 inst/tutorials/tutorial5/position.Rmd delete mode 100644 inst/tutorials/tutorial5/position.html delete mode 100644 inst/tutorials/tutorial5/position_data/data_chunks_index.txt diff --git a/inst/tutorials/tutorial5/position.Rmd b/inst/tutorials/tutorial5/position.Rmd deleted file mode 100644 index 7cafcd12..00000000 --- a/inst/tutorials/tutorial5/position.Rmd +++ /dev/null @@ -1,605 +0,0 @@ ---- -title: "Position" -author: "by James Hollway" -output: - learnr::tutorial: - theme: journal -runtime: shiny_prerendered -description: > - This tutorial aims to teach you how to measure structural holes and - identify and interpret structurally equivalent nodes. ---- - -```{r setup, include = FALSE} -library(learnr) -library(manynet) -library(migraph) -library(patchwork) -knitr::opts_chunk$set(echo = FALSE) -``` - - -## Setting up - -For this session, we're going to use the "ison_algebra" dataset included in the `{manynet}` package. -Do you remember how to call the data? -Can you find out some more information about it via its help file? - -```{r data, exercise = TRUE, purl = FALSE} - -``` - -```{r data-hint-1, purl = FALSE} -# Let's call and load the 'ison_algebra' dataset -data("ison_algebra", package = "manynet") -# Or you can retrieve like this: -ison_algebra <- manynet::ison_algebra -``` - -```{r data-hint-2, purl = FALSE} -# If you want to learn more about the 'ison_algebra' dataset, use the following function (below) -?manynet::ison_algebra -``` - -```{r data-solution} -data("ison_algebra", package = "manynet") -?manynet::ison_algebra -# If you want to see the network object, you can run the name of the object -# ison_algebra -# or print the code with brackets at the front and end of the code -# (ison_algebra <- manynet::ison_algebra) -``` - -We can see that the dataset is multiplex, -meaning that it contains several different types of ties: -friendship (friends), social (social) and task interactions (tasks). - -### Separating multiplex networks - -As a multiplex network, -there are actually three different types of ties in this network. -We can extract them and investigate them separately using `to_uniplex()`. -Within the parentheses, put the multiplex object's name, -and then as a second argument put the name of the tie attribute in quotation marks. -Once you have extracted all three networks, -graph them and add a descriptive title. - -```{r separatingnets, exercise=TRUE, exercise.setup = "data", purl = FALSE} - -``` - -```{r separatingnets-hint-1, purl = FALSE} -# Here's the basic idea/code syntax you will need to extract each type of network -# You will want to replace -____ <- to_uniplex(ison_algebra, _____) -``` - -```{r separatingnets-hint-4, purl = FALSE} -# Now, let's compare the each attribute's graph, side-by-side by using "+" -# Note: using "/" after each graph will order them vertically; however, it might not be best way -# See for example: -gfriend <- graphr(friends) + ggtitle("Friendship") -gfriend + gsocial + gtask -``` - -```{r separatingnets-solution} -friends <- to_uniplex(ison_algebra, "friends") -gfriend <- graphr(friends) + ggtitle("Friendship") - -social <- to_uniplex(ison_algebra, "social") -gsocial <- graphr(social) + ggtitle("Social") - -tasks <- to_uniplex(ison_algebra, "tasks") -gtask <- graphr(tasks) + ggtitle("Task") - -gfriend + gsocial + gtask -``` - -Note also that these are weighted networks. -`graphr()` automatically recognises these different weights and plots them. - -```{r strongties-qa, echo=FALSE, purl = FALSE} -question("If we interpret ties with higher weights as strong ties, and lesser weights as weak ties, then, according to network theory, where would we expect novel information to come from?", - answer("Weak ties", - correct = TRUE, - message = learnr::random_praise()), - answer("Strong ties", - message = learnr::random_encouragement()), - answer("Isolates", - message = learnr::random_encouragement()), - answer("Highest degree nodes", - message = learnr::random_encouragement()), - random_answer_order = TRUE, - allow_retry = TRUE -) -``` - -## Structural Holes and Constraint - -Our first question for this network, is where innovation and creative ideas -might be expected to appear. - -```{r structinnov-qa, echo=FALSE, purl = FALSE} -question("Which network concepts are associated with innovation?", - answer("Structural holes", - correct = TRUE, - message = learnr::random_praise()), - answer("Structural folds", - correct = TRUE), - answer("Structural balance", - message = learnr::random_encouragement()), - answer("Structural equivalence", - message = learnr::random_encouragement()), - answer("Structuralism", - message = learnr::random_encouragement()), - random_answer_order = TRUE, - allow_retry = TRUE -) -``` - -### Measuring structural holes - -```{r shmeasures-qa, echo=FALSE, purl = FALSE} -question("There are a number of measures that might be used to approximate the concept of structural holes. Select all that apply.", - answer("Constraint", - correct = TRUE, - message = learnr::random_praise()), - answer("Effective size", - correct = TRUE), - answer("Bridges", - correct = TRUE), - answer("Redundancy", - correct = TRUE), - answer("Efficiency", - correct = TRUE), - answer("Hierarchy", - correct = TRUE), - random_answer_order = TRUE, - allow_retry = TRUE -) -``` - -Let's take a look at which actors are least _constrained_ -by their position in the *task* network to begin with. -`{migraph}` makes this easy enough with the `node_constraint()` function. - -```{r objects-setup, purl=FALSE} -alge <- to_named(ison_algebra) -friends <- to_uniplex(alge, "friends") -social <- to_uniplex(alge, "social") -tasks <- to_uniplex(alge, "tasks") -``` - -```{r constraint, exercise = TRUE, exercise.setup = "objects-setup", purl = FALSE} - -``` - -```{r constraint-hint, purl = FALSE} -node_constraint(____) -# Don't forget we want to look at which actors are least constrained by their position in the 'tasks' network -``` - -```{r constraint-solution} -node_constraint(tasks) -``` - -This function returns a vector of constraint scores that can range between 0 and 1. -Let's graph the network again, sizing the nodes according to this score. -We can also identify the node with the minimum constraint score using `node_is_min()`. - -```{r constraintplot, exercise=TRUE, exercise.setup = "objects-setup", purl = FALSE} - -``` - -```{r constraintplot-hint-1, purl = FALSE} -tasks <- tasks %>% - mutate(constraint = node_constraint(____), - low_constraint = node_is_min(node_constraint(____))) - -# Don't forget, we are still looking at the 'tasks' network -``` - -```{r constraintplot-hint-3, purl = FALSE} -# Now, let's graph the network -# Note 1: we are looking at the 'tasks' network -# Note 2: we are interested in the actors 'least constrained' by their position - -graphr(____, node_color = "____") -``` - -```{r constraintplot-hint-4, purl = FALSE} -graphr(tasks, node_size = "constraint", node_color = "low_constraint") -``` - -```{r constraintplot-solution} -tasks <- tasks %>% - mutate(constraint = node_constraint(tasks), - low_constraint = node_is_min(node_constraint(tasks))) -graphr(tasks, node_size = "constraint", node_color = "low_constraint") -``` - -Why minimum? Because constraint measures how well connected each node's partners are, -with the implication that having few partners that are already connected to each other puts a node in an advantageous position to identify and share novel solutions to problems. -So what can we learn from this plot -about where innovation might occur within this network? - -## Structural Equivalence - -Next we might ask ourselves what (other) roles there are in the network? -We want to know who plays what role in this algebra class. -Let us begin with structural equivalence. - -```{r equiv-qa, echo=FALSE, purl = FALSE} -question("Structural equivalence means identifying classes of nodes with...", - answer("same/similar tie partners.", - correct = TRUE, - message = learnr::random_praise()), - answer("same/similar pattern of ties.", - message = "This is the definition for regular equivalence."), - answer("same/similar distance from all others.", - message = "This is the definition for automorphic equivalence.") -) -``` - -We're going to identify structurally equivalent positions -across all the data that we have, including 'task', 'social', and 'friend' ties. -So that is, we are using the multiplex `ison_algebra` dataset again and not -a uniplex subgraph thereof. - -### Finding structurally equivalent classes - -In `{migraph}`, finding how the nodes of a network can be partitioned -into structurally equivalent classes can be as easy as: - -```{r find-se, exercise = TRUE, exercise.setup = "data"} -node_in_structural(ison_algebra) - -ison_algebra %>% - mutate(se = node_in_structural(ison_algebra)) %>% - graphr(node_color = "se") -``` - -But actually, a lot is going on behind the scenes here that we can unpack. -Understanding what is going on behind the scenes is important for understanding -how these classes are identified and how to interpret them. - -### Step one: starting with a census - -All equivalence classes are based on nodes' similarity across some profile of motifs. -In `{migraph}`, we call these motif *censuses*. -Any kind of census can be used, and `{migraph}` includes a few options, -but `node_in_structural()` is based off of the census of all the nodes' ties, -both outgoing and incoming ties, to characterise their relationships to tie partners. - -```{r construct-cor, exercise = TRUE, exercise.setup = "data", purl = FALSE} - -``` - -```{r construct-cor-hint-1, purl = FALSE} -# Let's use the node_tie_census() function -# The function accepts an object such as a dataset -# Hint: Which dataset are we using in this tutorial? -node_tie_census(____) -``` - -```{r construct-cor-hint-2, purl = FALSE} -node_tie_census(ison_algebra) -``` - -```{r construct-cor-hint-3, purl = FALSE} -# Now, let's get the dimensions of an object via the dim() function -dim(node_tie_census(ison_algebra)) -``` - -```{r construct-cor-solution} -node_tie_census(ison_algebra) -dim(node_tie_census(ison_algebra)) -``` - -We can see that the result is a matrix of 16 rows -and 96 columns, -because we want to catalogue or take a census of all the different incoming/outgoing partners -our 16 nodes might have across these three networks. -Note also that the result is a weighted matrix; -what would you do if you wanted it to be binary? - -```{r construct-binary, exercise = TRUE, exercise.setup = "data", purl = FALSE} - -``` - -```{r construct-binary-hint, purl = FALSE} -# we could convert the result using as.matrix, returning the ties -as.matrix((node_tie_census(ison_algebra)>0)+0) - -``` - -```{r construct-binary-solution} -# But it's easier to simplify the network by removing the classification into different types of ties. -# Note that this also reduces the total number of possible paths between nodes -ison_algebra %>% - select_ties(-type) %>% - node_tie_census() -``` - -Note that `node_tie_census()` does not need to be passed to `node_in_structural()` --- -this is done automatically! -However, the more generic `node_in_equivalence()` is available and can be used with whichever tie census is desired. -Feel free to explore using some of the other censuses available in `{migraph}`, -though some common ones are already used in the other equivalence convenience functions, -e.g. `node_triad_census()` in `node_in_regular()` -and `node_path_census()` in `node_in_automorphic()`. - -### Step two: growing a tree of similarity - -The next part takes this census and creates a dendrogram based on distance or dissimilarity among the nodes' census profiles. -This is all done internally within e.g. `node_in_structural()`, -though there are two important parameters that can be set to obtain different results. - -First, users can set the type of distance measure used. -For enthusiasts, this is passed on to `stats::dist()`, -so that help page should be consulted for more details. -By default `"euclidean"` is used. - -Second, we can also set the type of clustering algorithm employed. -By default, `{migraph}`'s equivalence functions use hierarchical clustering, `"hier"`, -but for compatibility and enthusiasts, we also offer `"concor"`, -which implements a CONCOR (CONvergence of CORrelations) algorithm. - -We can see the difference from varying the clustering algorithm and/or distance -by plotting the dendrograms (hidden) in the output from `node_in_structural()`: - -```{r varyclust, exercise = TRUE, exercise.setup = "data"} -alge <- to_named(ison_algebra) # fake names to make comparison clearer -plot(node_in_structural(alge, cluster = "hier", distance = "euclidean")) - -# changing the type of distance used -plot(node_in_structural(alge, cluster = "hier", distance = "manhattan")) - -# changing the clustering algorithm -plot(node_in_structural(alge, cluster = "concor", distance = "euclidean")) -``` - -```{r scale-interp, echo = FALSE, purl = FALSE} -question("Do you see any differences?", - answer("Yes", correct = TRUE, message = learnr::random_praise()), - answer("No"), - allow_retry = TRUE) -``` - -So plotting a `membership` vector from `{migraph}` returns a dendrogram -with the names of the nodes on the _y_-axis and the distance between them on the _x_-axis. -Using the census as material, the distances between the nodes -is used to create a dendrogram of (dis)similarity among the nodes. -Basically, as we move to the right, we're allowing for -more and more dissimilarity among those we cluster together. -A fork or branching point indicates the level of dissimilarity -at which those two or more nodes would be said to be equivalent. -Where two nodes' branches join/fork represents the maximum distance among all their leaves, -so more similar nodes' branches fork closer to the tree's canopy, -and less similar (groups of) nodes don't join until they form basically the trunk. - -Note that with the results using the hierarchical clustering algorithm, -the distance directly affects the structure of the tree (and the results). - -The CONCOR dendrogram operates a bit differently to hierarchical clustering though. -Instead it represents how converging correlations repeatedly bifurcate -the nodes into one of two partitions. -As such the 'distance' is really just the (inverse) number of steps -of bifurcations until nodes belong to the same class. - -### Step three: identifying the number of clusters - -Another bit of information represented in the dendrogram -is where the tree should be cut (the dashed red line) and -how the nodes are assigned to the branches (clusters) present at that cut-point. - -But where does this red line come from? -Or, more technically, how do we identify the number of clusters -into which to assign nodes? - -`{migraph}` includes several different ways of establishing `k`, -or the number of clusters. -Remember, the further to the right the red line is -(the lower on the tree the cut point is) -the more dissimilar we're allowing nodes in the same cluster to be. -We could set this ourselves by just passing `k` an integer. - -```{r k-discrete, exercise = TRUE, exercise.setup = "varyclust"} -plot(node_in_structural(alge, k = 2)) -``` - -But we're really just guessing. Maybe 2 is not the best `k`? -To establish what the best `k` is for this clustering exercise, -we need to iterate through a number of potential `k` -and consider their fitness by some metric. -There are a couple of options here. - -One is to consider, for each `k`, -how correlated this partition is with the observed network. -When there is one cluster for each vertex in the network, -cell values will be identical to the observed correlation matrix, -and when there is one cluster for the whole network, -the values will all be equal to the average correlation -across the observed matrix. -So the correlations in each by-cluster matrix are correlated with the observed -correlation matrix to see how well each by-cluster matrix fits the data. - -Of course, the perfect partition would then be -where all nodes are in their own cluster, -which is hardly 'clustering' at all. -Also, increasing `k` will always improve the correlation. -But if one were to plot these correlations as a line graph, -then we might expect there to be a relatively rapid increase -in correlation as we move from, for example, 3 clusters to 4 clusters, -but a relatively small increase from, for example, 13 clusters to 14 clusters. -By identifying the inflection point in this line graph, -`{migraph}` selects a number of clusters that represents a trade-off -between fit and parsimony. -This is the `k = "elbow"` method. - -The other option is to evaluate a candidate for `k` based -not on correlation but on a metric of -how similar each node in a cluster is to others in its cluster -_and_ how dissimilar each node is to those in a neighbouring cluster. -When averaged over all nodes and all clusters, -this provides a 'silhouette coefficient' for a candidate of `k`. -Choosing the number of clusters that maximizes this coefficient, -which is what `k = "silhouette"` does, -can return a somewhat different result to the elbow method. -See what we have here, with all other arguments held the same: - -```{r elbowsil, exercise = TRUE, exercise.setup = "varyclust"} -plot(node_in_structural(alge, k = "elbow")) -plot(node_in_structural(alge, k = "silhouette")) -``` - -Ok, so it looks like the elbow method returns `k == 3` as a good trade-off -between fit and parsimony. -The silhouette method, by contrast, sees `k == 4` as maximising cluster similarity -and dissimilarity. -Either is probably fine here, -and there is much debate around how to select the number of clusters anyway. -However, the silhouette method seems to do a better job of identifying how unique -the 16th node is. -The silhouette method is also the default in `{migraph}`. - -Note that there is a somewhat hidden parameter here, `range`. -Since testing across all possible numbers of clusters can get -computationally expensive (not to mention uninterpretable) for large networks, -`{migraph}` only considers up to 8 clusters by default. -This however can be modified to be higher or lower, e.g. `range = 16`. - -Finally, one last option is `k = "strict"`, -which only assigns nodes to the same partition -if there is zero distance between them. -This is quick and rigorous solution, -however oftentimes this misses the point in finding clusters of nodes that, -despite some variation, can be considered as similar on some dimension. - -```{r strict, exercise = TRUE, exercise.setup = "varyclust"} -plot(node_in_structural(alge, k = "strict")) -``` - -Here for example, no two nodes have precisely the same tie-profile, -otherwise their branches would join/fork at a distance of 0. -As such, `k = "strict"` partitions the network into 16 clusters. -Where networks have a number of nodes with strictly the same profiles, -such a k-selection method might be helpful to recognise those in exactly the same structural position, -but here it essentially just reports nodes' identity. - -## Blockmodelling - -### Summarising profiles - -Ok, so now we have a result from establishing nodes' membership in structurally equivalent classes. -We can graph this of course, as above: - -```{r strplot, exercise = TRUE, exercise.setup = "varyclust"} -alge %>% - mutate(se = node_in_structural(alge)) %>% - graphr(node_color = "se") -``` - -While this plot adds the structurally equivalent classes information to our earlier graph, -it doesn't really help us understand how the classes relate. -That is, we might be less interested in how the individuals in the different classes relate, and more interested in how the different classes relate in aggregate. - -One option that can be useful for characterising what -the profile of ties (partners) is for each position/equivalence class -is to use `summary()`. -It summarises some census result by a partition (equivalence/membership) assignment. -By default it takes the average of ties (values), -but this can be tweaked by assigning some other summary statistic as `FUN = `. - -```{r summ, exercise = TRUE, exercise.setup = "strplot", purl = FALSE} - -``` - -```{r summ-hint, purl = FALSE} -# Let's wrap node_tie_census inside the summary() function -# and pass it a membership result -summary(node_tie_census(____), - membership = ____) -``` - -```{r summ-solution} -summary(node_tie_census(alge), - membership = node_in_structural(alge)) -``` - -This node census produces 96 columns, -$16 \text{nodes} * 2 \text{directions} * 3 \text{edge types}$, -it takes a bit to look through what varies between the different classes -as 'blocked'. -But only four rows (the four structurally equivalent classes, according to the default). - -Another way to do this is to plot the blockmodel as a whole. -Passing the `plot()` function an adjacency/incidence matrix -along with a membership vector allows the matrix to be sorted and framed -(without the membership vector, just the adjacency/incidence matrix is plotted): - -```{r block, exercise = TRUE, exercise.setup = "strplot", purl = FALSE} - -``` - -```{r block-hint, purl = FALSE} -# Let's plot the blockmodel using the plot() function we used for the dendrograms -# Instead of node_tie_census() let's us as_matrix() - -plot(as_matrix(____), - membership = ____) -``` - -```{r block-solution} -# plot the blockmodel for the whole network -plot(as_matrix(alge), - membership = node_in_structural(alge)) - -# plot the blockmodel for the friends, tasks, and social networks separately -plot(as_matrix(friends), - membership = node_in_structural(alge)) + -plot(as_matrix(tasks), - membership = node_in_structural(alge)) + -plot(as_matrix(social), - membership = node_in_structural(alge)) -``` - -By passing the membership argument our structural equivalence results, -the matrix is re-sorted to cluster or 'block' nodes from the same class together. -This can help us interpret the general relationships between classes. -For example, when we plot the friends, tasks, and social networks using the structural equivalence results, -we might characterise them like so: - -- The first group work together only in reciprocal pairs on tasks, -preferring to approach the nerd but also those of the other two roles. -While they hang out with each other socially quite a bit, friendship from groups 2 and 3 are preferred. -- The second group also work together only in reciprocal pairs, -preferring to work collaboratively with group 1 or also the nerd. -They also tend to count those from group 1 as friends, -and hang out with everyone else but themselves. -- The third group will work with either some in group 1 and 3, or 2, -but again prefer the nerd for task advice. -They are pretty good friends with each other though, -and pretty happy to socialise with everyone. -- The nerd is a loner, no friends, -but everyone hangs out with them for task advice. - -### Reduced graph - -Lastly, we can consider how _classes_ of nodes relate to one another in a blockmodel. -Let's use the 4-cluster solution on the valued network (though binary is possible too) -to create a _reduced graph_. -A reduced graph is a transformation of a network such that -the nodes are no longer the individual nodes but the groups of one or more nodes as a class, -and the ties between these blocked nodes can represent the sum or average tie between these classes. -Of course, this means that there can be self-ties or loops, -because even if the original network was simple (not complex), -any within-class ties will end up becoming loops and thus the network will be complex. - -```{r structblock, exercise = TRUE, exercise.setup = "varyclust", warning=FALSE} -(bm <- to_blocks(alge, node_in_structural(alge))) - -bm <- bm %>% as_tidygraph %>% - mutate(name = c("Freaks", "Squares", "Nerds", "Geek")) -graphr(bm) -``` diff --git a/inst/tutorials/tutorial5/position.html b/inst/tutorials/tutorial5/position.html deleted file mode 100644 index 547e7363..00000000 --- a/inst/tutorials/tutorial5/position.html +++ /dev/null @@ -1,1660 +0,0 @@ - - - - - - - - - - - - - - - - - -Position - - - - - - - - - - - - - - - - - - - - - -Skip to Tutorial Content - - - -
    -
    - -
    - -
    -

    Setting up

    -

    For this session, we’re going to use the “ison_algebra” dataset -included in the {manynet} package. Do you remember how to -call the data? Can you find out some more information about it via its -help file?

    -
    - -
    -
    -
    # Let's call and load the 'ison_algebra' dataset
    -data("ison_algebra", package = "manynet")
    -# Or you can retrieve like this:
    -ison_algebra <- manynet::ison_algebra
    -
    -
    -
    # If you want to learn more about the 'ison_algebra' dataset, use the following function (below)
    -?manynet::ison_algebra
    -
    -
    -
    data("ison_algebra", package = "manynet")
    -?manynet::ison_algebra
    -# If you want to see the network object, you can run the name of the object
    -# ison_algebra
    -# or print the code with brackets at the front and end of the code
    -# (ison_algebra <- manynet::ison_algebra)
    -
    -

    We can see that the dataset is multiplex, meaning that it contains -several different types of ties: friendship (friends), social (social) -and task interactions (tasks).

    -
    -

    Separating multiplex networks

    -

    As a multiplex network, there are actually three different types of -ties in this network. We can extract them and investigate them -separately using to_uniplex(). Within the parentheses, put -the multiplex object’s name, and then as a second argument put the name -of the tie attribute in quotation marks. Once you have extracted all -three networks, graph them and add a descriptive title.

    -
    - -
    -
    -
    # Here's the basic idea/code syntax you will need to extract each type of network
    -# You will want to replace
    -____ <- to_uniplex(ison_algebra, _____)
    -
    -
    -
    # Now, let's compare the each attribute's graph, side-by-side by using "+"
    -# Note: using "/" after each graph will order them vertically; however, it might not be best way
    -# See for example:
    -gfriend <- graphr(friends) + ggtitle("Friendship")
    -gfriend + gsocial + gtask
    -
    -
    -
    friends <- to_uniplex(ison_algebra, "friends")
    -gfriend <- graphr(friends) + ggtitle("Friendship")
    -
    -social <- to_uniplex(ison_algebra, "social")
    -gsocial <- graphr(social) + ggtitle("Social")
    -
    -tasks <- to_uniplex(ison_algebra, "tasks")
    -gtask <- graphr(tasks) + ggtitle("Task")
    -
    -gfriend + gsocial + gtask
    -
    -

    Note also that these are weighted networks. graphr() -automatically recognises these different weights and plots them.

    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -

    Structural Holes and Constraint

    -

    Our first question for this network, is where innovation and creative -ideas might be expected to appear.

    -
    -
    -
    -
    -
    - -
    -
    -
    -

    Measuring structural holes

    -
    -
    -
    -
    -
    - -
    -
    -

    Let’s take a look at which actors are least constrained by -their position in the task network to begin with. -{migraph} makes this easy enough with the -node_constraint() function.

    -
    - -
    -
    -
    node_constraint(____)
    -# Don't forget we want to look at which actors are least constrained by their position in the 'tasks' network
    -
    -
    -
    node_constraint(tasks)
    -
    -

    This function returns a vector of constraint scores that can range -between 0 and 1. Let’s graph the network again, sizing the nodes -according to this score. We can also identify the node with the minimum -constraint score using node_is_min().

    -
    - -
    -
    -
    tasks <- tasks %>% 
    -  mutate(constraint = node_constraint(____),
    -         low_constraint = node_is_min(node_constraint(____)))
    -
    -# Don't forget, we are still looking at the 'tasks' network
    -
    -
    -
    # Now, let's graph the network
    -# Note 1: we are looking at the 'tasks' network
    -# Note 2: we are interested in the actors 'least constrained' by their position
    -
    -graphr(____, node_color = "____")
    -
    -
    -
    graphr(tasks, node_size = "constraint", node_color = "low_constraint")
    -
    -
    -
    tasks <- tasks %>% 
    -  mutate(constraint = node_constraint(tasks), 
    -         low_constraint = node_is_min(node_constraint(tasks)))
    -graphr(tasks, node_size = "constraint", node_color = "low_constraint")
    -
    -

    Why minimum? Because constraint measures how well connected each -node’s partners are, with the implication that having few partners that -are already connected to each other puts a node in an advantageous -position to identify and share novel solutions to problems. So what can -we learn from this plot about where innovation might occur within this -network?

    -
    -
    -
    -

    Structural Equivalence

    -

    Next we might ask ourselves what (other) roles there are in the -network? We want to know who plays what role in this algebra class. Let -us begin with structural equivalence.

    -
    -
    -
    -
    -
    - -
    -
    -

    We’re going to identify structurally equivalent positions across all -the data that we have, including ‘task’, ‘social’, and ‘friend’ ties. So -that is, we are using the multiplex ison_algebra dataset -again and not a uniplex subgraph thereof.

    -
    -

    Finding structurally equivalent classes

    -

    In {migraph}, finding how the nodes of a network can be -partitioned into structurally equivalent classes can be as easy as:

    -
    -
    node_in_structural(ison_algebra)
    -
    -ison_algebra %>% 
    -  mutate(se = node_in_structural(ison_algebra)) %>% 
    -  graphr(node_color = "se")
    - -
    -

    But actually, a lot is going on behind the scenes here that we can -unpack. Understanding what is going on behind the scenes is important -for understanding how these classes are identified and how to interpret -them.

    -
    -
    -

    Step one: starting with a census

    -

    All equivalence classes are based on nodes’ similarity across some -profile of motifs. In {migraph}, we call these motif -censuses. Any kind of census can be used, and -{migraph} includes a few options, but -node_in_structural() is based off of the census of all the -nodes’ ties, both outgoing and incoming ties, to characterise their -relationships to tie partners.

    -
    - -
    -
    -
    # Let's use the node_tie_census() function
    -# The function accepts an object such as a dataset
    -# Hint: Which dataset are we using in this tutorial?
    -node_tie_census(____)
    -
    -
    -
    node_tie_census(ison_algebra)
    -
    -
    -
    # Now, let's get the dimensions of an object via the dim() function
    -dim(node_tie_census(ison_algebra))
    -
    -
    -
    node_tie_census(ison_algebra)
    -dim(node_tie_census(ison_algebra))
    -
    -

    We can see that the result is a matrix of 16 rows and 96 columns, -because we want to catalogue or take a census of all the different -incoming/outgoing partners our 16 nodes might have across these three -networks. Note also that the result is a weighted matrix; what would you -do if you wanted it to be binary?

    -
    - -
    -
    -
    # we could convert the result using as.matrix, returning the ties 
    -as.matrix((node_tie_census(ison_algebra)>0)+0)
    -
    -
    -
    # But it's easier to simplify the network by removing the classification into different types of ties.
    -# Note that this also reduces the total number of possible paths between nodes
    -ison_algebra %>%
    -  select_ties(-type) %>%
    -  node_tie_census()
    -
    -

    Note that node_tie_census() does not need to be passed -to node_in_structural() — this is done automatically! -However, the more generic node_in_equivalence() is -available and can be used with whichever tie census is desired. Feel -free to explore using some of the other censuses available in -{migraph}, though some common ones are already used in the -other equivalence convenience functions, -e.g. node_triad_census() in node_in_regular() -and node_path_census() in -node_in_automorphic().

    -
    -
    -

    Step two: growing a tree of similarity

    -

    The next part takes this census and creates a dendrogram based on -distance or dissimilarity among the nodes’ census profiles. This is all -done internally within e.g. node_in_structural(), though -there are two important parameters that can be set to obtain different -results.

    -

    First, users can set the type of distance measure used. For -enthusiasts, this is passed on to stats::dist(), so that -help page should be consulted for more details. By default -"euclidean" is used.

    -

    Second, we can also set the type of clustering algorithm employed. By -default, {migraph}’s equivalence functions use hierarchical -clustering, "hier", but for compatibility and enthusiasts, -we also offer "concor", which implements a CONCOR -(CONvergence of CORrelations) algorithm.

    -

    We can see the difference from varying the clustering algorithm -and/or distance by plotting the dendrograms (hidden) in the output from -node_in_structural():

    -
    -
    alge <- to_named(ison_algebra) # fake names to make comparison clearer
    -plot(node_in_structural(alge, cluster = "hier", distance = "euclidean"))
    -
    -# changing the type of distance used
    -plot(node_in_structural(alge, cluster = "hier", distance = "manhattan"))
    -
    -# changing the clustering algorithm
    -plot(node_in_structural(alge, cluster = "concor", distance = "euclidean"))
    - -
    -
    -
    -
    -
    -
    - -
    -
    -

    So plotting a membership vector from -{migraph} returns a dendrogram with the names of the nodes -on the y-axis and the distance between them on the -x-axis. Using the census as material, the distances between the -nodes is used to create a dendrogram of (dis)similarity among the nodes. -Basically, as we move to the right, we’re allowing for more and more -dissimilarity among those we cluster together. A fork or branching point -indicates the level of dissimilarity at which those two or more nodes -would be said to be equivalent. Where two nodes’ branches join/fork -represents the maximum distance among all their leaves, so more similar -nodes’ branches fork closer to the tree’s canopy, and less similar -(groups of) nodes don’t join until they form basically the trunk.

    -

    Note that with the results using the hierarchical clustering -algorithm, the distance directly affects the structure of the tree (and -the results).

    -

    The CONCOR dendrogram operates a bit differently to hierarchical -clustering though. Instead it represents how converging correlations -repeatedly bifurcate the nodes into one of two partitions. As such the -‘distance’ is really just the (inverse) number of steps of bifurcations -until nodes belong to the same class.

    -
    -
    -

    Step three: identifying the number of clusters

    -

    Another bit of information represented in the dendrogram is where the -tree should be cut (the dashed red line) and how the nodes are assigned -to the branches (clusters) present at that cut-point.

    -

    But where does this red line come from? Or, more technically, how do -we identify the number of clusters into which to assign nodes?

    -

    {migraph} includes several different ways of -establishing k, or the number of clusters. Remember, the -further to the right the red line is (the lower on the tree the cut -point is) the more dissimilar we’re allowing nodes in the same cluster -to be. We could set this ourselves by just passing k an -integer.

    -
    -
    plot(node_in_structural(alge, k = 2))
    - -
    -

    But we’re really just guessing. Maybe 2 is not the best -k? To establish what the best k is for this -clustering exercise, we need to iterate through a number of potential -k and consider their fitness by some metric. There are a -couple of options here.

    -

    One is to consider, for each k, how correlated this -partition is with the observed network. When there is one cluster for -each vertex in the network, cell values will be identical to the -observed correlation matrix, and when there is one cluster for the whole -network, the values will all be equal to the average correlation across -the observed matrix. So the correlations in each by-cluster matrix are -correlated with the observed correlation matrix to see how well each -by-cluster matrix fits the data.

    -

    Of course, the perfect partition would then be where all nodes are in -their own cluster, which is hardly ‘clustering’ at all. Also, increasing -k will always improve the correlation. But if one were to -plot these correlations as a line graph, then we might expect there to -be a relatively rapid increase in correlation as we move from, for -example, 3 clusters to 4 clusters, but a relatively small increase from, -for example, 13 clusters to 14 clusters. By identifying the inflection -point in this line graph, {migraph} selects a number of -clusters that represents a trade-off between fit and parsimony. This is -the k = "elbow" method.

    -

    The other option is to evaluate a candidate for k based -not on correlation but on a metric of how similar each node in a cluster -is to others in its cluster and how dissimilar each node is to -those in a neighbouring cluster. When averaged over all nodes and all -clusters, this provides a ‘silhouette coefficient’ for a candidate of -k. Choosing the number of clusters that maximizes this -coefficient, which is what k = "silhouette" does, can -return a somewhat different result to the elbow method. See what we have -here, with all other arguments held the same:

    -
    -
    plot(node_in_structural(alge, k = "elbow"))
    -plot(node_in_structural(alge, k = "silhouette"))
    - -
    -

    Ok, so it looks like the elbow method returns k == 3 as -a good trade-off between fit and parsimony. The silhouette method, by -contrast, sees k == 4 as maximising cluster similarity and -dissimilarity. Either is probably fine here, and there is much debate -around how to select the number of clusters anyway. However, the -silhouette method seems to do a better job of identifying how unique the -16th node is. The silhouette method is also the default in -{migraph}.

    -

    Note that there is a somewhat hidden parameter here, -range. Since testing across all possible numbers of -clusters can get computationally expensive (not to mention -uninterpretable) for large networks, {migraph} only -considers up to 8 clusters by default. This however can be modified to -be higher or lower, e.g. range = 16.

    -

    Finally, one last option is k = "strict", which only -assigns nodes to the same partition if there is zero distance between -them. This is quick and rigorous solution, however oftentimes this -misses the point in finding clusters of nodes that, despite some -variation, can be considered as similar on some dimension.

    -
    -
    plot(node_in_structural(alge, k = "strict"))
    - -
    -

    Here for example, no two nodes have precisely the same tie-profile, -otherwise their branches would join/fork at a distance of 0. As such, -k = "strict" partitions the network into 16 clusters. Where -networks have a number of nodes with strictly the same profiles, such a -k-selection method might be helpful to recognise those in exactly the -same structural position, but here it essentially just reports nodes’ -identity.

    -
    -
    -
    -

    Blockmodelling

    -
    -

    Summarising profiles

    -

    Ok, so now we have a result from establishing nodes’ membership in -structurally equivalent classes. We can graph this of course, as -above:

    -
    -
    alge %>% 
    -  mutate(se = node_in_structural(alge)) %>% 
    -  graphr(node_color = "se")
    - -
    -

    While this plot adds the structurally equivalent classes information -to our earlier graph, it doesn’t really help us understand how the -classes relate. That is, we might be less interested in how the -individuals in the different classes relate, and more interested in how -the different classes relate in aggregate.

    -

    One option that can be useful for characterising what the profile of -ties (partners) is for each position/equivalence class is to use -summary(). It summarises some census result by a partition -(equivalence/membership) assignment. By default it takes the average of -ties (values), but this can be tweaked by assigning some other summary -statistic as FUN =.

    -
    - -
    -
    -
    # Let's wrap node_tie_census inside the summary() function
    -# and pass it a membership result
    -summary(node_tie_census(____),
    -        membership = ____)
    -
    -
    -
    summary(node_tie_census(alge),
    -        membership = node_in_structural(alge))
    -
    -

    This node census produces 96 columns, \(16 -\text{nodes} * 2 \text{directions} * 3 \text{edge types}\), it -takes a bit to look through what varies between the different classes as -‘blocked’. But only four rows (the four structurally equivalent classes, -according to the default).

    -

    Another way to do this is to plot the blockmodel as a whole. Passing -the plot() function an adjacency/incidence matrix along -with a membership vector allows the matrix to be sorted and framed -(without the membership vector, just the adjacency/incidence matrix is -plotted):

    -
    - -
    -
    -
    # Let's plot the blockmodel using the plot() function we used for the dendrograms
    -# Instead of node_tie_census() let's us as_matrix()
    -
    -plot(as_matrix(____),
    -     membership = ____)
    -
    -
    -
    # plot the blockmodel for the whole network
    -plot(as_matrix(alge),
    -     membership = node_in_structural(alge))
    -
    -# plot the blockmodel for the friends, tasks, and social networks separately
    -plot(as_matrix(friends),
    -     membership = node_in_structural(alge)) +
    -plot(as_matrix(tasks),
    -     membership = node_in_structural(alge)) +
    -plot(as_matrix(social),
    -     membership = node_in_structural(alge))
    -
    -

    By passing the membership argument our structural equivalence -results, the matrix is re-sorted to cluster or ‘block’ nodes from the -same class together. This can help us interpret the general -relationships between classes. For example, when we plot the friends, -tasks, and social networks using the structural equivalence results, we -might characterise them like so:

    -
      -
    • The first group work together only in reciprocal pairs on tasks, -preferring to approach the nerd but also those of the other two roles. -While they hang out with each other socially quite a bit, friendship -from groups 2 and 3 are preferred.
    • -
    • The second group also work together only in reciprocal pairs, -preferring to work collaboratively with group 1 or also the nerd. They -also tend to count those from group 1 as friends, and hang out with -everyone else but themselves.
    • -
    • The third group will work with either some in group 1 and 3, or 2, -but again prefer the nerd for task advice. They are pretty good friends -with each other though, and pretty happy to socialise with -everyone.
    • -
    • The nerd is a loner, no friends, but everyone hangs out with them -for task advice.
    • -
    -
    -
    -

    Reduced graph

    -

    Lastly, we can consider how classes of nodes relate to one -another in a blockmodel. Let’s use the 4-cluster solution on the valued -network (though binary is possible too) to create a reduced -graph. A reduced graph is a transformation of a network such that -the nodes are no longer the individual nodes but the groups of one or -more nodes as a class, and the ties between these blocked nodes can -represent the sum or average tie between these classes. Of course, this -means that there can be self-ties or loops, because even if the original -network was simple (not complex), any within-class ties will end up -becoming loops and thus the network will be complex.

    -
    -
    (bm <- to_blocks(alge, node_in_structural(alge)))
    -
    -bm <- bm %>% as_tidygraph %>% 
    -  mutate(name = c("Freaks", "Squares", "Nerds", "Geek"))
    -graphr(bm)
    - -
    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    - - - - - - -
    -
    - -
    - -
    -
    -
    -
    - - -
    -

    Position

    -

    by James Hollway

    -
    - - -
    -
    -
    -
    - - -
    -
    - - - - - - - - - - - - - - - - diff --git a/inst/tutorials/tutorial5/position_data/data_chunks_index.txt b/inst/tutorials/tutorial5/position_data/data_chunks_index.txt deleted file mode 100644 index 2846c4f9..00000000 --- a/inst/tutorials/tutorial5/position_data/data_chunks_index.txt +++ /dev/null @@ -1 +0,0 @@ -data.RData From c5a9918dacd32743bb9ccadd233cce5b881f5cb1 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 12:21:52 +0200 Subject: [PATCH 70/97] Migrated topology tutorial to manynet --- inst/tutorials/tutorial6/topology.Rmd | 652 ------- inst/tutorials/tutorial6/topology.html | 2476 ------------------------ 2 files changed, 3128 deletions(-) delete mode 100644 inst/tutorials/tutorial6/topology.Rmd delete mode 100644 inst/tutorials/tutorial6/topology.html diff --git a/inst/tutorials/tutorial6/topology.Rmd b/inst/tutorials/tutorial6/topology.Rmd deleted file mode 100644 index 27e41782..00000000 --- a/inst/tutorials/tutorial6/topology.Rmd +++ /dev/null @@ -1,652 +0,0 @@ ---- -title: "Topology" -author: "by James Hollway, Andrea Biswas-Tortajada" -output: - learnr::tutorial: - theme: journal -runtime: shiny_prerendered -description: > - This tutorial aims to teach you how to create deterministic networks, - generate probabilistic networks, identify core-periphery structures, - and measure network resilience. ---- - -```{r setup, include = FALSE} -library(learnr) -library(manynet) -library(migraph) -library(patchwork) -knitr::opts_chunk$set(echo = FALSE) -learnr::random_phrases_add(language = "fr", - praise = c("C'est génial!", - "Beau travail", - "Excellent travail!", - "Bravo!", - "Super!", - "Bien fait", - "Bien joué", - "Tu l'as fait!", - "Je savais que tu pouvais le faire.", - "Ça a l'air facile!", - "C'était un travail de première classe.", - "C'est ce que j'appelle un bon travail!"), - encouragement = c("Bon effort", - "Vous l'avez presque maîtrisé!", - "Ça avance bien.", - "Continuez comme ça.", - "Continuez à travailler dur!", - "Vous apprenez vite!", - "Vous faites un excellent travail aujourd'hui.")) -learnr::random_phrases_add(language = "en", - praise = c("C'est génial!", - "Beau travail!", - "Bravo!", - "Super!"), - encouragement = c("Bon effort")) -``` - -In this tutorial, we'll explore: - -- how to create or generate different network topologies -- the core-periphery structure of a network -- features of a network related to its resilience - -## Generate networks of different structures - -This tutorial covers a range of different network topologies: -trees, lattices, random, small-world, scale-free, and core-periphery -networks. -These ideal networks exaggerate centrality, cohesion, and randomness features, -and are thus great for theory-building and investigating the relationship between rules and structure. - -In this practical, we're going to create/generate -a number of ideal-typical network topologies and plot them. -We'll first look at some deterministic algorithms for _creating_ networks -of different structures, -and then look at how the introduction of some randomness can _generate_ a variety of network structures. - -### Deterministic graphs - -To begin with, let's create a few 'empty' and full/'complete' graphs. -You will want to use some of the `create_*()` group of functions from `{manynet}`, -because they create graphs following some strict rule(s). -The two functions you will want to use here are `create_empty()` and `create_filled()`. -`create_empty()` creates an empty graph with the given number of nodes, -in this case 50 nodes. -For `create_filled()` we're creating a full graph, -where all of the nodes are connected to all of the other nodes. - -Let's say that we want to explore networks of fifty nodes in this script. -Graph one empty and one complete network with 50 nodes each, -give them an informative title, and plot the graphs together. -What would a complete network with half the nodes look like? -Add that too. - -```{r empty, exercise=TRUE, purl = FALSE} - -``` - -```{r empty-solution} -(graphr(create_empty(50), "circle") + ggtitle("Empty graph")) -(graphr(create_filled(50)) + ggtitle("Complete graph")) -(graphr(create_filled(50/2)) + ggtitle("Complete graph (smaller)")) -``` - -#### Stars - -In a star network, there is one node to which all other nodes are connected. -There is no transitivity. -The maximum path length is two. -And centrality is maximised! -This network maximises all centrality measures as one node acts -as the sole bridge connecting one part of the network to the other. - -Use the `create_star()` function to graph three star networks: - -- an undirected star network -- a out-directed star network -- and an in-directed star network - -```{r star, exercise = TRUE, purl = FALSE} - -``` - -```{r star-solution} -(graphr(create_star(50)) + ggtitle("Star graph")) -(graphr(create_star(50, directed = TRUE)) + ggtitle("Star out")) -(graphr(to_redirected(create_star(50, directed = TRUE))) + ggtitle("Star in")) -``` - -#### Trees - -Trees, or regular trees, are networks with branching nodes. -They can be directed or undirected, and tend to indicate strong hierarchy. -Again graph three networks: - -- one undirected with 2 branches per node -- a directed network with 2 branches per node -- the same as above, but graphed using the "tree" layout - -```{r tree, exercise = TRUE, purl = FALSE} - -``` - -```{r tree-solution} -# width argument specifies the breadth of the branches -(graphr(create_tree(50, width = 2)) + ggtitle("Tree graph")) -(graphr(create_tree(50, width = 2, directed = TRUE)) + ggtitle("Tree out")) -(graphr(create_tree(50, width = 2, directed = TRUE), "tree") + ggtitle("Tree layout")) -``` - -Try varying the `width` argument to see the result. - -#### Lattices - -Lattices reflect highly clustered networks -where there is a high likelihood that interaction partners also interact. -They are used to show how clustering facilitates or limits diffusion -or makes pockets of behaviour stable. - -```{r lat-qa, echo=FALSE, purl = FALSE} -question("Why are lattices considered highly clustered?", - answer("Because neighbours are likely also neighbours of each other", - message = learnr::random_praise(), - correct = TRUE), - answer("Because all nodes are directly connected to each other", - message = learnr::random_encouragement()), - answer("Because there is a single component", - message = learnr::random_encouragement()), - answer("Because there is a single community", - message = learnr::random_encouragement()), - random_answer_order = TRUE, - allow_retry = TRUE) -``` - -Note that `create_lattice()` in `{manynet}` works a little differently -to how it works in `{igraph}`. -In `{igraph}` the number or vector passed to the function indicates -the length of each dimension. -So `c(50)` would be a one-dimensional lattice, -essentially a chain of 50 nodes connected to their neighbours. -`c(50,50)` would be a two-dimensional lattice, -of 50 nodes long and 50 nodes wide. -`c(50,50,50)` would be a three-dimensional lattice, -of 50 nodes long, 50 nodes wide, and 50 nodes deep, etc. - -_But_ this doesn't help us when we want to see what a lattice representation -with the same order (number of nodes) as a given network would be. -For example, perhaps we just want to know what a lattice with 50 nodes -would look like. -So `{manynet}` instead tries to find the most even or balanced -two-dimensional representation with a given number of nodes. - -Graph two lattices, one with 50 nodes, -and another with half the number of nodes. - -```{r lattices, exercise = TRUE, purl = FALSE} - -``` - -```{r lattices-solution} -(graphr(create_lattice(50)) + ggtitle("One-mode lattice graph")) -(graphr(create_lattice(50/2)) + ggtitle("Smaller lattice graph")) -``` - -#### Rings - -This creates a graph where each node has two separate neighbours -which creates a ring graph. -Graph three ring networks: - -- one with 50 nodes -- one with 50 nodes where they are connected to neighbours two steps away, - on a "circle" layout -- the same as above, but on a "stress" layout - -```{r rings, exercise = TRUE, purl = FALSE} - -``` - -```{r rings-solution} -(graphr(create_ring(50)) + ggtitle("Ring graph", subtitle = "Starring Naomi Watts")) -# width argument specifies the width of the ring -(graphr(create_ring(50, width = 2), "circle") + ggtitle("The Ring Two", subtitle = "No different?")) -(graphr(create_ring(50, width = 2), "stress") + ggtitle("The Ring Two v2.0")) -``` - -### Probabilistic graphs - -Next we are going to take a look at some probabilistic graphs. -These involve some random element, perhaps in addition to specific rules, -to stochastically 'generate' networks of certain types of topologies. -As such, we'll be using the `generate_*()` group of functions from `{manynet}`. - -#### Random graphs - -An Erdös-Renyi graph is simply a random graph. -You will need to specify the probability of a tie -in addition to the number of nodes. -An Erdos-Renyi graph on the vertex set $V$ is a random graph -which connects each pair of nodes ${i,j}$ with probability $p$, independent. -Note that for a “sparse” ER graphs, $p$ must decrease as $N$ goes up. -Generate three random networks of 50 nodes and a density of 0.08: - -```{r random, exercise = TRUE, purl = FALSE} - -``` - -```{r random-solution} -(graphr(generate_random(50, 0.08)) + ggtitle("Random 1 graph")) -(graphr(generate_random(50, 0.08)) + ggtitle("Random 2 graph")) -(graphr(generate_random(50, 0.08)) + ggtitle("Random 3 graph")) -``` - -Keep going if you like... it will be a little different every time. -Note that you can also pass the second argument an integer, -in which case the function will interpret that as the number of ties/edges rather than the probability that a tie is present. -Try generating a random graph with 200 edges/ties now: - -```{r randomno, exercise = TRUE, purl = FALSE} - -``` - -```{r randomno-solution} -(erdren4 <- graphr(generate_random(50, 200)) + ggtitle("Random 1 graph")) -``` - -#### Small-world graphs - -Remember the ring graph from above? -What if we rewire (change) some of the edges at a certain probability? -This is how small-world networks are generated. -Graph three small-world networks, all with 50 nodes and a rewiring probability of 0.025. - -```{r smallw, exercise = TRUE, purl = FALSE} - -``` - -```{r smallw-solution} -(graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 1 graph")) -(graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 2 graph")) -(graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 3 graph")) -``` - -With on average 2.5 ties randomly rewired, does the structure look different? -This is a small-world network, where clustering/transitivity remains high -but path lengths are much lower than they would otherwise be. -Remember that in a small-world network, the shortest-path distance between nodes -increases sufficiently slowly as a function of the number of nodes in the network. -You can also call these networks a Watts–Strogatz toy network. -If you want to review this, go back to the reading by Watts (2004). - -There is also such a thing as a network's small-world coefficient. -See the help page for more details, -but with the default equation ('omega'), -the coefficient typically ranges between 0 and 1, -where 1 is as close to a small-world as possible. -Try it now on a small-world generated network, -but with a rewiring probability of 0.25: - -```{r smallwtest, exercise = TRUE, purl = FALSE} - -``` - -```{r smallwtest-solution} -network_smallworld(generate_smallworld(50, 0.25)) -``` - -#### Scale-free graphs - -There is another famous model in network science: the scale-free model. -Remember: -"In many real-world networks, the distribution of the number of network neighbours -the degree distribution is typically right-skewed with a "heavy tail". -A majority of the nodes have less-than-average degree and -a small fraction of hubs are many times better connected than average (2004, p. 250). - -The following generates a scale-free graph according to the Barabasi-Albert (BA) model -that rests upon the mechanism of preferential attachment. -More on this in the Watts paper (2005, p.51) and Merton (1968). -The BA model rests on two mechanisms: -population growth and preferential attachment. -Population growth: real networks grow in time as new members join the population. -Preferential/cumulative attachment means that newly arriving nodes will tend to -connect to already well-connected nodes rather than poorly connected ones. - -Generate and graph three scale-free networks, -with alpha parameters of 0.5, 1, and 1.5. - -```{r scalef, exercise = TRUE, purl = FALSE} - -``` - -```{r scalef-solution} -(graphr(generate_scalefree(50, 0.5)) + - ggtitle("Scalefree 1 graph", subtitle = "Power = .5")) -(graphr(generate_scalefree(50, 1)) + - ggtitle("Scalefree 2 graph", subtitle = "Power = 1")) -(graphr(generate_scalefree(50, 1.5)) + - ggtitle("Scalefree 3 graph", subtitle = "Power = 1.5")) -``` - -You can also test whether a network has a degree distribution that fits -the scale-free model. -When a Kolmogorov-Smirnov test p-value less than 0.05 is implied, -a message is given that you should reject the hypothesis -that a power law fits here. -With an alpha/power-law exponent between 2 and 3, -one generally cannot reject the hypothesis that the observed data -comes from a power-law distribution. - -```{r scaleftest, exercise = TRUE, purl = FALSE} - -``` - -```{r scaleftest-solution} -network_scalefree(generate_scalefree(50, 2)) -``` - -## Core-Periphery - -### Core-periphery graphs - -Lastly, we'll take a look at some core-periphery graphs. -The most common definition of a core-periphery network -is one in which the network can be partitioned into two groups -such that one group of nodes (the core) has -dense interactions among themselves, -moderately dense interactions with the second group, -and the second group (the periphery) has -sparse interactions among themselves. - -```{r corevcomm-qa, echo=FALSE, purl = FALSE} -question("Can a single network have both a community structure and a core-periphery structure?", - answer("No", message = learnr::random_encouragement()), - answer("Yes", - message = learnr::random_praise(), - correct = TRUE), - random_answer_order = TRUE, - allow_retry = TRUE) -``` - -We can visualise extreme versions of such a network -using the `create_core()` function. -Graph a core-periphery network of 50 nodes -(which, unless a core-periphery membership assignment is given, -will be split evenly between core and periphery partitions). - -```{r core, exercise=TRUE, purl = FALSE} - -``` - -```{r core-solution} -(graphr(create_core(50)) + ggtitle("Core")) -``` - -### Core-periphery assignment - -Let's consider identifying the core and peripheral nodes in a network. -Let's use the `ison_lawfirm` dataset from `{manynet}`. -This dataset involves relations between partners in a corporate law firm in New England. -First of all, graph the data and see whether you can guess which nodes -might be part of the core and which are part of the periphery. -Color the nodes by Gender, Office, Practice, and School. -Any you might think correlate with core status? - -```{r gnet, exercise=TRUE, purl = FALSE} - -``` - -```{r gnet-solution} -graphr(ison_lawfirm, node_color = "school") -``` - -Next, let's assign nodes to the core and periphery blocks -using the `node_in_core()` function from `{migraph}`. -It works pretty straightforwardly. -By default it runs down the rank order of nodes by their degree, -at each step working out whether including the next highest degree node -in the core will maximise the core-periphery structure of the network. - -```{r nodecore, exercise=TRUE, purl = FALSE} - -``` - -```{r nodecore-solution} -ison_lawfirm %>% - mutate(nc = node_in_core(ison_lawfirm)) %>% - graphr(node_color = "nc") -``` - -This graph suggests that there might even be two cores here, -one on the left and one on the right. - -But is it really all that much of a core-periphery structure? -We can establish how correlated our network is compared to -a core-periphery model of the same dimension using `network_core()`. - -```{r netcore, exercise=TRUE, purl = FALSE} - -``` - -```{r netcore-solution} -network_core(ison_lawfirm, node_in_core(ison_lawfirm)) -``` - -```{r corecorr-qa, echo=FALSE, purl = FALSE} -question("What can we say about this correlation.", - answer("It is a perfect positive relationship", - message = learnr::random_encouragement()), - answer("It is fairly strong", - message = learnr::random_encouragement()), - answer("It is negative", - message = learnr::random_encouragement()), - answer("There is absolutely no correlation", - message = learnr::random_encouragement()), - answer("None of the above", correct = TRUE, - message = learnr::random_praise()), - allow_retry = TRUE -) -``` - -Note that `node_in_core()` also includes a method that descends through -the rank order of nodes' eigenvector centralities instead of degree centralities. -Why might that not be such a good choice here? - -Now let's see whether our core-periphery membership vector correlates with any of the three -categorical attributes we looked at before. -Since we're doing this on categorical variables, we'll use the Chi-squared test in base R. -Take a look and see whether there is a statistically significant association -between gender and core (or periphery) status. - -```{r chisq, exercise=TRUE, purl=FALSE} - -``` - -```{r chisq-solution} -chisq.test(node_in_core(ison_lawfirm), node_attribute(ison_lawfirm, "Gender")) -``` - -```{r chisq-qa, echo=FALSE, purl = FALSE} -question("There a statistically significant association between the core assignment and...", - answer("gender.", - message = learnr::random_encouragement()), - answer("office.", - message = learnr::random_encouragement()), - answer("school.", - message = learnr::random_encouragement()), - answer("practice.", - message = learnr::random_encouragement()), - answer("none of the above variables.", correct = TRUE, - message = learnr::random_praise()), - allow_retry = TRUE -) -``` - -### Coreness values - -An alternative route is to identify 'core' nodes -depending on their _k_-coreness. -In `{migraph}`, we can return nodes _k_-coreness -with `node_coreness()` instead of -the `node_in_core()` used for core-periphery. - -```{r nodecoren, exercise=TRUE, purl = FALSE} - -``` - -```{r nodecoren-solution} -ison_lawfirm %>% - mutate(ncn = node_coreness(ison_lawfirm)) %>% - graphr(node_color = "ncn") + scale_colour_sdgs() -``` - -```{r dich-qa, echo=FALSE, purl = FALSE} -question("Which has more than two classes/groups.", - answer("node_coreness()", correct = TRUE, - message = learnr::random_praise()), - answer("node_in_core()", - message = learnr::random_encouragement()), - random_answer_order = TRUE, - allow_retry = TRUE -) -``` - -```{r ness-qa, echo=FALSE, purl = FALSE} -question("Select the correct definitions:", - answer("The k-core of a network is a maximal subgraph in which each vertex has at least degree k.", correct = TRUE, - message = learnr::random_praise()), - answer("The coreness of a node is k if it belongs to the k-core but not to the (k+1)-core.", correct = TRUE), - answer("The coreness of a node is equal to its degree.", - message = learnr::random_encouragement()), - random_answer_order = TRUE, - allow_retry = TRUE -) -``` - -## Network Resilience - -### How cohesive is the network? - -When investigating a network's resilience, -we might think of whether the network will remain connected despite some nodes or ties dropping out. -Let's explore how resilient a (core) network of adolescents (`ison_adolescents`) might be. -First, we might be interested in whether the network is connected at all. - -```{r connected, exercise=TRUE, purl = FALSE} - -``` - -```{r connected-solution} -network_connectedness(ison_adolescents) -``` - -This measure gets at the proportion of dyads that can reach each other in the network. -Another way to get at this would be to see how many components there are in the network. - -```{r connect-qa, echo=FALSE, purl=FALSE} -question("But counting the number of components instead of connectedness can overemphasise:", - answer("Isolates", correct = TRUE, - message = learnr::random_praise()), - answer("Small components", correct = TRUE, - message = learnr::random_encouragement()), - answer("Density", - message = learnr::random_encouragement()), - random_answer_order = TRUE, - allow_retry = TRUE -) -``` - -A dropped tie can have severe consequences to the topology of a network -if it is a bridge, say. -But a dropped node can be even more consequential, as it will take any ties it has with it. -Find out how many dropped nodes it would take to (further) fragment the network. - -```{r cohesion, exercise=TRUE, purl = FALSE} - -``` - -```{r cohesion-solution} -network_cohesion(ison_adolescents) -``` - -```{r cohesion-qa, echo=FALSE, purl = FALSE} -question("The result of this function represents...", - answer("the minimum number of nodes necessary to remove from the network to increase the number of components.", correct = TRUE, - message = learnr::random_praise()), - answer("the number of strong components in the network.", - message = learnr::random_encouragement()), - answer("the minimum number of ties necessary to remove from the network to increase the number of components.", - message = "This is actually the definition of `node_adhesion()`."), - random_answer_order = TRUE, - allow_retry = TRUE -) -``` - -```{r res-qa, echo=FALSE, purl = FALSE} -question("The higher the minimum number of nodes to remove...", - answer("the more resilient is the network.", correct = TRUE, - message = learnr::random_praise()), - answer("the less resilient the network.", - message = learnr::random_encouragement()), - random_answer_order = TRUE, - allow_retry = TRUE -) -``` - -### Identifying cutpoints - -But which are these nodes? Is there more than one? -Nodes that endanger fragmentation of the network are called cutpoints. -Find and use a function to identify which, if any, of the nodes in the `ison_adolescents` -network are cutpoints. - -```{r idcuts, exercise = TRUE, purl=FALSE} - -``` - -```{r idcuts-solution} -node_is_cutpoint(ison_adolescents) -``` - -Ok, so this results in a vector identifying which nodes are cutpoints (TRUE) or not (FALSE). -Somewhat more useful though would be to highlight these nodes on the network. -Can you add a node attribute that highlights which nodes are cutpoints? - -```{r closerlook, exercise = TRUE, purl=FALSE} - -``` - -```{r closerlook-solution} -ison_adolescents |> mutate(cut = node_is_cutpoint(ison_adolescents)) |> - graphr(node_color = "cut") -``` - -### Identifying bridges - -Let's do something similar now, but with respect to ties rather than nodes. - -```{r tieside, exercise = TRUE, purl=FALSE} - -``` - -```{r tieside-solution} -network_adhesion(ison_adolescents) -ison_adolescents |> mutate_ties(cut = tie_is_bridge(ison_adolescents)) |> - graphr(edge_color = "cut") -``` - -We could also investigate the opposite of a bridge, -the degree to which ties are deeply embedded in triangles. -This is called (rather confusingly) tie cohesion. - -```{r tiecoh, exercise = TRUE, purl=FALSE} - -``` - -```{r tiecoh-solution} -ison_adolescents |> mutate_ties(coh = tie_cohesion(ison_adolescents)) |> - graphr(edge_color = "coh") -``` - -Where would you target your efforts if you wanted to fragment this network? diff --git a/inst/tutorials/tutorial6/topology.html b/inst/tutorials/tutorial6/topology.html deleted file mode 100644 index 6577327f..00000000 --- a/inst/tutorials/tutorial6/topology.html +++ /dev/null @@ -1,2476 +0,0 @@ - - - - - - - - - - - - - - - - - -Topology - - - - - - - - - - - - - - - - - - - - - -Skip to Tutorial Content - - - -
    -
    - -
    - -

    In this tutorial, we’ll explore:

    -
      -
    • how to create or generate different network topologies
    • -
    • the core-periphery structure of a network
    • -
    • features of a network related to its resilience
    • -
    -
    -

    Generate networks of different structures

    -

    This tutorial covers a range of different network topologies: trees, -lattices, random, small-world, scale-free, and core-periphery networks. -These ideal networks exaggerate centrality, cohesion, and randomness -features, and are thus great for theory-building and investigating the -relationship between rules and structure.

    -

    In this practical, we’re going to create/generate a number of -ideal-typical network topologies and plot them. We’ll first look at some -deterministic algorithms for creating networks of different -structures, and then look at how the introduction of some randomness can -generate a variety of network structures.

    -
    -

    Deterministic graphs

    -

    To begin with, let’s create a few ‘empty’ and full/‘complete’ graphs. -You will want to use some of the create_*() group of -functions from {manynet}, because they create graphs -following some strict rule(s). The two functions you will want to use -here are create_empty() and create_filled(). -create_empty() creates an empty graph with the given number -of nodes, in this case 50 nodes. For create_filled() we’re -creating a full graph, where all of the nodes are connected to all of -the other nodes.

    -

    Let’s say that we want to explore networks of fifty nodes in this -script. Graph one empty and one complete network with 50 nodes each, -give them an informative title, and plot the graphs together. What would -a complete network with half the nodes look like? Add that too.

    -
    - -
    -
    -
    (graphr(create_empty(50), "circle") + ggtitle("Empty graph"))
    -(graphr(create_filled(50)) + ggtitle("Complete graph"))
    -(graphr(create_filled(50/2)) + ggtitle("Complete graph (smaller)"))
    -
    -
    -

    Stars

    -

    In a star network, there is one node to which all other nodes are -connected. There is no transitivity. The maximum path length is two. And -centrality is maximised! This network maximises all centrality measures -as one node acts as the sole bridge connecting one part of the network -to the other.

    -

    Use the create_star() function to graph three star -networks:

    -
      -
    • an undirected star network
    • -
    • a out-directed star network
    • -
    • and an in-directed star network
    • -
    -
    - -
    -
    -
    (graphr(create_star(50)) + ggtitle("Star graph"))
    -(graphr(create_star(50, directed = TRUE)) + ggtitle("Star out"))
    -(graphr(to_redirected(create_star(50, directed = TRUE))) + ggtitle("Star in"))
    -
    -
    -
    -

    Trees

    -

    Trees, or regular trees, are networks with branching nodes. They can -be directed or undirected, and tend to indicate strong hierarchy. Again -graph three networks:

    -
      -
    • one undirected with 2 branches per node
    • -
    • a directed network with 2 branches per node
    • -
    • the same as above, but graphed using the “tree” layout
    • -
    -
    - -
    -
    -
    # width argument specifies the breadth of the branches
    -(graphr(create_tree(50, width = 2)) + ggtitle("Tree graph"))
    -(graphr(create_tree(50, width = 2, directed = TRUE)) + ggtitle("Tree out"))
    -(graphr(create_tree(50, width = 2, directed = TRUE), "tree") + ggtitle("Tree layout"))
    -
    -

    Try varying the width argument to see the result.

    -
    -
    -

    Lattices

    -

    Lattices reflect highly clustered networks where there is a high -likelihood that interaction partners also interact. They are used to -show how clustering facilitates or limits diffusion or makes pockets of -behaviour stable.

    -
    -
    -
    -
    -
    - -
    -
    -

    Note that create_lattice() in {manynet} -works a little differently to how it works in {igraph}. In -{igraph} the number or vector passed to the function -indicates the length of each dimension. So c(50) would be a -one-dimensional lattice, essentially a chain of 50 nodes connected to -their neighbours. c(50,50) would be a two-dimensional -lattice, of 50 nodes long and 50 nodes wide. c(50,50,50) -would be a three-dimensional lattice, of 50 nodes long, 50 nodes wide, -and 50 nodes deep, etc.

    -

    But this doesn’t help us when we want to see what a lattice -representation with the same order (number of nodes) as a given network -would be. For example, perhaps we just want to know what a lattice with -50 nodes would look like. So {manynet} instead tries to -find the most even or balanced two-dimensional representation with a -given number of nodes.

    -

    Graph two lattices, one with 50 nodes, and another with half the -number of nodes.

    -
    - -
    -
    -
    (graphr(create_lattice(50)) + ggtitle("One-mode lattice graph"))
    -(graphr(create_lattice(50/2)) + ggtitle("Smaller lattice graph"))
    -
    -
    -
    -

    Rings

    -

    This creates a graph where each node has two separate neighbours -which creates a ring graph. Graph three ring networks:

    -
      -
    • one with 50 nodes
    • -
    • one with 50 nodes where they are connected to neighbours two steps -away, on a “circle” layout
    • -
    • the same as above, but on a “stress” layout
    • -
    -
    - -
    -
    -
    (graphr(create_ring(50)) + ggtitle("Ring graph", subtitle = "Starring Naomi Watts"))
    -# width argument specifies the width of the ring
    -(graphr(create_ring(50, width = 2), "circle") + ggtitle("The Ring Two", subtitle = "No different?"))
    -(graphr(create_ring(50, width = 2), "stress") + ggtitle("The Ring Two v2.0"))
    -
    -
    -
    -
    -

    Probabilistic graphs

    -

    Next we are going to take a look at some probabilistic graphs. These -involve some random element, perhaps in addition to specific rules, to -stochastically ‘generate’ networks of certain types of topologies. As -such, we’ll be using the generate_*() group of functions -from {manynet}.

    -
    -

    Random graphs

    -

    An Erdös-Renyi graph is simply a random graph. You will need to -specify the probability of a tie in addition to the number of nodes. An -Erdos-Renyi graph on the vertex set \(V\) is a random graph which connects each -pair of nodes \({i,j}\) with -probability \(p\), independent. Note -that for a “sparse” ER graphs, \(p\) -must decrease as \(N\) goes up. -Generate three random networks of 50 nodes and a density of 0.08:

    -
    - -
    -
    -
    (graphr(generate_random(50, 0.08)) + ggtitle("Random 1 graph"))
    -(graphr(generate_random(50, 0.08)) + ggtitle("Random 2 graph"))
    -(graphr(generate_random(50, 0.08)) + ggtitle("Random 3 graph"))
    -
    -

    Keep going if you like… it will be a little different every time. -Note that you can also pass the second argument an integer, in which -case the function will interpret that as the number of ties/edges rather -than the probability that a tie is present. Try generating a random -graph with 200 edges/ties now:

    -
    - -
    -
    -
    (erdren4 <- graphr(generate_random(50, 200)) + ggtitle("Random 1 graph"))
    -
    -
    -
    -

    Small-world graphs

    -

    Remember the ring graph from above? What if we rewire (change) some -of the edges at a certain probability? This is how small-world networks -are generated. Graph three small-world networks, all with 50 nodes and a -rewiring probability of 0.025.

    -
    - -
    -
    -
    (graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 1 graph"))
    -(graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 2 graph"))
    -(graphr(generate_smallworld(50, 0.025)) + ggtitle("Smallworld 3 graph"))
    -
    -

    With on average 2.5 ties randomly rewired, does the structure look -different? This is a small-world network, where clustering/transitivity -remains high but path lengths are much lower than they would otherwise -be. Remember that in a small-world network, the shortest-path distance -between nodes increases sufficiently slowly as a function of the number -of nodes in the network. You can also call these networks a -Watts–Strogatz toy network. If you want to review this, go back to the -reading by Watts (2004).

    -

    There is also such a thing as a network’s small-world coefficient. -See the help page for more details, but with the default equation -(‘omega’), the coefficient typically ranges between 0 and 1, where 1 is -as close to a small-world as possible. Try it now on a small-world -generated network, but with a rewiring probability of 0.25:

    -
    - -
    -
    -
    network_smallworld(generate_smallworld(50, 0.25))
    -
    -
    -
    -

    Scale-free graphs

    -

    There is another famous model in network science: the scale-free -model. Remember: “In many real-world networks, the distribution of the -number of network neighbours the degree distribution is typically -right-skewed with a”heavy tail”. A majority of the nodes have -less-than-average degree and a small fraction of hubs are many times -better connected than average (2004, p. 250).

    -

    The following generates a scale-free graph according to the -Barabasi-Albert (BA) model that rests upon the mechanism of preferential -attachment. More on this in the Watts paper (2005, p.51) and Merton -(1968). The BA model rests on two mechanisms: population growth and -preferential attachment. Population growth: real networks grow in time -as new members join the population. Preferential/cumulative attachment -means that newly arriving nodes will tend to connect to already -well-connected nodes rather than poorly connected ones.

    -

    Generate and graph three scale-free networks, with alpha parameters -of 0.5, 1, and 1.5.

    -
    - -
    -
    -
    (graphr(generate_scalefree(50, 0.5)) +
    -    ggtitle("Scalefree 1 graph", subtitle = "Power = .5"))
    -(graphr(generate_scalefree(50, 1)) +
    -    ggtitle("Scalefree 2 graph", subtitle = "Power = 1"))
    -(graphr(generate_scalefree(50, 1.5)) +
    -    ggtitle("Scalefree 3 graph", subtitle = "Power = 1.5"))
    -
    -

    You can also test whether a network has a degree distribution that -fits the scale-free model. When a Kolmogorov-Smirnov test p-value less -than 0.05 is implied, a message is given that you should reject the -hypothesis that a power law fits here. With an alpha/power-law exponent -between 2 and 3, one generally cannot reject the hypothesis that the -observed data comes from a power-law distribution.

    -
    - -
    -
    -
    network_scalefree(generate_scalefree(50, 2))
    -
    -
    -
    -
    -
    -

    Core-Periphery

    -
    -

    Core-periphery graphs

    -

    Lastly, we’ll take a look at some core-periphery graphs. The most -common definition of a core-periphery network is one in which the -network can be partitioned into two groups such that one group of nodes -(the core) has dense interactions among themselves, moderately dense -interactions with the second group, and the second group (the periphery) -has sparse interactions among themselves.

    -
    -
    -
    -
    -
    - -
    -
    -

    We can visualise extreme versions of such a network using the -create_core() function. Graph a core-periphery network of -50 nodes (which, unless a core-periphery membership assignment is given, -will be split evenly between core and periphery partitions).

    -
    - -
    -
    -
    (graphr(create_core(50)) + ggtitle("Core"))
    -
    -
    -
    -

    Core-periphery assignment

    -

    Let’s consider identifying the core and peripheral nodes in a -network. Let’s use the ison_lawfirm dataset from -{manynet}. This dataset involves relations between partners -in a corporate law firm in New England. First of all, graph the data and -see whether you can guess which nodes might be part of the core and -which are part of the periphery. Color the nodes by Gender, Office, -Practice, and School. Any you might think correlate with core -status?

    -
    - -
    -
    -
    graphr(ison_lawfirm, node_color = "school")
    -
    -

    Next, let’s assign nodes to the core and periphery blocks using the -node_in_core() function from {migraph}. It -works pretty straightforwardly. By default it runs down the rank order -of nodes by their degree, at each step working out whether including the -next highest degree node in the core will maximise the core-periphery -structure of the network.

    -
    - -
    -
    -
    ison_lawfirm %>% 
    -  mutate(nc = node_in_core(ison_lawfirm)) %>% 
    -  graphr(node_color = "nc")
    -
    -

    This graph suggests that there might even be two cores here, one on -the left and one on the right.

    -

    But is it really all that much of a core-periphery structure? We can -establish how correlated our network is compared to a core-periphery -model of the same dimension using network_core().

    -
    - -
    -
    -
    network_core(ison_lawfirm, node_in_core(ison_lawfirm))
    -
    -
    -
    -
    -
    -
    - -
    -
    -

    Note that node_in_core() also includes a method that -descends through the rank order of nodes’ eigenvector centralities -instead of degree centralities. Why might that not be such a good choice -here?

    -

    Now let’s see whether our core-periphery membership vector correlates -with any of the three categorical attributes we looked at before. Since -we’re doing this on categorical variables, we’ll use the Chi-squared -test in base R. Take a look and see whether there is a statistically -significant association between gender and core (or periphery) -status.

    -
    - -
    -
    -
    chisq.test(node_in_core(ison_lawfirm), node_attribute(ison_lawfirm, "Gender"))
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -

    Coreness values

    -

    An alternative route is to identify ‘core’ nodes depending on their -k-coreness. In {migraph}, we can return nodes -k-coreness with node_coreness() instead of the -node_in_core() used for core-periphery.

    -
    - -
    -
    -
    ison_lawfirm %>% 
    -  mutate(ncn = node_coreness(ison_lawfirm)) %>% 
    -  graphr(node_color = "ncn") + scale_colour_sdgs()
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -

    Network Resilience

    -
    -

    How cohesive is the network?

    -

    When investigating a network’s resilience, we might think of whether -the network will remain connected despite some nodes or ties dropping -out. Let’s explore how resilient a (core) network of adolescents -(ison_adolescents) might be. First, we might be interested -in whether the network is connected at all.

    -
    - -
    -
    -
    network_connectedness(ison_adolescents)
    -
    -

    This measure gets at the proportion of dyads that can reach each -other in the network. Another way to get at this would be to see how -many components there are in the network.

    -
    -
    -
    -
    -
    - -
    -
    -

    A dropped tie can have severe consequences to the topology of a -network if it is a bridge, say. But a dropped node can be even more -consequential, as it will take any ties it has with it. Find out how -many dropped nodes it would take to (further) fragment the network.

    -
    - -
    -
    -
    network_cohesion(ison_adolescents)
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -

    Identifying cutpoints

    -

    But which are these nodes? Is there more than one? Nodes that -endanger fragmentation of the network are called cutpoints. Find and use -a function to identify which, if any, of the nodes in the -ison_adolescents network are cutpoints.

    -
    - -
    -
    -
    node_is_cutpoint(ison_adolescents)
    -
    -

    Ok, so this results in a vector identifying which nodes are cutpoints -(TRUE) or not (FALSE). Somewhat more useful though would be to highlight -these nodes on the network. Can you add a node attribute that highlights -which nodes are cutpoints?

    -
    - -
    -
    -
    ison_adolescents |> mutate(cut = node_is_cutpoint(ison_adolescents)) |> 
    -  graphr(node_color = "cut")
    -
    -
    -
    -

    Identifying bridges

    -

    Let’s do something similar now, but with respect to ties rather than -nodes.

    -
    - -
    -
    -
    network_adhesion(ison_adolescents)
    -ison_adolescents |> mutate_ties(cut = tie_is_bridge(ison_adolescents)) |> 
    -  graphr(edge_color = "cut")
    -
    -

    We could also investigate the opposite of a bridge, the degree to -which ties are deeply embedded in triangles. This is called (rather -confusingly) tie cohesion.

    -
    - -
    -
    -
    ison_adolescents |> mutate_ties(coh = tie_cohesion(ison_adolescents)) |> 
    -  graphr(edge_color = "coh")
    -
    -

    Where would you target your efforts if you wanted to fragment this -network? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    - - - - - - -
    -
    - -
    - -
    -
    -
    -
    - - -
    -

    Topology

    -

    by James Hollway, Andrea -Biswas-Tortajada

    -
    - - -
    -
    -
    -
    - - -
    -
    - - - - - - - - - - - - - - - - From b7eef6e6178ded10cbbdefec280b850d12cc751c Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 13:10:53 +0200 Subject: [PATCH 71/97] Migrated defunct warnings to manynet --- man/defunct.Rd | 105 +++---------------------------------------------- 1 file changed, 5 insertions(+), 100 deletions(-) diff --git a/man/defunct.Rd b/man/defunct.Rd index 22c7edd6..a4c0a6fc 100644 --- a/man/defunct.Rd +++ b/man/defunct.Rd @@ -44,27 +44,8 @@ \alias{graph_smallworld} \alias{network_homophily} \alias{node_homophily} -\alias{node_optimal} -\alias{node_kernighanlin} -\alias{node_edge_betweenness} -\alias{node_fast_greedy} -\alias{node_leading_eigen} -\alias{node_walktrap} -\alias{node_infomap} -\alias{node_spinglass} -\alias{node_fluid} -\alias{node_leiden} -\alias{node_louvain} -\alias{node_core} -\alias{node_roulette} -\alias{node_components} -\alias{node_weak_components} -\alias{node_strong_components} -\alias{node_equivalence} -\alias{node_structural_equivalence} -\alias{node_regular_equivalence} -\alias{node_automorphic_equivalence} \alias{test_gof} +\alias{node_adopter} \title{Functions that have been renamed, superseded, or are no longer working} \usage{ edge_betweenness(object, normalized = TRUE) @@ -151,47 +132,9 @@ network_homophily(object, attribute) node_homophily(object, attribute) -node_optimal(.data) - -node_kernighanlin(.data) - -node_edge_betweenness(.data) - -node_fast_greedy(.data) - -node_leading_eigen(.data) - -node_walktrap(.data) - -node_infomap(.data) - -node_spinglass(.data) - -node_fluid(.data) - -node_leiden(.data) - -node_louvain(.data) - -node_core(.data) - -node_roulette(.data) - -node_components(.data) - -node_weak_components(.data) - -node_strong_components(.data) - -node_equivalence(.data) - -node_structural_equivalence(.data) - -node_regular_equivalence(.data) - -node_automorphic_equivalence(.data) - test_gof(diff_model, diff_models) + +node_adopter(diff_model) } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} @@ -288,47 +231,9 @@ wherever possible and update your scripts accordingly. \item \code{node_homophily()}: Deprecated on 2022-09-25. -\item \code{node_optimal()}: Deprecated on 2024-06-14. - -\item \code{node_kernighanlin()}: Deprecated on 2024-06-14. - -\item \code{node_edge_betweenness()}: Deprecated on 2024-06-14. - -\item \code{node_fast_greedy()}: Deprecated on 2024-06-14. - -\item \code{node_leading_eigen()}: Deprecated on 2024-06-14. - -\item \code{node_walktrap()}: Deprecated on 2024-06-14. - -\item \code{node_infomap()}: Deprecated on 2024-06-14. - -\item \code{node_spinglass()}: Deprecated on 2024-06-14. - -\item \code{node_fluid()}: Deprecated on 2024-06-14. - -\item \code{node_leiden()}: Deprecated on 2024-06-14. - -\item \code{node_louvain()}: Deprecated on 2024-06-14. - -\item \code{node_core()}: Deprecated on 2024-06-14. - -\item \code{node_roulette()}: Deprecated on 2024-06-14. - -\item \code{node_components()}: Deprecated on 2024-06-14. - -\item \code{node_weak_components()}: Deprecated on 2024-06-14. - -\item \code{node_strong_components()}: Deprecated on 2024-06-14. - -\item \code{node_equivalence()}: Deprecated on 2024-06-14. - -\item \code{node_structural_equivalence()}: Deprecated on 2024-06-14. - -\item \code{node_regular_equivalence()}: Deprecated on 2024-06-14. - -\item \code{node_automorphic_equivalence()}: Deprecated on 2024-06-14. - \item \code{test_gof()}: Deprecated on 2024-06-16. +\item \code{node_adopter()}: Deprecated on 2024-06-19. + }} \keyword{internal} From 3af95db23ffe7e0ac14bc3f5febc90cadf6da011 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 13:12:35 +0200 Subject: [PATCH 72/97] test_fit() no longer measures fit against steps where there is no covariance --- R/model_regression.R | 1 - R/model_tests.R | 1 + man/regression.Rd | 11 ----------- man/tests.Rd | 9 --------- 4 files changed, 1 insertion(+), 21 deletions(-) diff --git a/R/model_regression.R b/R/model_regression.R index 81753cc9..6ef464e9 100644 --- a/R/model_regression.R +++ b/R/model_regression.R @@ -72,7 +72,6 @@ #' @importFrom future plan #' @importFrom furrr future_map_dfr furrr_options #' @importFrom stats glm.fit as.formula df.residual pchisq -#' @seealso `vignette("p7linearmodel")` #' @references #' Krackhardt, David. 1988. #' “Predicting with Networks: Nonparametric Multiple Regression Analysis of Dyadic Data.” diff --git a/R/model_tests.R b/R/model_tests.R index e9814fe5..24d5868f 100644 --- a/R/model_tests.R +++ b/R/model_tests.R @@ -235,6 +235,7 @@ test_fit <- function(diff_model, diff_models){ # make into method? sims <- y |> dplyr::select(sim, t, I) |> tidyr::pivot_wider(names_from = t, values_from = I) |> dplyr::select(-c(sim, `0`)) + sims <- sims[,colSums(stats::cov(sims))!=0] mah <- stats::mahalanobis(x$I[-1], colMeans(sims), stats::cov(sims)) pval <- pchisq(mah, df=length(x$I[-1]), lower.tail=FALSE) dplyr::tibble(statistic = mah, p.value = pval, diff --git a/man/regression.Rd b/man/regression.Rd index 2be7e6b6..f8c0ab89 100644 --- a/man/regression.Rd +++ b/man/regression.Rd @@ -39,15 +39,6 @@ See Haunss and Hollway (2023) for more on this effect. \item dyadic covariates (other networks) can just be named }} -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - \item{method}{A method for establishing the null hypothesis. Note that "qap" uses Dekker et al's (2007) double semi-partialling technique, whereas "qapy" permutes only the $y$ variable. @@ -119,8 +110,6 @@ Dekker, David, David Krackhard, and Tom A. B. Snijders. 2007. \doi{10.1007/s11336-007-9016-1}. } \seealso{ -\code{vignette("p7linearmodel")} - Other models: \code{\link{test_distributions}}, \code{\link{tests}} diff --git a/man/tests.Rd b/man/tests.Rd index a6b14baa..7cee80e6 100644 --- a/man/tests.Rd +++ b/man/tests.Rd @@ -25,15 +25,6 @@ test_permutation( ) } \arguments{ -\item{.data}{An object of a \code{{manynet}}-consistent class: -\itemize{ -\item matrix (adjacency or incidence) from \code{{base}} R -\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} -\item igraph, from the \code{{igraph}} package -\item network, from the \code{{network}} package -\item tbl_graph, from the \code{{tidygraph}} package -}} - \item{FUN}{A graph-level statistic function to test.} \item{...}{Additional arguments to be passed on to FUN, From e72e10c5e61ddc96fbcf4ba56f7f2c467c9e7d8f Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 16:08:50 +0200 Subject: [PATCH 73/97] Migrated tests to manynet --- tests/testthat/test-measure_centrality.R | 157 -------------------- tests/testthat/test-measure_closure.R | 44 ------ tests/testthat/test-measure_cohesion.R | 25 ---- tests/testthat/test-measure_features.R | 32 ---- tests/testthat/test-measure_heterogeneity.R | 27 ---- tests/testthat/test-measure_holes.R | 46 ------ tests/testthat/test-member_community.R | 24 --- tests/testthat/test-member_equivalence.R | 25 ---- tests/testthat/test-motif_census.R | 87 ----------- 9 files changed, 467 deletions(-) delete mode 100644 tests/testthat/test-measure_centrality.R delete mode 100644 tests/testthat/test-measure_closure.R delete mode 100644 tests/testthat/test-measure_cohesion.R delete mode 100644 tests/testthat/test-measure_features.R delete mode 100644 tests/testthat/test-measure_heterogeneity.R delete mode 100644 tests/testthat/test-measure_holes.R delete mode 100644 tests/testthat/test-member_community.R delete mode 100644 tests/testthat/test-member_equivalence.R delete mode 100644 tests/testthat/test-motif_census.R diff --git a/tests/testthat/test-measure_centrality.R b/tests/testthat/test-measure_centrality.R deleted file mode 100644 index cdc90930..00000000 --- a/tests/testthat/test-measure_centrality.R +++ /dev/null @@ -1,157 +0,0 @@ -test_tbl <- manynet::as_tidygraph(manynet::ison_southern_women) -test_igr <- manynet::ison_southern_women -test_mat <- manynet::as_matrix(manynet::ison_southern_women) - -test_that("one mode degree centrality calculated correctly",{ - expect_equal(top5(node_degree(mpn_elite_mex, normalized = FALSE)), c(3,6,8,6,6)) -}) - -test_that("one mode strength centrality calculated correctly",{ - expect_equal(top5(node_degree(to_unweighted(ison_networkers), direction = "in", normalized = FALSE)), - c(29, 24, 11, 18, 8)) - expect_equal(top5(node_degree(ison_networkers, direction = "in", normalized = FALSE, alpha = 1)), - c(2495, 1212, 101, 322, 89)) -}) - -test_that("two mode degree centrality calculated correctly",{ - expect_equal(top5(node_degree(test_mat, normalized = FALSE)), c(8,7,8,7,4)) - expect_equal(top5(node_degree(test_igr, normalized = FALSE)), c(8,7,8,7,4)) - expect_equal(top5(with_graph(test_tbl, node_degree(normalized = FALSE))), c(8,7,8,7,4)) - expect_equal(bot5(node_degree(test_mat, normalized = FALSE)), c(6,4,7,4,4)) - expect_equal(bot5(node_degree(test_igr, normalized = FALSE)), c(6,4,7,4,4)) - expect_equal(bot5(with_graph(test_tbl, node_degree(normalized = FALSE))), c(6,4,7,4,4)) - expect_equal(top5(node_degree(test_mat, normalized = TRUE)), c(0.5714, .5, .5714, .5, .2857)) - expect_equal(top5(node_degree(test_igr, normalized = TRUE)), c(0.5714, .5, .5714, .5, .2857)) - expect_equal(top5(with_graph(test_tbl, node_degree(normalized = TRUE))), c(0.5714, .5, .5714, .5, .2857)) - expect_equal(bot5(node_degree(test_mat, normalized = TRUE)), c(0.3333, .2222, .3889, .2222, .2222)) - expect_equal(bot5(node_degree(test_igr, normalized = TRUE)), c(0.3333, .2222, .3889, .2222, .2222)) - expect_equal(bot5(with_graph(test_tbl, node_degree(normalized = TRUE))), c(0.3333, .2222, .3889, .2222, .2222)) -}) - -test_that("one mode closeness centrality calculated correctly",{ - expect_equal(top3(node_closeness(mpn_elite_mex, normalized = FALSE)), c(0.0118, 0.0119, 0.0137)) -}) - -test_that("two mode closeness centrality calculated correctly",{ - expect_equal(top5(node_closeness(test_mat, normalized = FALSE)), c(0.0167, 0.0152, 0.0167, 0.0152, 0.0125)) - expect_equal(top5(node_closeness(test_igr, normalized = FALSE)), c(0.0167, 0.0152, 0.0167, 0.0152, 0.0125)) - expect_equal(top5(with_graph(test_tbl, node_closeness(normalized = FALSE))), c(0.0167, 0.0152, 0.0167, 0.0152, 0.0125)) - expect_equal(bot5(node_closeness(test_mat, normalized = FALSE)), c(0.0128, 0.0122, 0.0132, 0.0122, 0.0122)) - expect_equal(bot5(node_closeness(test_igr, normalized = FALSE)), c(0.0128, 0.0122, 0.0132, 0.0122, 0.0122)) - expect_equal(bot5(with_graph(test_tbl, node_closeness(normalized = FALSE))), c(0.0128, 0.0122, 0.0132, 0.0122, 0.0122)) - expect_equal(top5(node_closeness(test_mat, normalized = TRUE)), c(0.8000, 0.7273, 0.8000, 0.7273, 0.6000)) - expect_equal(top5(node_closeness(test_igr, normalized = TRUE)), c(0.8000, 0.7273, 0.8000, 0.7273, 0.6000)) - expect_equal(top5(with_graph(test_tbl, node_closeness(normalized = TRUE))), c(0.8000, 0.7273, 0.8000, 0.7273, 0.6000)) - expect_equal(bot5(node_closeness(test_mat, normalized = TRUE)), c(0.5641, 0.5366, 0.5789, 0.5366, 0.5366)) - expect_equal(bot5(node_closeness(test_igr, normalized = TRUE)), c(0.5641, 0.5366, 0.5789, 0.5366, 0.5366)) - expect_equal(bot5(with_graph(test_tbl, node_closeness(normalized = TRUE))), c(0.5641, 0.5366, 0.5789, 0.5366, 0.5366)) -}) - -test_that("one mode betweenness centrality calculated correctly",{ - expect_equal(top3(node_betweenness(mpn_elite_mex, normalized = FALSE)), c(2.8345, 4.5922, 17.3583)) -}) - -test_that("two mode betweenness centrality calculated correctly",{ - expect_equal(top5(node_betweenness(test_mat, normalized = FALSE)), c(42.7600, 22.8565, 38.7393, 22.0119, 4.7279)) - expect_equal(top5(node_betweenness(test_igr, normalized = FALSE)), c(42.7600, 22.8565, 38.7393, 22.0119, 4.7279)) - expect_equal(top5(with_graph(test_tbl, node_betweenness(normalized = FALSE))), c(42.7600, 22.8565, 38.7393, 22.0119, 4.7279)) - expect_equal(bot5(node_betweenness(test_mat, normalized = FALSE)), c(6.8186, 9.0194, 10.2354, 1.8892, 1.8892)) - expect_equal(bot5(node_betweenness(test_igr, normalized = FALSE)), c(6.8186, 9.0194, 10.2354, 1.8892, 1.8892)) - expect_equal(bot5(with_graph(test_tbl, node_betweenness(normalized = FALSE))), c(6.8186, 9.0194, 10.2354, 1.8892, 1.8892)) - expect_equal(top5(node_betweenness(test_mat, normalized = TRUE),4), c(0.0967, 0.0517, 0.0876, 0.0498, 0.0107)) - expect_equal(top5(node_betweenness(test_igr, normalized = TRUE),4), c(0.0967, 0.0517, 0.0876, 0.0498, 0.0107)) - expect_equal(top5(with_graph(test_tbl, node_betweenness(normalized = TRUE)),4), c(0.0967, 0.0517, 0.0876, 0.0498, 0.0107)) - expect_equal(bot5(node_betweenness(test_mat, normalized = TRUE),4), c(0.0151, 0.02, 0.0226, 0.0042, 0.0042)) - expect_equal(bot5(node_betweenness(test_igr, normalized = TRUE),4), c(0.0151, 0.02, 0.0226, 0.0042, 0.0042)) - expect_equal(bot5(with_graph(test_tbl, node_betweenness(normalized = TRUE)),4), c(0.0151, 0.02, 0.0226, 0.0042, 0.0042)) -}) - -test_that("one mode eigenvector centrality calculated correctly",{ - expect_equal(top3(node_eigenvector(mpn_elite_mex, normalized = FALSE)), c(0.0571, 0.0771, 0.1176)) - expect_equal(top3(node_eigenvector(mpn_elite_mex, normalized = TRUE)), c(0.0808, 0.1090, 0.1663)) -}) - -test_that("two mode eigenvector centrality calculated correctly",{ - expect_equal(top3(node_eigenvector(test_mat, normalized = FALSE)), c(0.2991, 0.2809, 0.3338)) - expect_equal(top3(node_eigenvector(test_igr, normalized = FALSE)), c(0.2991, 0.2809, 0.3338)) - expect_equal(bot3(node_eigenvector(test_mat, normalized = FALSE)), c(0.2551, 0.1774, 0.1774)) - expect_equal(bot3(node_eigenvector(test_igr, normalized = FALSE)), c(0.2551, 0.1774, 0.1774)) - expect_equal(top3(node_eigenvector(test_igr, normalized = TRUE)), c(0.423, 0.3973, 0.4721)) -}) - -test_that("node measure class works", { - expect_s3_class(node_degree(ison_adolescents), "node_measure") - expect_s3_class(node_betweenness(ison_adolescents), "node_measure") - expect_s3_class(node_closeness(ison_adolescents), "node_measure") - expect_s3_class(node_eigenvector(ison_adolescents), "node_measure") - expect_s3_class(node_reach(ison_adolescents), "node_measure") - testplot <- plot(node_degree(ison_adolescents)) - expect_equal(testplot$data$Score, unname(node_degree(ison_adolescents))) - # expect_equal(testplot$labels$y, "Frequency") -}) - -# ####### Centralization - -test_that("one-mode centralisation is calculated correctly", { - expect_equal(as.numeric(network_degree(mpn_elite_mex)), 0.3033, tolerance = 0.001) - expect_equal(as.numeric(network_closeness(mpn_elite_mex)), 0.3855, tolerance = 0.001) - expect_equal(as.numeric(network_betweenness(mpn_elite_mex)), 0.2024, tolerance = 0.001) - expect_equal(as.numeric(network_eigenvector(mpn_elite_mex)), 0.6300, tolerance = 0.001) -}) - -test_that("two mode degree centralisation calculated correctly", { - expect_equal(as.numeric(network_degree(ison_southern_women, normalized = FALSE)), c(0.1813, 0.5097), tolerance = 0.001) - expect_equal(as.numeric(network_degree(ison_southern_women, direction = "in")), c(0.2308, 0.4661), tolerance = 0.001) - expect_equal(as.numeric(network_degree(ison_southern_women, normalized = TRUE)), c(0.2268, 0.4744), tolerance = 0.001) -}) - -test_that("two mode closeness centralisation calculated correctly", { - expect_equal(as.numeric(network_closeness(ison_southern_women, normalized = TRUE)), c(0.2843, 0.4418), tolerance = 0.001) - expect_equal(as.numeric(network_closeness(ison_southern_women, direction = "in")), c(0.2135, 0.5285), tolerance = 0.001) -}) - -test_that("two mode betweenness centralisation calculated correctly", { - expect_equal(as.numeric(network_betweenness(ison_southern_women, normalized = FALSE)), c(0.0580, 0.2073), tolerance = 0.001) - expect_equal(as.numeric(network_betweenness(ison_southern_women, direction = "in")), c(0.0668, 0.1982), tolerance = 0.001) - expect_equal(as.numeric(network_betweenness(ison_southern_women, normalized = TRUE)), c(0.05858, 0.2073), tolerance = 0.001) -}) - -test_that("network_measure class works", { - expect_s3_class(network_degree(ison_algebra), "network_measure") - expect_s3_class(network_betweenness(mpn_elite_usa_advice), "network_measure") - expect_s3_class(network_closeness(mpn_elite_usa_advice), "network_measure") - expect_output(print(network_degree(ison_algebra))) -}) - -# ####### Edge centrality -test_that("tie_degree works", { - expect_s3_class(tie_degree(ison_adolescents), - "tie_measure") - expect_length(tie_degree(ison_adolescents), - manynet::network_ties(ison_adolescents)) -}) - -test_that("tie_betweenness works", { - expect_s3_class(tie_betweenness(ison_adolescents), - "tie_measure") - expect_length(tie_betweenness(ison_adolescents), - manynet::network_ties(ison_adolescents)) - expect_equal(top3(tie_betweenness(ison_adolescents)), - c(7,3,5), tolerance = 0.001) -}) - -test_that("tie_closeness works", { - expect_s3_class(tie_closeness(ison_adolescents), - "tie_measure") - expect_length(tie_closeness(ison_adolescents), - manynet::network_ties(ison_adolescents)) - expect_equal(top3(tie_closeness(ison_adolescents)), - c(0.562,0.692,0.600), tolerance = 0.001) -}) - -test_that("tie_eigenvector works", { - expect_s3_class(tie_eigenvector(ison_southern_women), - "tie_measure") - expect_length(tie_eigenvector(ison_southern_women), - manynet::network_ties(ison_southern_women)) -}) diff --git a/tests/testthat/test-measure_closure.R b/tests/testthat/test-measure_closure.R deleted file mode 100644 index e725b6f0..00000000 --- a/tests/testthat/test-measure_closure.R +++ /dev/null @@ -1,44 +0,0 @@ -test_that("network density works", { - expect_s3_class(network_density(ison_southern_women), "network_measure") - expect_equal(as.numeric(network_density(manynet::create_empty(10))), 0) - expect_equal(as.numeric(network_density(manynet::create_empty(c(10,6)))), 0) - expect_equal(as.numeric(network_density(manynet::create_filled(10))), 1) - expect_equal(as.numeric(network_density(manynet::create_filled(c(10,6)))), 1) - expect_output(print(network_density(manynet::create_filled(10)))) -}) - -test_that("network reciprocity works", { - expect_s3_class(network_reciprocity(ison_networkers), "network_measure") - expect_output(print(network_reciprocity(ison_networkers))) - expect_length(network_reciprocity(ison_networkers), 1) - expect_equal(as.numeric(network_reciprocity(ison_networkers)), - igraph::reciprocity(as_igraph(ison_networkers))) -}) - -test_that("one-mode object clustering is reported correctly",{ - expect_equal(as.numeric(network_transitivity(ison_algebra)), - 0.69787, tolerance = 0.001) - expect_s3_class(network_transitivity(ison_algebra), "network_measure") - expect_output(print(network_transitivity(ison_algebra))) -}) - -test_that("two-mode object clustering is reported correctly",{ - expect_equal(as.numeric(network_equivalency(ison_southern_women)), - 0.4872, tolerance = 0.001) - expect_s3_class(network_equivalency(ison_southern_women), "network_measure") - expect_output(print(network_equivalency(ison_southern_women))) -}) - -test_that("three-mode clustering calculated correctly",{ - mat1 <- manynet::create_ring(c(10,5)) - mat2 <- manynet::create_ring(c(5,8)) - expect_equal(as.numeric(network_congruency(mat1, mat2)), - 0.3684, tolerance = 0.001) - expect_s3_class(network_congruency(mat1, mat2), "network_measure") - expect_output(print(network_congruency(mat1, mat2))) -}) - -test_that("node_transitivity is reported correctly",{ - expect_length(node_transitivity(ison_algebra), network_nodes(ison_algebra)) - expect_s3_class(node_transitivity(ison_algebra), "node_measure") -}) diff --git a/tests/testthat/test-measure_cohesion.R b/tests/testthat/test-measure_cohesion.R deleted file mode 100644 index f6ef95f2..00000000 --- a/tests/testthat/test-measure_cohesion.R +++ /dev/null @@ -1,25 +0,0 @@ -test_that("graph components works", { - expect_s3_class(network_components(mpn_bristol), "network_measure") - expect_equal(as.numeric(network_components(mpn_bristol)), 3) -}) - -test_that("graph cohesion works", { - expect_s3_class(network_cohesion(mpn_bristol), "network_measure") - expect_equal(as.numeric(network_cohesion(mpn_bristol)), 0) -}) - -test_that("graph adhesion works", { - expect_s3_class(network_adhesion(mpn_bristol), "network_measure") - expect_equal(as.numeric(network_adhesion(mpn_bristol)), 0) -}) - -test_that("graph diameter works", { - expect_s3_class(network_diameter(mpn_bristol), "network_measure") - expect_equal(as.numeric(network_diameter(mpn_bristol)), 6) -}) - -test_that("graph length works", { - expect_s3_class(network_length(mpn_bristol), "network_measure") - expect_equal(as.numeric(network_length(mpn_bristol)), 2.451265, - tolerance = 0.000001) -}) diff --git a/tests/testthat/test-measure_features.R b/tests/testthat/test-measure_features.R deleted file mode 100644 index 8b4f4462..00000000 --- a/tests/testthat/test-measure_features.R +++ /dev/null @@ -1,32 +0,0 @@ -set.seed(123) - -test_that("small-world metrics for two mode networks are calculated and displayed correctly", { - expect_s3_class(network_smallworld(ison_southern_women), "network_measure") - expect_equal(as.numeric(network_smallworld(ison_southern_women)), -1.04, tolerance = 0.02) -}) - -test_that("network_balance works", { - expect_s3_class(network_balance(ison_marvel_relationships), "network_measure") - expect_equal(as.numeric(network_balance(ison_marvel_relationships)), 0.668, tolerance = 0.01) - expect_length(network_balance(ison_marvel_relationships), 1) - expect_error(network_balance(ison_adolescents)) -}) - -test_that("network_modularity works for two mode networks", { - expect_s3_class(network_modularity(ison_southern_women, - node_in_partition(ison_southern_women)), "network_measure") - expect_length(network_modularity(ison_southern_women, - node_in_partition(ison_southern_women)), 1) -}) - -test_that("network_core works", { - expect_s3_class(network_core(ison_adolescents), "network_measure") - expect_equal(length(network_core(ison_adolescents)), - length(network_core(ison_southern_women))) -}) - -test_that("network_factions works", { - expect_s3_class(network_factions(ison_adolescents), "network_measure") - expect_equal(length(network_factions(ison_adolescents)), - length(network_factions(ison_southern_women))) -}) diff --git a/tests/testthat/test-measure_heterogeneity.R b/tests/testthat/test-measure_heterogeneity.R deleted file mode 100644 index 62ec1705..00000000 --- a/tests/testthat/test-measure_heterogeneity.R +++ /dev/null @@ -1,27 +0,0 @@ -#*************** Test the heterogeneity family of functions ******************# - -test_that("diversity function works", { - expect_equal(as.numeric(network_diversity(ison_marvel_relationships, "Gender")), 0.306, tolerance = 0.001) - expect_equal(as.numeric(network_diversity(ison_marvel_relationships, "Gender", "Rich")), - c(0.3367,0.1653), tolerance = 0.001) -}) - -test_that("heterophily function works", { - expect_equal(as.numeric(network_heterophily(mpn_elite_mex, "military")), -0.3675, tolerance = 0.001) - expect_length(node_heterophily(mpn_elite_mex, "military"), - network_nodes(mpn_elite_mex)) - expect_s3_class(node_heterophily(mpn_elite_mex, "military"), "node_measure") -}) - -test_that("assortativity function works", { - expect_length(network_assortativity(mpn_elite_mex), 1) - expect_s3_class(network_assortativity(mpn_elite_mex), "network_measure") -}) - -test_that("richeness function works", { - expect_length(network_richness(mpn_bristol), 1) - expect_equal(as.numeric(network_richness(mpn_bristol)), 3) - expect_s3_class(network_richness(mpn_bristol), "network_measure") - expect_length(node_richness(mpn_bristol, "type"), 264) - expect_s3_class(node_richness(mpn_bristol, "type"), "node_measure") -}) diff --git a/tests/testthat/test-measure_holes.R b/tests/testthat/test-measure_holes.R deleted file mode 100644 index 2b940eda..00000000 --- a/tests/testthat/test-measure_holes.R +++ /dev/null @@ -1,46 +0,0 @@ -test_that("redundancy is reported correctly", { - expect_s3_class(node_redundancy(ison_brandes), "node_measure") - expect_s3_class(node_redundancy(mpn_elite_usa_advice), "node_measure") - expect_equal(length(node_redundancy(ison_brandes)), network_nodes(ison_brandes)) - expect_equal(length(node_redundancy(mpn_elite_usa_advice)), - network_nodes(mpn_elite_usa_advice)) - expect_named(node_redundancy(mpn_elite_usa_advice)) -}) - -test_that("effective size is calculated and reported correctly", { - expect_s3_class(node_effsize(ison_brandes), "node_measure") - expect_s3_class(node_effsize(mpn_elite_usa_advice), "node_measure") - expect_equal(length(node_effsize(ison_brandes)), network_nodes(ison_brandes)) - expect_equal(length(node_effsize(mpn_elite_usa_advice)), - network_nodes(mpn_elite_usa_advice)) - expect_named(node_effsize(mpn_elite_usa_advice)) - expect_equal(top5(node_effsize(ison_southern_women)), c(2.5,1.3778,2.4561,1.4565,1)) -}) - -test_that("efficiency is reported correctly", { - expect_s3_class(node_efficiency(ison_brandes), "node_measure") - expect_s3_class(node_efficiency(mpn_elite_usa_advice), "node_measure") - expect_equal(length(node_efficiency(ison_brandes)), network_nodes(ison_brandes)) - expect_equal(length(node_efficiency(mpn_elite_usa_advice)), - network_nodes(mpn_elite_usa_advice)) -}) - -test_that("constraint scores are reported correctly for two-mode notworks",{ - expect_equal(round(unname(node_constraint(ison_southern_women)[1:3]),2), c(0.28, 0.31, 0.29)) - # 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) - -test_that("constraint scores are reported correctly for one-mode notworks",{ - expect_equal(round(unname(node_constraint(mpn_elite_mex)[1:3]),2), c(0.45, 0.35, 0.28)) -}) - -test_that("hierarchy is reported correctly", { - expect_s3_class(node_hierarchy(ison_brandes), "node_measure") - expect_s3_class(node_hierarchy(mpn_elite_usa_advice), "node_measure") - expect_equal(length(node_hierarchy(ison_brandes)), network_nodes(ison_brandes)) - expect_equal(length(node_hierarchy(mpn_elite_usa_advice)), - network_nodes(mpn_elite_usa_advice)) - expect_named(node_hierarchy(mpn_elite_usa_advice)) -}) diff --git a/tests/testthat/test-member_community.R b/tests/testthat/test-member_community.R deleted file mode 100644 index d59e33aa..00000000 --- a/tests/testthat/test-member_community.R +++ /dev/null @@ -1,24 +0,0 @@ -test_that("node_kernighanlin algorithm works", { - expect_s3_class(node_in_partition(mpn_elite_mex), "node_member") - expect_length(node_in_partition(mpn_elite_mex), - network_nodes(mpn_elite_mex)) - expect_false(any(node_in_partition(mpn_elite_mex) > "B")) -}) - -test_that("node_edge_betweenness algorithm works", { - expect_s3_class(node_in_betweenness(mpn_elite_mex), "node_member") - expect_length(node_in_betweenness(mpn_elite_mex), - network_nodes(mpn_elite_mex)) -}) - -test_that("node_fast_greedy algorithm works", { - expect_s3_class(node_in_greedy(ison_southern_women), "node_member") - expect_length(node_in_greedy(ison_southern_women), - network_nodes(ison_southern_women)) -}) - -test_that("node_walktrap algorithm works", { - expect_s3_class(node_in_walktrap(ison_southern_women), "node_member") - expect_length(node_in_walktrap(ison_southern_women), - network_nodes(ison_southern_women)) -}) diff --git a/tests/testthat/test-member_equivalence.R b/tests/testthat/test-member_equivalence.R deleted file mode 100644 index 0f32016e..00000000 --- a/tests/testthat/test-member_equivalence.R +++ /dev/null @@ -1,25 +0,0 @@ -# # Equivalence clustering tests - -test_that("equivalence clustering returns the right class", { - expect_s3_class(node_in_structural(ison_adolescents, "strict", "hier"), "node_member") - expect_s3_class(node_in_structural(ison_adolescents, "elbow", "hier"), "node_member") - expect_s3_class(node_in_structural(ison_adolescents, "elbow", "concor"), "node_member") - expect_s3_class(node_in_regular(mpn_elite_mex), "node_member") - expect_s3_class(node_in_automorphic(mpn_elite_mex), "node_member") -}) - -test_that("equivalence clustering works", { - expect_equal(node_in_structural(ison_adolescents, "silhouette", "hier"), node_in_structural(ison_adolescents)) - expect_equal(node_in_regular(mpn_elite_mex), node_in_regular(mpn_elite_mex, "silhouette", "hier")) - expect_equal(network_nodes(ison_adolescents), length(node_in_structural(ison_adolescents, "silhouette", "concor"))) - expect_equal(network_nodes(ison_adolescents), length(node_in_structural(ison_adolescents, k = 3, "hier"))) - expect_equal(network_nodes(ison_adolescents), length(node_in_structural(ison_adolescents, "strict", "concor"))) - expect_equal(network_nodes(mpn_elite_mex), length(node_in_regular(mpn_elite_mex, cluster = "concor"))) - expect_equal(network_nodes(mpn_elite_mex), length(node_in_regular(mpn_elite_mex, "elbow"))) - expect_equal(network_nodes(mpn_elite_mex), length(node_in_regular(mpn_elite_mex, "strict"))) - expect_equal(network_nodes(mpn_elite_usa_advice), length(node_in_automorphic(mpn_elite_usa_advice, "strict", distance = "binary"))) - expect_equal(network_nodes(mpn_elite_usa_advice), length(node_in_automorphic(mpn_elite_usa_advice, distance = "maximum"))) - expect_true("C" %in% node_in_structural(ison_adolescents, k = 3, "concor")) - expect_true("B" %in% node_in_regular(mpn_elite_mex, 2)) - expect_true("D" %in% node_in_automorphic(mpn_elite_usa_advice, 4)) -}) diff --git a/tests/testthat/test-motif_census.R b/tests/testthat/test-motif_census.R deleted file mode 100644 index d2e9713e..00000000 --- a/tests/testthat/test-motif_census.R +++ /dev/null @@ -1,87 +0,0 @@ -# # Census function family tests -set.seed(123) -task_eg <- manynet::to_named(manynet::to_uniplex(manynet::ison_algebra, "tasks")) - -test <- node_tie_census(task_eg) -test_that("node tie census works", { - expect_equal(test[1:4], rep(0, 4)) - expect_s3_class(test, "node_motif") -}) - -test <- node_triad_census(task_eg) -test_that("node triad census works", { - expect_equal(top3(test[,16]), c(7,8,6)) - expect_s3_class(test, "node_motif") - expect_equal(colnames(test)[1:3], c("003", "012", "102")) -}) - -test <- network_dyad_census(manynet::ison_adolescents) -test_that("network_dyad census works", { - expect_equal(test[[1]], 10) - expect_equal(test[[2]], 18) - expect_equal(names(test), c("Mutual", "Null")) - expect_s3_class(test, "network_motif") - # Error - expect_error(network_dyad_census(manynet::ison_southern_women)) -}) - -test <- network_triad_census(manynet::ison_adolescents) -test_that("network_triad census works", { - expect_equal(test[[1]], 13) - expect_equal(test[[3]], 29) - expect_equal(names(test), c("003", "012", "102", "201", "210", "300")) - expect_s3_class(test, "network_motif") - # Error - expect_error(network_triad_census(manynet::ison_southern_women)) -}) - -test <- node_quad_census(manynet::ison_southern_women) -test_that("node quad census works", { - expect_s3_class(test, "node_motif") - expect_equal(test[1,1], 1402) -}) - -test_that("network_mixed census works", { - marvel_friends <- to_unsigned(manynet::ison_marvel_relationships, "positive") - test <- network_mixed_census(marvel_friends, manynet::ison_marvel_teams) - expect_s3_class(test, "network_motif") - expect_equal(unname(test[1]), 1137) - expect_equal(names(test[1]), "22") - # Errors - expect_error(network_mixed_census(manynet::ison_southern_women, - manynet::ison_marvel_teams)) - expect_error(network_mixed_census(manynet::ison_marvel_teams, - manynet::ison_southern_women)) - expect_error(network_mixed_census(manynet::ison_karateka, - manynet::ison_marvel_teams)) -}) - -test <- node_path_census(manynet::ison_southern_women) -test_that("node path census works", { - expect_equal(network_nodes(manynet::ison_adolescents), - nrow(node_path_census(manynet::ison_adolescents))) - expect_s3_class(test, "node_motif") - expect_true(nrow(node_path_census(manynet::ison_southern_women)) == - ncol(node_path_census(manynet::ison_southern_women))) -}) - -test <- node_brokering_activity(manynet::ison_networkers, "Discipline") -test_that("node activity works", { - expect_s3_class(test, "node_measure") - expect_equal(manynet::network_nodes(manynet::ison_networkers), length(test)) - expect_equal(top3(test), c(333,207,3)) -}) - -test <- node_brokering_exclusivity(manynet::ison_networkers, "Discipline") -test_that("node exclusivity works", { - expect_s3_class(test, "node_measure") - expect_equal(manynet::network_nodes(manynet::ison_networkers), length(test)) - expect_equal(top3(test), c(1,0,0)) -}) - -test <- node_brokering(manynet::ison_networkers, "Discipline") -test_that("node brokering works", { - expect_s3_class(test, "node_member") - expect_equal(manynet::network_nodes(manynet::ison_networkers), length(test)) - expect_equal(top3(test), c("Powerhouse","Connectors","Sideliners")) -}) From 5ece8c621727a3e0412b41a007947c3fb30af4b6 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 16:09:09 +0200 Subject: [PATCH 74/97] Dropped old defuncts --- NAMESPACE | 42 ------ R/migraph-defunct.R | 353 -------------------------------------------- man/defunct.Rd | 210 -------------------------- 3 files changed, 605 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index dc641af1..9e7d2567 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,13 +2,9 @@ S3method(glance,netlm) S3method(glance,netlogit) -S3method(plot,graph_test) S3method(plot,netlm) S3method(plot,netlogit) S3method(plot,network_test) -S3method(print,graph_measure) -S3method(print,graph_motif) -S3method(print,graph_test) S3method(print,network_test) S3method(tidy,netlm) S3method(tidy,netlogit) @@ -19,56 +15,18 @@ export(.N) export(aes) export(as.network) export(bind_edges) -export(edge_betweenness) -export(edge_bridges) -export(edge_closeness) -export(edge_degree) -export(edge_eigenvector) -export(edge_loop) -export(edge_multiple) -export(edge_reciprocal) export(ggplot) export(ggsave) export(ggtitle) export(glance) -export(graph_adhesion) -export(graph_assortativity) -export(graph_balance) -export(graph_betweenness) -export(graph_blau_index) -export(graph_closeness) -export(graph_cohesion) -export(graph_components) -export(graph_congruency) -export(graph_core) -export(graph_degree) -export(graph_density) -export(graph_diameter) -export(graph_diversity) -export(graph_dyad_census) -export(graph_ei_index) -export(graph_eigenvector) -export(graph_equivalency) -export(graph_factions) -export(graph_homophily) -export(graph_length) -export(graph_mixed_census) -export(graph_modularity) -export(graph_reciprocity) -export(graph_smallworld) -export(graph_transitivity) -export(graph_triad_census) export(guides) export(is.network) export(is.tbl_graph) export(is_igraph) export(labs) export(mutate) -export(network_homophily) export(network_reg) export(node_adopter) -export(node_cuts) -export(node_homophily) export(rename) export(test_distribution) export(test_fit) diff --git a/R/migraph-defunct.R b/R/migraph-defunct.R index c6656176..71f90e20 100644 --- a/R/migraph-defunct.R +++ b/R/migraph-defunct.R @@ -11,359 +11,6 @@ #' @keywords internal NULL -#' @describeIn defunct Deprecated on 2022-06-28. -#' @export -edge_betweenness <- function(object, normalized = TRUE){ - .Deprecated("tie_betweenness", package = "migraph", - old = "edge_betweenness") - tie_betweenness(object, normalized) -} - -#' @describeIn defunct Deprecated on 2022-06-28. -#' @export -edge_closeness <- function(object, normalized = TRUE){ - .Deprecated("tie_closeness", package = "migraph", - old = "edge_closeness") - tie_closeness(object, normalized) -} - -#' @describeIn defunct Deprecated on 2022-06-28. -#' @export -edge_degree <- function(object, normalized = TRUE){ - .Deprecated("tie_degree", package = "migraph", - old = "edge_degree") - tie_degree(object, normalized) -} - -#' @describeIn defunct Deprecated on 2022-06-28. -#' @export -edge_eigenvector <- function(object, normalized = TRUE){ - .Deprecated("tie_eigenvector", package = "migraph", - old = "edge_eigenvector") - tie_eigenvector(object, normalized) -} - -#' @describeIn defunct Deprecated on 2022-06-28. -#' @export -edge_loop <- function(object){ - .Deprecated("tie_is_loop", package = "migraph", - old = "edge_loop") - manynet::tie_is_loop(object) -} - -#' @describeIn defunct Deprecated on 2022-06-28. -#' @export -edge_multiple <- function(object){ - .Deprecated("tie_is_multiple", package = "migraph", - old = "edge_multiple") - manynet::tie_is_multiple(object) -} - -#' @describeIn defunct Deprecated on 2022-06-28. -#' @export -edge_bridges <- function(object){ - .Deprecated("tie_is_bridge", package = "migraph", - old = "edge_bridges") - manynet::tie_is_bridge(object) -} - -#' @describeIn defunct Deprecated on 2022-06-28. -#' @export -edge_reciprocal <- function(object){ - .Deprecated("tie_is_reciprocated", package = "migraph", - old = "edge_reciprocal") - manynet::tie_is_reciprocated(object) -} - -#' @describeIn defunct Deprecated on 2022-06-30. -#' @export -node_cuts <- function(object){ - .Deprecated("node_is_cutpoint", package = "migraph", - old = "node_cuts") - manynet::node_is_cutpoint(object) -} - -#' @describeIn defunct Deprecated on 2022-09-10. -#' @export -graph_blau_index <- function(object, attribute, clusters = NULL) { - .Deprecated("network_diversity", package = "migraph", - old = "graph_blau_index") - network_diversity(object, attribute = attribute, clusters = clusters) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_diversity <- function(object, attribute, clusters = NULL) { - .Deprecated("network_diversity", package = "migraph", - old = "graph_diversity") - network_diversity(object, attribute = attribute, clusters = clusters) -} - -#' @describeIn defunct Deprecated on 2022-09-10. -#' @export -graph_ei_index <- function(object, attribute) { - .Deprecated("network_homophily", package = "migraph", - old = "graph_ei_index") - network_homophily(object, attribute = attribute) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_homophily <- function(object, attribute) { - .Deprecated("network_homophily", package = "migraph", - old = "graph_homophily") - network_homophily(object, attribute = attribute) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -plot.graph_test <- function(x, ..., - threshold = .95, - tails = c("two", "one")) { - .Deprecated("plot.network_test", package = "migraph", - old = "plot.graph_test") - plot.network_test(x, ..., - threshold = threshold, - tails = tails) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -print.graph_test <- function(x, ..., - max.length = 6, - digits = 3) { - .Deprecated("print.network_test", package = "migraph", - old = "print.graph_test") - print.network_test(x, ..., - max.length = max.length, - digits = digits) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -print.graph_measure <- function(x, ..., - digits = 3) { - .Deprecated("print.network_measure", package = "migraph", - old = "print.graph_measure") - print.network_measure(x, ..., - digits = digits) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -print.graph_motif <- function(x, ...) { - .Deprecated("print.network_motif", package = "migraph", - old = "print.graph_motif") - print.network_motif(x, ...) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_adhesion <- function(object) { - .Deprecated("network_adhesion", package = "migraph", - old = "graph_adhesion") - network_adhesion(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_cohesion <- function(object) { - .Deprecated("network_cohesion", package = "migraph", - old = "graph_cohesion") - network_cohesion(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_assortativity <- function(object) { - .Deprecated("network_assortativity", package = "migraph", - old = "graph_assortativity") - network_assortativity(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_balance <- function(object) { - .Deprecated("network_balance", package = "migraph", - old = "graph_balance") - network_balance(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_betweenness <- function(object, normalized = TRUE, - direction = c("all", "out", "in")) { - .Deprecated("network_betweenness", package = "migraph", - old = "graph_betweenness") - network_betweenness(object, normalized = normalized, - direction = direction) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_closeness <- function(object, normalized = TRUE, - direction = c("all", "out", "in")) { - .Deprecated("network_closeness", package = "migraph", - old = "graph_closeness") - network_closeness(object, normalized = normalized, - direction = direction) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_degree <- function(object, normalized = TRUE, - direction = c("all", "out", "in")) { - .Deprecated("network_degree", package = "migraph", - old = "graph_degree") - network_degree(object, normalized = normalized, - direction = direction) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_eigenvector <- function(object, normalized = TRUE) { - .Deprecated("network_eigenvector", package = "migraph", - old = "graph_eigenvector") - network_eigenvector(object, normalized = normalized) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_components <- function(object) { - .Deprecated("network_components", package = "migraph", - old = "graph_components") - network_components(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_factions <- function(object, membership = NULL) { - .Deprecated("network_factions", package = "migraph", - old = "graph_factions") - network_factions(object, membership = membership) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_congruency <- function(object, object2) { - .Deprecated("network_congruency", package = "migraph", - old = "graph_congruency") - network_congruency(object, object2) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_equivalency <- function(object) { - .Deprecated("network_equivalency", package = "migraph", - old = "graph_equivalency") - network_equivalency(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_core <- function(object, membership = NULL) { - .Deprecated("network_core", package = "migraph", - old = "graph_core") - network_core(object, membership = membership) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_density <- function(object) { - .Deprecated("network_density", package = "migraph", - old = "graph_density") - network_density(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_reciprocity <- function(object, method = "default") { - .Deprecated("network_reciprocity", package = "migraph", - old = "graph_reciprocity") - network_reciprocity(object, method = method) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_transitivity <- function(object) { - .Deprecated("network_transitivity", package = "migraph", - old = "graph_transitivity") - network_transitivity(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_diameter <- function(object) { - .Deprecated("network_diameter", package = "migraph", - old = "graph_diameter") - network_diameter(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_length <- function(object) { - .Deprecated("network_length", package = "migraph", - old = "graph_length") - network_length(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_dyad_census <- function(object) { - .Deprecated("network_dyad_census", package = "migraph", - old = "graph_dyad_census") - network_dyad_census(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_triad_census <- function(object) { - .Deprecated("network_triad_census", package = "migraph", - old = "graph_triad_census") - network_triad_census(object) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_mixed_census <- function(object, object2) { - .Deprecated("network_mixed_census", package = "migraph", - old = "graph_mixed_census") - network_mixed_census(object, object2) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_modularity <- function(object, membership = NULL, resolution = 1) { - .Deprecated("network_modularity", package = "migraph", - old = "graph_modularity") - network_modularity(object, membership = membership, - resolution = resolution) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -graph_smallworld <- function(object, times = 100) { - .Deprecated("network_smallworld", package = "migraph", - old = "graph_smallworld") - network_smallworld(object, times = times) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -network_homophily <- function(object, attribute) { - .Deprecated("network_heterophily", package = "migraph", - old = "network_homophily") - network_heterophily(object, attribute) -} - -#' @describeIn defunct Deprecated on 2022-09-25. -#' @export -node_homophily <- function(object, attribute) { - .Deprecated("node_heterophily", package = "migraph", - old = "node_homophily") - node_heterophily(object, attribute) -} - #' @describeIn defunct Deprecated on 2024-06-16. #' @export test_gof <- function(diff_model, diff_models) { diff --git a/man/defunct.Rd b/man/defunct.Rd index a4c0a6fc..b8c6e39d 100644 --- a/man/defunct.Rd +++ b/man/defunct.Rd @@ -2,136 +2,10 @@ % Please edit documentation in R/migraph-defunct.R \name{defunct} \alias{defunct} -\alias{edge_betweenness} -\alias{edge_closeness} -\alias{edge_degree} -\alias{edge_eigenvector} -\alias{edge_loop} -\alias{edge_multiple} -\alias{edge_bridges} -\alias{edge_reciprocal} -\alias{node_cuts} -\alias{graph_blau_index} -\alias{graph_diversity} -\alias{graph_ei_index} -\alias{graph_homophily} -\alias{plot.graph_test} -\alias{print.graph_test} -\alias{print.graph_measure} -\alias{print.graph_motif} -\alias{graph_adhesion} -\alias{graph_cohesion} -\alias{graph_assortativity} -\alias{graph_balance} -\alias{graph_betweenness} -\alias{graph_closeness} -\alias{graph_degree} -\alias{graph_eigenvector} -\alias{graph_components} -\alias{graph_factions} -\alias{graph_congruency} -\alias{graph_equivalency} -\alias{graph_core} -\alias{graph_density} -\alias{graph_reciprocity} -\alias{graph_transitivity} -\alias{graph_diameter} -\alias{graph_length} -\alias{graph_dyad_census} -\alias{graph_triad_census} -\alias{graph_mixed_census} -\alias{graph_modularity} -\alias{graph_smallworld} -\alias{network_homophily} -\alias{node_homophily} \alias{test_gof} \alias{node_adopter} \title{Functions that have been renamed, superseded, or are no longer working} \usage{ -edge_betweenness(object, normalized = TRUE) - -edge_closeness(object, normalized = TRUE) - -edge_degree(object, normalized = TRUE) - -edge_eigenvector(object, normalized = TRUE) - -edge_loop(object) - -edge_multiple(object) - -edge_bridges(object) - -edge_reciprocal(object) - -node_cuts(object) - -graph_blau_index(object, attribute, clusters = NULL) - -graph_diversity(object, attribute, clusters = NULL) - -graph_ei_index(object, attribute) - -graph_homophily(object, attribute) - -\method{plot}{graph_test}(x, ..., threshold = 0.95, tails = c("two", "one")) - -\method{print}{graph_test}(x, ..., max.length = 6, digits = 3) - -\method{print}{graph_measure}(x, ..., digits = 3) - -\method{print}{graph_motif}(x, ...) - -graph_adhesion(object) - -graph_cohesion(object) - -graph_assortativity(object) - -graph_balance(object) - -graph_betweenness(object, normalized = TRUE, direction = c("all", "out", "in")) - -graph_closeness(object, normalized = TRUE, direction = c("all", "out", "in")) - -graph_degree(object, normalized = TRUE, direction = c("all", "out", "in")) - -graph_eigenvector(object, normalized = TRUE) - -graph_components(object) - -graph_factions(object, membership = NULL) - -graph_congruency(object, object2) - -graph_equivalency(object) - -graph_core(object, membership = NULL) - -graph_density(object) - -graph_reciprocity(object, method = "default") - -graph_transitivity(object) - -graph_diameter(object) - -graph_length(object) - -graph_dyad_census(object) - -graph_triad_census(object) - -graph_mixed_census(object, object2) - -graph_modularity(object, membership = NULL, resolution = 1) - -graph_smallworld(object, times = 100) - -network_homophily(object, attribute) - -node_homophily(object, attribute) - test_gof(diff_model, diff_models) node_adopter(diff_model) @@ -147,90 +21,6 @@ wherever possible and update your scripts accordingly. } \section{Functions}{ \itemize{ -\item \code{edge_betweenness()}: Deprecated on 2022-06-28. - -\item \code{edge_closeness()}: Deprecated on 2022-06-28. - -\item \code{edge_degree()}: Deprecated on 2022-06-28. - -\item \code{edge_eigenvector()}: Deprecated on 2022-06-28. - -\item \code{edge_loop()}: Deprecated on 2022-06-28. - -\item \code{edge_multiple()}: Deprecated on 2022-06-28. - -\item \code{edge_bridges()}: Deprecated on 2022-06-28. - -\item \code{edge_reciprocal()}: Deprecated on 2022-06-28. - -\item \code{node_cuts()}: Deprecated on 2022-06-30. - -\item \code{graph_blau_index()}: Deprecated on 2022-09-10. - -\item \code{graph_diversity()}: Deprecated on 2022-09-25. - -\item \code{graph_ei_index()}: Deprecated on 2022-09-10. - -\item \code{graph_homophily()}: Deprecated on 2022-09-25. - -\item \code{plot(graph_test)}: Deprecated on 2022-09-25. - -\item \code{print(graph_test)}: Deprecated on 2022-09-25. - -\item \code{print(graph_measure)}: Deprecated on 2022-09-25. - -\item \code{print(graph_motif)}: Deprecated on 2022-09-25. - -\item \code{graph_adhesion()}: Deprecated on 2022-09-25. - -\item \code{graph_cohesion()}: Deprecated on 2022-09-25. - -\item \code{graph_assortativity()}: Deprecated on 2022-09-25. - -\item \code{graph_balance()}: Deprecated on 2022-09-25. - -\item \code{graph_betweenness()}: Deprecated on 2022-09-25. - -\item \code{graph_closeness()}: Deprecated on 2022-09-25. - -\item \code{graph_degree()}: Deprecated on 2022-09-25. - -\item \code{graph_eigenvector()}: Deprecated on 2022-09-25. - -\item \code{graph_components()}: Deprecated on 2022-09-25. - -\item \code{graph_factions()}: Deprecated on 2022-09-25. - -\item \code{graph_congruency()}: Deprecated on 2022-09-25. - -\item \code{graph_equivalency()}: Deprecated on 2022-09-25. - -\item \code{graph_core()}: Deprecated on 2022-09-25. - -\item \code{graph_density()}: Deprecated on 2022-09-25. - -\item \code{graph_reciprocity()}: Deprecated on 2022-09-25. - -\item \code{graph_transitivity()}: Deprecated on 2022-09-25. - -\item \code{graph_diameter()}: Deprecated on 2022-09-25. - -\item \code{graph_length()}: Deprecated on 2022-09-25. - -\item \code{graph_dyad_census()}: Deprecated on 2022-09-25. - -\item \code{graph_triad_census()}: Deprecated on 2022-09-25. - -\item \code{graph_mixed_census()}: Deprecated on 2022-09-25. - -\item \code{graph_modularity()}: Deprecated on 2022-09-25. - -\item \code{graph_smallworld()}: Deprecated on 2022-09-25. - -\item \code{network_homophily()}: Deprecated on 2022-09-25. - -\item \code{node_homophily()}: Deprecated on 2022-09-25. - \item \code{test_gof()}: Deprecated on 2024-06-16. \item \code{node_adopter()}: Deprecated on 2024-06-19. From 779dd2aa32ff686ca091bbc46bb529c441afcfb3 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 16:09:20 +0200 Subject: [PATCH 75/97] Fixed documentation bug in regression --- R/model_regression.R | 3 ++- man/regression.Rd | 3 +++ man/tests.Rd | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/R/model_regression.R b/R/model_regression.R index 6ef464e9..fff195b1 100644 --- a/R/model_regression.R +++ b/R/model_regression.R @@ -45,7 +45,8 @@ #' 'ego' is excluded from these calculations. #' See Haunss and Hollway (2023) for more on this effect. #' - dyadic covariates (other networks) can just be named -#' @inheritParams cohesion +#' @param .data A manynet-consistent network. +#' See e.g. `manynet::as_tidygraph()` for more details. #' @param method A method for establishing the null hypothesis. #' Note that "qap" uses Dekker et al's (2007) double semi-partialling technique, #' whereas "qapy" permutes only the $y$ variable. diff --git a/man/regression.Rd b/man/regression.Rd index f8c0ab89..5b232f9e 100644 --- a/man/regression.Rd +++ b/man/regression.Rd @@ -39,6 +39,9 @@ See Haunss and Hollway (2023) for more on this effect. \item dyadic covariates (other networks) can just be named }} +\item{.data}{A manynet-consistent network. +See e.g. \code{manynet::as_tidygraph()} for more details.} + \item{method}{A method for establishing the null hypothesis. Note that "qap" uses Dekker et al's (2007) double semi-partialling technique, whereas "qapy" permutes only the $y$ variable. diff --git a/man/tests.Rd b/man/tests.Rd index 7cee80e6..ecf13f52 100644 --- a/man/tests.Rd +++ b/man/tests.Rd @@ -25,6 +25,9 @@ test_permutation( ) } \arguments{ +\item{.data}{A manynet-consistent network. +See e.g. \code{manynet::as_tidygraph()} for more details.} + \item{FUN}{A graph-level statistic function to test.} \item{...}{Additional arguments to be passed on to FUN, From 1daea5ade4a9815eca1dee18bf8a6be1af4de8fe Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 16:33:58 +0200 Subject: [PATCH 76/97] Fixed missing scale_y_discrete reexport --- NAMESPACE | 2 ++ R/reexports_ggplot2.R | 5 +++++ man/reexports.Rd | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/NAMESPACE b/NAMESPACE index 9e7d2567..06803009 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -28,6 +28,7 @@ export(mutate) export(network_reg) export(node_adopter) export(rename) +export(scale_y_discrete) export(test_distribution) export(test_fit) export(test_gof) @@ -51,6 +52,7 @@ importFrom(ggplot2,ggsave) importFrom(ggplot2,ggtitle) importFrom(ggplot2,guides) importFrom(ggplot2,labs) +importFrom(ggplot2,scale_y_discrete) importFrom(ggplot2,xlab) importFrom(ggplot2,ylab) importFrom(igraph,is_igraph) diff --git a/R/reexports_ggplot2.R b/R/reexports_ggplot2.R index 9d58908b..16aacbe4 100644 --- a/R/reexports_ggplot2.R +++ b/R/reexports_ggplot2.R @@ -29,3 +29,8 @@ ggplot2::aes #' @importFrom ggplot2 ggsave #' @export ggplot2::ggsave + +#' @importFrom ggplot2 scale_y_discrete +#' @export +ggplot2::scale_y_discrete + diff --git a/man/reexports.Rd b/man/reexports.Rd index 1b4412db..9969dad8 100644 --- a/man/reexports.Rd +++ b/man/reexports.Rd @@ -26,6 +26,7 @@ \alias{ylab} \alias{aes} \alias{ggsave} +\alias{scale_y_discrete} \title{Objects exported from other packages} \keyword{internal} \description{ @@ -37,7 +38,7 @@ below to see their documentation. \item{generics}{\code{\link[generics]{glance}}, \code{\link[generics]{tidy}}} - \item{ggplot2}{\code{\link[ggplot2]{aes}}, \code{\link[ggplot2]{ggplot}}, \code{\link[ggplot2]{ggsave}}, \code{\link[ggplot2:labs]{ggtitle}}, \code{\link[ggplot2]{guides}}, \code{\link[ggplot2]{labs}}, \code{\link[ggplot2:labs]{xlab}}, \code{\link[ggplot2:labs]{ylab}}} + \item{ggplot2}{\code{\link[ggplot2]{aes}}, \code{\link[ggplot2]{ggplot}}, \code{\link[ggplot2]{ggsave}}, \code{\link[ggplot2:labs]{ggtitle}}, \code{\link[ggplot2]{guides}}, \code{\link[ggplot2]{labs}}, \code{\link[ggplot2:scale_discrete]{scale_y_discrete}}, \code{\link[ggplot2:labs]{xlab}}, \code{\link[ggplot2:labs]{ylab}}} \item{igraph}{\code{\link[igraph]{is_igraph}}} From 8137de67be0e637bb3a27ba6d6fe124c15d1b3dd Mon Sep 17 00:00:00 2001 From: James Hollway Date: Sun, 23 Jun 2024 16:34:41 +0200 Subject: [PATCH 77/97] Corrected manynet dependencies and net_ naming in tests --- R/model_tests.R | 8 ++++---- tests/testthat/test-model_tests.R | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/R/model_tests.R b/R/model_tests.R index 24d5868f..b994dda8 100644 --- a/R/model_tests.R +++ b/R/model_tests.R @@ -40,8 +40,8 @@ test_random <- function(.data, FUN, ..., } else { obsd <- FUN(.data) } - n <- manynet::network_dims(.data) - d <- network_density(.data) + n <- manynet::net_dims(.data) + d <- manynet::net_density(.data) oplan <- future::plan(strategy) on.exit(future::plan(oplan), add = TRUE) rands <- furrr::future_map(1:times, manynet::generate_random, n = n, p = d, @@ -90,8 +90,8 @@ test_permutation <- function(.data, FUN, ..., } else { obsd <- FUN(.data) } - n <- manynet::network_dims(.data) - d <- network_density(.data) + n <- manynet::net_dims(.data) + d <- manynet::net_density(.data) oplan <- future::plan(strategy) on.exit(future::plan(oplan), add = TRUE) rands <- furrr::future_map(1:times, diff --git a/tests/testthat/test-model_tests.R b/tests/testthat/test-model_tests.R index 22e4759e..26e9a58a 100644 --- a/tests/testthat/test-model_tests.R +++ b/tests/testthat/test-model_tests.R @@ -2,14 +2,14 @@ marvel_friends <- manynet::to_giant(manynet::to_unsigned(manynet::ison_marvel_relationships)) %>% manynet::to_subgraph(PowerOrigin == "Human") cugtest <- test_random(marvel_friends, - network_heterophily, + manynet::net_heterophily, attribute = "Attractive", times = 200) cugtest2 <- test_random(marvel_friends, - network_betweenness, + manynet::net_betweenness, times = 200) cugtest3 <- test_random(ison_southern_women, - network_equivalency, + manynet::net_equivalency, times = 200) test_that("test_random works", { @@ -42,7 +42,7 @@ marvel_friends <- manynet::to_unsigned(manynet::ison_marvel_relationships) marvel_friends <- manynet::to_giant(marvel_friends) marvel_friends <- manynet::to_subgraph(marvel_friends, PowerOrigin == "Human") qaptest <- test_permutation(marvel_friends, - network_heterophily, + manynet::net_heterophily, attribute = "Attractive", times = 200) test_that("test_permutation works", { From 9c1745f596b19b752db27e4bf9af28a667a4f086 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 3 Jul 2024 17:50:57 +0200 Subject: [PATCH 78/97] Fixed bug in test_random() where parameters were passed to manynet::generate_random() instead of the original object, which is processed more intuitively within manynet::generate_random() (thanks @RWKrause) --- R/model_tests.R | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/R/model_tests.R b/R/model_tests.R index b994dda8..63859a00 100644 --- a/R/model_tests.R +++ b/R/model_tests.R @@ -40,11 +40,9 @@ test_random <- function(.data, FUN, ..., } else { obsd <- FUN(.data) } - n <- manynet::net_dims(.data) - d <- manynet::net_density(.data) oplan <- future::plan(strategy) on.exit(future::plan(oplan), add = TRUE) - rands <- furrr::future_map(1:times, manynet::generate_random, n = n, p = d, + rands <- furrr::future_map(1:times, manynet::generate_random, n = .data, .progress = verbose, .options = furrr::furrr_options(seed = T)) if (length(args) > 0) { From 0749b5dddf6dec8db0f658715755a50261cda9b1 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 3 Jul 2024 17:52:21 +0200 Subject: [PATCH 79/97] Corrected that test_random() returns results on edge-conditioned uniform graphs, not size --- R/model_tests.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/model_tests.R b/R/model_tests.R index 63859a00..f627424c 100644 --- a/R/model_tests.R +++ b/R/model_tests.R @@ -63,7 +63,7 @@ test_random <- function(.data, FUN, ..., testdist = simd, mode = manynet::is_directed(.data), diag = manynet::is_complex(.data), - cmode = "csize", + cmode = "edges", plteobs = mean(simd <= obsd), pgteobs = mean(simd >= obsd), reps = times) From 15c8a7c3092d5e2143eee679050cb0c90c68244b Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 8 Jul 2024 19:02:47 +0200 Subject: [PATCH 80/97] Declared global variables --- R/migraph-package.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/R/migraph-package.R b/R/migraph-package.R index 252ff1b3..4d78ffe7 100644 --- a/R/migraph-package.R +++ b/R/migraph-package.R @@ -16,3 +16,6 @@ thisRequires <- function(pkgname){ } } } + +# defining global variables more centrally +utils::globalVariables(c(".data", ".graph_context")) \ No newline at end of file From cfd8f3422c0d1a461bba932cdb79b0bfecbf89a0 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 8 Jul 2024 19:03:06 +0200 Subject: [PATCH 81/97] Fixed various dependency issues --- DESCRIPTION | 5 +---- NAMESPACE | 5 ++++- R/migraph-defunct.R | 8 -------- R/model_tests.R | 5 +++-- man/defunct.Rd | 5 ----- man/tests.Rd | 4 ++-- tests/testthat/test-model_tests.R | 4 ++-- 7 files changed, 12 insertions(+), 24 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 2a9168a4..7b4beca8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: migraph Title: Many Network Measures, Motifs, Members, and Models Version: 1.4.0 -Date: 2024-05-23 +Date: 2024-07-08 Description: A set of tools for analysing multimodal networks. It includes functions for measuring centrality, centralization, cohesion, closure, constraint and diversity, @@ -30,10 +30,7 @@ Imports: network, future, furrr, - pillar, purrr, - rlang, - sna, tidygraph, tidyr Suggests: diff --git a/NAMESPACE b/NAMESPACE index 06803009..9177352f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -26,7 +26,6 @@ export(is_igraph) export(labs) export(mutate) export(network_reg) -export(node_adopter) export(rename) export(scale_y_discrete) export(test_distribution) @@ -56,6 +55,10 @@ importFrom(ggplot2,scale_y_discrete) importFrom(ggplot2,xlab) importFrom(ggplot2,ylab) importFrom(igraph,is_igraph) +importFrom(manynet,bind_node_attributes) +importFrom(manynet,generate_random) +importFrom(manynet,is_complex) +importFrom(manynet,is_directed) importFrom(network,as.network) importFrom(network,is.network) importFrom(purrr,flatten) diff --git a/R/migraph-defunct.R b/R/migraph-defunct.R index 71f90e20..f46e4284 100644 --- a/R/migraph-defunct.R +++ b/R/migraph-defunct.R @@ -18,11 +18,3 @@ test_gof <- function(diff_model, diff_models) { old = "test_gof") test_fit(diff_model, diff_models) } - -#' @describeIn defunct Deprecated on 2024-06-19. -#' @export -node_adopter <- function(diff_model) { - .Deprecated("node_in_adopter", package = "migraph", - old = "node_adopter") - node_in_adopter(diff_model) -} \ No newline at end of file diff --git a/R/model_tests.R b/R/model_tests.R index f627424c..10c9d790 100644 --- a/R/model_tests.R +++ b/R/model_tests.R @@ -21,11 +21,12 @@ NULL #' @rdname tests +#' @importFrom manynet generate_random bind_node_attributes is_directed is_complex #' @examples #' marvel_friends <- to_unsigned(ison_marvel_relationships) #' marvel_friends <- to_giant(marvel_friends) %>% #' to_subgraph(PowerOrigin == "Human") -#' (cugtest <- test_random(marvel_friends, network_heterophily, attribute = "Attractive", +#' (cugtest <- test_random(marvel_friends, manynet::net_heterophily, attribute = "Attractive", #' times = 200)) #' plot(cugtest) #' @export @@ -73,7 +74,7 @@ test_random <- function(.data, FUN, ..., #' @rdname tests #' @examples #' (qaptest <- test_permutation(marvel_friends, -#' network_heterophily, attribute = "Attractive", +#' manynet::net_heterophily, attribute = "Attractive", #' times = 200)) #' plot(qaptest) #' @export diff --git a/man/defunct.Rd b/man/defunct.Rd index b8c6e39d..359fd939 100644 --- a/man/defunct.Rd +++ b/man/defunct.Rd @@ -3,12 +3,9 @@ \name{defunct} \alias{defunct} \alias{test_gof} -\alias{node_adopter} \title{Functions that have been renamed, superseded, or are no longer working} \usage{ test_gof(diff_model, diff_models) - -node_adopter(diff_model) } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} @@ -23,7 +20,5 @@ wherever possible and update your scripts accordingly. \itemize{ \item \code{test_gof()}: Deprecated on 2024-06-16. -\item \code{node_adopter()}: Deprecated on 2024-06-19. - }} \keyword{internal} diff --git a/man/tests.Rd b/man/tests.Rd index ecf13f52..9648db86 100644 --- a/man/tests.Rd +++ b/man/tests.Rd @@ -68,11 +68,11 @@ of the original network. marvel_friends <- to_unsigned(ison_marvel_relationships) marvel_friends <- to_giant(marvel_friends) \%>\% to_subgraph(PowerOrigin == "Human") -(cugtest <- test_random(marvel_friends, network_heterophily, attribute = "Attractive", +(cugtest <- test_random(marvel_friends, manynet::net_heterophily, attribute = "Attractive", times = 200)) plot(cugtest) (qaptest <- test_permutation(marvel_friends, - network_heterophily, attribute = "Attractive", + manynet::net_heterophily, attribute = "Attractive", times = 200)) plot(qaptest) } diff --git a/tests/testthat/test-model_tests.R b/tests/testthat/test-model_tests.R index 26e9a58a..3cd280ba 100644 --- a/tests/testthat/test-model_tests.R +++ b/tests/testthat/test-model_tests.R @@ -19,7 +19,7 @@ test_that("test_random works", { expect_equal(length(cugtest$testdist), 200) # NB: Stochastic expect_false(cugtest$mode) expect_false(cugtest$diag) - expect_equal(cugtest$cmode, "csize") + expect_equal(cugtest$cmode, "edges") expect_equal(class(cugtest$plteobs), "numeric") expect_equal(class(cugtest$pgteobs), "numeric") expect_equal(cugtest$reps, 200) @@ -30,7 +30,7 @@ test_that("test_random works", { expect_equal(length(cugtest2$testdist), 200) # NB: Stochastic expect_false(cugtest2$mode) expect_false(cugtest2$diag) - expect_equal(cugtest2$cmode, "csize") + expect_equal(cugtest2$cmode, "edges") expect_equal(round(cugtest2$plteobs), 1) expect_equal(round(cugtest2$pgteobs), 0) expect_equal(cugtest2$reps, 200) From fba418b726e3b70a344fd1ed386e8d0ce8ef32a9 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Tue, 9 Jul 2024 07:45:22 +0200 Subject: [PATCH 82/97] Explaining situation in cran-comments --- cran-comments.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cran-comments.md b/cran-comments.md index ae763253..e46ec175 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,10 +1,15 @@ ## Test environments -* local R installation, x86_64-apple-darwin20, R 4.3.2 -* Mac OS X 12.6.9 (on Github), R 4.3.2 -* Microsoft Windows Server 2022 10.0.20348 (on Github), R 4.3.2 -* Ubuntu 22.04.3 (on Github), R 4.3.2 +* local R installation, aarch64-apple-darwin20, R 4.4.0 +* macOS 14.5 (on Github), R 4.4.1 +* Microsoft Windows Server 2022 10.0.20348 (on Github), R 4.4.1 +* Ubuntu 22.04.4 (on Github), R 4.4.1 ## R CMD check results 0 errors | 0 warnings | 0 notes + +* This release is expected to create errors with older versions of manynet, +but should create no errors with the latest version +* Since manynet is a Depends for migraph, this should not pose a problem for users +upgrading From 63dcb1455ff6fd5eef51cca3e809381d98cf12e6 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Tue, 9 Jul 2024 07:45:42 +0200 Subject: [PATCH 83/97] Commenting out tests/examples for now --- R/model_tests.R | 28 +++--- man/test_distributions.Rd | 14 +-- man/tests.Rd | 14 +-- tests/testthat/test-model_tests.R | 142 +++++++++++++++--------------- 4 files changed, 99 insertions(+), 99 deletions(-) diff --git a/R/model_tests.R b/R/model_tests.R index 10c9d790..29133a28 100644 --- a/R/model_tests.R +++ b/R/model_tests.R @@ -26,9 +26,9 @@ NULL #' marvel_friends <- to_unsigned(ison_marvel_relationships) #' marvel_friends <- to_giant(marvel_friends) %>% #' to_subgraph(PowerOrigin == "Human") -#' (cugtest <- test_random(marvel_friends, manynet::net_heterophily, attribute = "Attractive", -#' times = 200)) -#' plot(cugtest) +#' # (cugtest <- test_random(marvel_friends, manynet::net_heterophily, attribute = "Attractive", +#' # times = 200)) +#' # plot(cugtest) #' @export test_random <- function(.data, FUN, ..., times = 1000, @@ -73,10 +73,10 @@ test_random <- function(.data, FUN, ..., } #' @rdname tests #' @examples -#' (qaptest <- test_permutation(marvel_friends, -#' manynet::net_heterophily, attribute = "Attractive", -#' times = 200)) -#' plot(qaptest) +#' # (qaptest <- test_permutation(marvel_friends, +#' # manynet::net_heterophily, attribute = "Attractive", +#' # times = 200)) +#' # plot(qaptest) #' @export test_permutation <- function(.data, FUN, ..., times = 1000, @@ -189,8 +189,8 @@ NULL #' @rdname test_distributions #' @param diff_model1,diff_model2 diff_model objects #' @examples -#' test_distribution(play_diffusion(ison_networkers), -#' play_diffusion(ison_networkers, thresholds = 75)) +#' # test_distribution(play_diffusion(ison_networkers), +#' # play_diffusion(ison_networkers, thresholds = 75)) #' @export test_distribution <- function(diff_model1, diff_model2){ out <- stats::ks.test(diff_model1$I, diff_model2$I) @@ -220,12 +220,12 @@ test_distribution <- function(diff_model1, diff_model2){ # the set of simulated diffusions (and thus that the model is not a good fit). #' @examples #' # Playing a reasonably quick diffusion -#' x <- play_diffusion(generate_random(15), transmissibility = 0.7) +#' # x <- play_diffusion(generate_random(15), transmissibility = 0.7) #' # Playing a slower diffusion -#' y <- play_diffusions(generate_random(15), transmissibility = 0.1, times = 40) -#' plot(x) -#' plot(y) -#' test_fit(x, y) +#' # y <- play_diffusions(generate_random(15), transmissibility = 0.1, times = 40) +#' # plot(x) +#' # plot(y) +#' # test_fit(x, y) #' @export test_fit <- function(diff_model, diff_models){ # make into method? x <- diff_model diff --git a/man/test_distributions.Rd b/man/test_distributions.Rd index 7ba7d2e3..8dcfe041 100644 --- a/man/test_distributions.Rd +++ b/man/test_distributions.Rd @@ -46,15 +46,15 @@ then one can argue that the first diffusion is not well captured by } \examples{ - test_distribution(play_diffusion(ison_networkers), - play_diffusion(ison_networkers, thresholds = 75)) + # test_distribution(play_diffusion(ison_networkers), + # play_diffusion(ison_networkers, thresholds = 75)) # Playing a reasonably quick diffusion - x <- play_diffusion(generate_random(15), transmissibility = 0.7) + # x <- play_diffusion(generate_random(15), transmissibility = 0.7) # Playing a slower diffusion - y <- play_diffusions(generate_random(15), transmissibility = 0.1, times = 40) - plot(x) - plot(y) - test_fit(x, y) + # y <- play_diffusions(generate_random(15), transmissibility = 0.1, times = 40) + # plot(x) + # plot(y) + # test_fit(x, y) } \seealso{ Other models: diff --git a/man/tests.Rd b/man/tests.Rd index 9648db86..e464d12a 100644 --- a/man/tests.Rd +++ b/man/tests.Rd @@ -68,13 +68,13 @@ of the original network. marvel_friends <- to_unsigned(ison_marvel_relationships) marvel_friends <- to_giant(marvel_friends) \%>\% to_subgraph(PowerOrigin == "Human") -(cugtest <- test_random(marvel_friends, manynet::net_heterophily, attribute = "Attractive", - times = 200)) -plot(cugtest) -(qaptest <- test_permutation(marvel_friends, - manynet::net_heterophily, attribute = "Attractive", - times = 200)) -plot(qaptest) +# (cugtest <- test_random(marvel_friends, manynet::net_heterophily, attribute = "Attractive", +# times = 200)) +# plot(cugtest) +# (qaptest <- test_permutation(marvel_friends, +# manynet::net_heterophily, attribute = "Attractive", +# times = 200)) +# plot(qaptest) } \seealso{ Other models: diff --git a/tests/testthat/test-model_tests.R b/tests/testthat/test-model_tests.R index 3cd280ba..cb98b352 100644 --- a/tests/testthat/test-model_tests.R +++ b/tests/testthat/test-model_tests.R @@ -1,75 +1,75 @@ # # Making sure the tests family of functions works as intended. marvel_friends <- manynet::to_giant(manynet::to_unsigned(manynet::ison_marvel_relationships)) %>% manynet::to_subgraph(PowerOrigin == "Human") -cugtest <- test_random(marvel_friends, - manynet::net_heterophily, - attribute = "Attractive", - times = 200) -cugtest2 <- test_random(marvel_friends, - manynet::net_betweenness, - times = 200) -cugtest3 <- test_random(ison_southern_women, - manynet::net_equivalency, - times = 200) +# cugtest <- test_random(marvel_friends, +# manynet::net_heterophily, +# attribute = "Attractive", +# times = 200) +# cugtest2 <- test_random(marvel_friends, +# manynet::net_betweenness, +# times = 200) +# cugtest3 <- test_random(ison_southern_women, +# manynet::net_equivalency, +# times = 200) -test_that("test_random works", { - # Set the cugtest up - # Test stuff cug1 - expect_equal(as.numeric(cugtest$testval), -0.85714, tolerance = 0.001) - expect_equal(length(cugtest$testdist), 200) # NB: Stochastic - expect_false(cugtest$mode) - expect_false(cugtest$diag) - expect_equal(cugtest$cmode, "edges") - expect_equal(class(cugtest$plteobs), "numeric") - expect_equal(class(cugtest$pgteobs), "numeric") - expect_equal(cugtest$reps, 200) - expect_s3_class(cugtest, "network_test") - # Test stuff cug2 - expect_equal(as.numeric(cugtest2$testval), 0.2375, tolerance = 0.001) - # expect_equal(mean(cugtest3$testdist), 0.3600, tolerance = 0.02) - expect_equal(length(cugtest2$testdist), 200) # NB: Stochastic - expect_false(cugtest2$mode) - expect_false(cugtest2$diag) - expect_equal(cugtest2$cmode, "edges") - expect_equal(round(cugtest2$plteobs), 1) - expect_equal(round(cugtest2$pgteobs), 0) - expect_equal(cugtest2$reps, 200) - expect_s3_class(cugtest2, "network_test") -}) - -# Set the qaptest up -marvel_friends <- manynet::to_unsigned(manynet::ison_marvel_relationships) -marvel_friends <- manynet::to_giant(marvel_friends) -marvel_friends <- manynet::to_subgraph(marvel_friends, PowerOrigin == "Human") -qaptest <- test_permutation(marvel_friends, - manynet::net_heterophily, - attribute = "Attractive", - times = 200) -test_that("test_permutation works", { - expect_equal(as.numeric(qaptest$testval), -0.85714, tolerance = 0.001) - expect_equal(length(qaptest$testdist), 200) # NB: Stochastic - expect_equal(class(qaptest$plteobs), "numeric") # NB: Stochastic - expect_equal(class(qaptest$pgteobs), "numeric") # NB: Stochastic - expect_equal(qaptest$reps, 200) - expect_s3_class(qaptest, "network_test") -}) - -cugplot <- plot(cugtest) -test_that("cug plot works", { - expect_s3_class(cugplot, "gg") - expect_s3_class(cugplot$layers[[1]], "ggproto") - expect_s3_class(cugplot$layers[[1]]$geom, "GeomDensity") - expect_s3_class(cugplot$layers[[1]]$stat, "StatDensity") - expect_identical(cugplot$labels$x, "Statistic") - expect_identical(cugplot$labels$y, "Density") -}) - -qapplot <- plot(qaptest) -test_that("qap plot works", { - expect_s3_class(qapplot, "gg") - expect_s3_class(qapplot$layers[[1]], "ggproto") - expect_s3_class(qapplot$layers[[1]]$geom, "GeomDensity") - expect_s3_class(qapplot$layers[[1]]$stat, "StatDensity") - expect_identical(qapplot$labels$x, "Statistic") - expect_identical(qapplot$labels$y, "Density") -}) +# test_that("test_random works", { +# # Set the cugtest up +# # Test stuff cug1 +# expect_equal(as.numeric(cugtest$testval), -0.85714, tolerance = 0.001) +# expect_equal(length(cugtest$testdist), 200) # NB: Stochastic +# expect_false(cugtest$mode) +# expect_false(cugtest$diag) +# expect_equal(cugtest$cmode, "edges") +# expect_equal(class(cugtest$plteobs), "numeric") +# expect_equal(class(cugtest$pgteobs), "numeric") +# expect_equal(cugtest$reps, 200) +# expect_s3_class(cugtest, "network_test") +# # Test stuff cug2 +# expect_equal(as.numeric(cugtest2$testval), 0.2375, tolerance = 0.001) +# # expect_equal(mean(cugtest3$testdist), 0.3600, tolerance = 0.02) +# expect_equal(length(cugtest2$testdist), 200) # NB: Stochastic +# expect_false(cugtest2$mode) +# expect_false(cugtest2$diag) +# expect_equal(cugtest2$cmode, "edges") +# expect_equal(round(cugtest2$plteobs), 1) +# expect_equal(round(cugtest2$pgteobs), 0) +# expect_equal(cugtest2$reps, 200) +# expect_s3_class(cugtest2, "network_test") +# }) +# +# # Set the qaptest up +# marvel_friends <- manynet::to_unsigned(manynet::ison_marvel_relationships) +# marvel_friends <- manynet::to_giant(marvel_friends) +# marvel_friends <- manynet::to_subgraph(marvel_friends, PowerOrigin == "Human") +# qaptest <- test_permutation(marvel_friends, +# manynet::net_heterophily, +# attribute = "Attractive", +# times = 200) +# test_that("test_permutation works", { +# expect_equal(as.numeric(qaptest$testval), -0.85714, tolerance = 0.001) +# expect_equal(length(qaptest$testdist), 200) # NB: Stochastic +# expect_equal(class(qaptest$plteobs), "numeric") # NB: Stochastic +# expect_equal(class(qaptest$pgteobs), "numeric") # NB: Stochastic +# expect_equal(qaptest$reps, 200) +# expect_s3_class(qaptest, "network_test") +# }) +# +# cugplot <- plot(cugtest) +# test_that("cug plot works", { +# expect_s3_class(cugplot, "gg") +# expect_s3_class(cugplot$layers[[1]], "ggproto") +# expect_s3_class(cugplot$layers[[1]]$geom, "GeomDensity") +# expect_s3_class(cugplot$layers[[1]]$stat, "StatDensity") +# expect_identical(cugplot$labels$x, "Statistic") +# expect_identical(cugplot$labels$y, "Density") +# }) +# +# qapplot <- plot(qaptest) +# test_that("qap plot works", { +# expect_s3_class(qapplot, "gg") +# expect_s3_class(qapplot$layers[[1]], "ggproto") +# expect_s3_class(qapplot$layers[[1]]$geom, "GeomDensity") +# expect_s3_class(qapplot$layers[[1]]$stat, "StatDensity") +# expect_identical(qapplot$labels$x, "Statistic") +# expect_identical(qapplot$labels$y, "Density") +# }) From fcb93b7456dbe23f4a0ce88fd86e672550378c42 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 18:58:16 +0200 Subject: [PATCH 84/97] specificationAdvice now ignores absent ego terms for undirected networks --- R/model_regression.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/R/model_regression.R b/R/model_regression.R index fff195b1..a79e54b0 100644 --- a/R/model_regression.R +++ b/R/model_regression.R @@ -293,7 +293,7 @@ convertToMatrixList <- function(formula, data){ DV <- manynet::as_matrix(data) } else DV <- manynet::as_matrix(data) IVnames <- getRHSNames(formula) - specificationAdvice(IVnames) + specificationAdvice(IVnames, data) IVs <- lapply(IVnames, function(IV){ out <- lapply(seq_along(IV), function(elem){ # ego #### @@ -445,7 +445,7 @@ getDependentName <- function(formula) { unlist(lapply(dep, deparse)) } -specificationAdvice <- function(formula){ +specificationAdvice <- function(formula, data){ formdf <- t(data.frame(formula)) if(any(formdf[,1] %in% c("sim","same"))){ vars <- formdf[formdf[,1] %in% c("sim","same"), 2] @@ -456,6 +456,7 @@ specificationAdvice <- function(formula){ # incl }, FUN.VALUE = character(1)) suggests <- suggests[!is.na(suggests)] + if(!manynet::is_directed(data)) suggests <- suggests[!grepl("ego\\(", suggests)] if(length(suggests)>0){ if(length(suggests) > 1) suggests <- paste0(suggests, collapse = ", ") From fa38ea26adc443675eba34abf786e7e0a692cd69 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 18:58:47 +0200 Subject: [PATCH 85/97] Dropped centrality tutorial (in manynet) --- inst/tutorials/tutorial3/centrality.Rmd | 346 ------- inst/tutorials/tutorial3/centrality.html | 1098 ---------------------- 2 files changed, 1444 deletions(-) delete mode 100644 inst/tutorials/tutorial3/centrality.Rmd delete mode 100644 inst/tutorials/tutorial3/centrality.html diff --git a/inst/tutorials/tutorial3/centrality.Rmd b/inst/tutorials/tutorial3/centrality.Rmd deleted file mode 100644 index d8c5ea66..00000000 --- a/inst/tutorials/tutorial3/centrality.Rmd +++ /dev/null @@ -1,346 +0,0 @@ ---- -title: "Centrality" -author: "by James Hollway" -output: - learnr::tutorial: - theme: journal -runtime: shiny_prerendered -description: > - This tutorial aims to show how to measure and map degree, betweenness, - closeness, eigenvector and other types of centrality and centralization. ---- - -```{r setup, include=FALSE} -library(learnr) -library(manynet) -library(migraph) -library(patchwork) -knitr::opts_chunk$set(echo = FALSE) -ison_brandes2 <- ison_brandes %>% rename(type = twomode_type) -``` - -## Calculating centrality - -For this exercise, we'll use the `ison_brandes` dataset in `{manynet}`. -This dataset is in a 'tidygraph' format, -but `manynet` makes it easy to coerce this into other forms -to be compatible with other packages. -We can create a two-mode version of the dataset -by renaming the nodal attribute "twomode_type" to just "type". -Let's begin by graphing these datasets using `manynet::graphr()`. - -```{r coercion, exercise = TRUE, purl = FALSE} - -``` - -```{r coercion-hint-1, purl = FALSE} -# Let's graph the one-mode version -graphr(____) -``` - -```{r coercion-hint-2, purl = FALSE} -# Now, let's create a two-mode version 'ison_brandes2' and graph it. -ison_brandes2 <- ison_brandes %>% rename(type = twomode_type) -graphr(____) -``` - -```{r coercion-solution, purl = FALSE} -# plot the one-mode version -graphr(ison_brandes) -ison_brandes2 <- ison_brandes %>% rename(type = twomode_type) -# plot the two-mode version -graphr(ison_brandes2) -``` - -The network is anonymous, but I think it would be nice to add some names, -even if it's just pretend. -Luckily, `{manynet}` has a function for this. -This makes plotting the network just a wee bit more accessible and interpretable: - -```{r addingnames, exercise = TRUE, purl = FALSE} -ison_brandes <- to_named(ison_brandes) -``` - -```{r addingnames-hint-1, purl = FALSE} -# Now, let's graph using the object names: "ison_brandes" -graphr(____) -``` - -```{r addingnames-solution} -ison_brandes <- to_named(ison_brandes) -# plot network with names -graphr(ison_brandes) -``` - -Note that you will likely get a different set of names, -as they are assigned randomly from a pool of (American) first names. - -### Degree centrality - -Let's start with calculating degree, as it is easy to calculate yourself. -Just sum the rows or columns of the matrix! - -```{r degreesum, exercise = TRUE, exercise.setup = "addingnames", purl = FALSE} - -``` - -```{r degreesum-hint-1, purl = FALSE} -# We can calculate degree centrality like this: -(mat <- as_matrix(ison_brandes)) -(degrees <- rowSums(mat)) -rowSums(mat) == colSums(mat) -``` - -```{r degreesum-hint-2, purl = FALSE} -# Or by using a built in command in migraph like this: -node_degree(ison_brandes, normalized = FALSE) -``` - -```{r degreesum-solution} -# manually calculate degree centrality -mat <- as_matrix(ison_brandes) -degrees <- rowSums(mat) -rowSums(mat) == colSums(mat) -# You can also just use a built in command in migraph though: -node_degree(ison_brandes, normalized = FALSE) -``` - -```{r degreesum-Q, echo=FALSE, purl = FALSE} -question("Are the row sums the same as the column sums?", - answer("Yes", - correct = TRUE, - message = "That's right, that's because this is an undirected network."), - answer("No"), - allow_retry = FALSE -) -``` - -Often we are interested in the distribution of (degree) centrality in a network. -`{migraph}` offers a way to get a pretty good first look at this distribution, -though there are more elaborate ways to do this in base and grid graphics. - -```{r distrib, exercise = TRUE, exercise.setup = "addingnames", purl = FALSE} - -``` - -```{r distrib-solution} -# distribution of degree centrality scores of nodes -plot(node_degree(ison_brandes)) -``` - -What's plotted here by default is both the degree distribution as a histogram, -as well as a density plot overlaid on it. -What kind of shape does this have? - -### Other centralities - -Other measures of centrality can be a little trickier to calculate by hand. -Fortunately, we can use functions from `{migraph}` to help calculate the -betweenness, closeness, and eigenvector centralities for each node in the network. -Let's collect the vectors of these centralities for the `ison_brandes` dataset: - -```{r micent, exercise = TRUE, exercise.setup = "addingnames", purl = FALSE} - -``` - -```{r micent-hint-1, purl = FALSE} -# Use the node_betweenness() function to calculate the -# betweenness centralities of nodes in a network -node_betweenness(ison_brandes) -``` - -```{r micent-hint-2, purl = FALSE} -# Use the node_closeness() function to calculate the -# closeness centrality of nodes in a network -node_closeness(ison_brandes) -``` - -```{r micent-hint-3, purl = FALSE} -# Use the node_eigenvector() function to calculate -# the eigenvector centrality of nodes in a network -node_eigenvector(ison_brandes) -``` - -```{r micent-solution} -node_betweenness(ison_brandes) -node_closeness(ison_brandes) -node_eigenvector(ison_brandes) -# TASK: Can you create degree distributions for each of these? -``` - -What is returned here are vectors of betweenness, closeness, and eigenvector scores -for the nodes in the network. -But what do they mean? -Try to answer the following questions for yourself: - -- in what ways is a higher degree actor more 'central'? -- can you explain why a node that has the smallest sum of geodesic distances to all other nodes is said to be 'central'? -- why would an actor lying 'between' two other actors be 'central'? -- what does Bonacich mean when he says that power and influence are not the same thing? -- can you think of a real-world example when an actor might be central but not powerful, or powerful but not central? - -Note that all centrality measures in `{migraph}` return normalized -scores by default -- -for the raw scores, include `normalized = FALSE` in the function as an extra argument. - -## Plotting centrality - -It is straightforward in `{migraph}` to highlight nodes and ties -with maximum or minimum (e.g. degree) scores. -If the vector is numeric (i.e. a "measure"), -then this can be easily converted into a logical vector that -identifies the node/tie with the maximum/minimum score using -e.g. `node_is_max()` or `tie_is_min()`. -By passing this attribute to the `graphr()` argument "node_color" -we can highlight which node or nodes hold the maximum score in red. - -```{r ggid, exercise = TRUE, exercise.setup = "addingnames", purl = FALSE} - -``` - -```{r ggid-solution} -# plot the network, highlighting the node with the highest centrality score with a different colour -ison_brandes %>% - add_node_attribute("color", node_is_max(node_degree(ison_brandes))) %>% - graphr(node_color = "color") - -ison_brandes %>% - add_node_attribute("color", node_is_max(node_betweenness(ison_brandes))) %>% - graphr(node_color = "color") - -ison_brandes %>% - add_node_attribute("color", node_is_max(node_closeness(ison_brandes))) %>% - graphr(node_color = "color") - -ison_brandes %>% - add_node_attribute("color", node_is_max(node_eigenvector(ison_brandes))) %>% - graphr(node_color = "color") -``` - -How neat! Try it with the two-mode version. -What can you see? - -```{r ggid_twomode, exercise = TRUE, purl = FALSE} -# Instead of "ison_brandes", use "ison_brandes2" - -``` - -```{r ggid_twomode-solution} -ison_brandes2 %>% - add_node_attribute("color", node_is_max(node_degree(ison_brandes2))) %>% - graphr(node_color = "color") - -ison_brandes2 %>% - add_node_attribute("color", node_is_max(node_betweenness(ison_brandes2))) %>% - graphr(node_color = "color") - -ison_brandes2 %>% - add_node_attribute("color", node_is_max(node_closeness(ison_brandes2))) %>% - graphr(node_color = "color") - -ison_brandes2 %>% - add_node_attribute("color", node_is_max(node_eigenvector(ison_brandes2))) %>% - graphr(node_color = "color") -``` - -```{r brandes2quiz, purl = FALSE} -question("Select all that are true for the two-mode Brandes network.", - answer("Only one node is selected in each plot."), - answer("The maximum degree square has a higher degree than the maximum degree circle(s).", - correct = TRUE), - answer("No node is ever the most central according to two or more different centrality measures."), - allow_retry = TRUE, - random_answer_order = TRUE) -``` - -## Calculating centralization - -`{migraph}` also implements network centralization functions. -Here we are no longer interested in the level of the node, -but in the level of the whole network, -so the syntax replaces `node_` with `network_`: - -```{r centzn, exercise = TRUE, exercise.setup = "addingnames", purl = FALSE} - -``` - -```{r centzn-solution} -network_degree(ison_brandes) -network_betweenness(ison_brandes) -network_closeness(ison_brandes) -network_eigenvector(ison_brandes) -``` - -By default, scores are printed to 3 decimal places, -but this can be modified and, in any case, -the unrounded values are retained internally. -This means that even if rounded values are printed, -as much precision as is available is used in further calculations. - -Note that for centralization in two-mode networks, -two values are given (as a named vector), -since normalization typically depends on the (asymmetric) -number of nodes in each mode. - -What if we want to have a single image/figure with multiple plots? -This can be a little tricky with gg-based plots, -but fortunately the `{patchwork}` package is here to help. - -```{r multiplot, exercise = TRUE, exercise.setup = "addingnames", purl = FALSE} - -``` - -```{r multiplot-solution} -ison_brandes <- ison_brandes %>% - add_node_attribute("degree", - node_is_max(node_degree(ison_brandes))) %>% - add_node_attribute("betweenness", - node_is_max(node_betweenness(ison_brandes))) %>% - add_node_attribute("closeness", - node_is_max(node_closeness(ison_brandes))) %>% - add_node_attribute("eigenvector", - node_is_max(node_eigenvector(ison_brandes))) -gd <- graphr(ison_brandes, node_color = "degree") + - ggtitle("Degree", subtitle = round(network_degree(ison_brandes), 2)) -gc <- graphr(ison_brandes, node_color = "closeness") + - ggtitle("Closeness", subtitle = round(network_closeness(ison_brandes), 2)) -gb <- graphr(ison_brandes, node_color = "betweenness") + - ggtitle("Betweenness", subtitle = round(network_betweenness(ison_brandes), 2)) -ge <- graphr(ison_brandes, node_color = "eigenvector") + - ggtitle("Eigenvector", subtitle = round(network_eigenvector(ison_brandes), 2)) -(gd | gb) / (gc | ge) -# ggsave("brandes-centralities.pdf") -``` - - -```{r centzdq, purl = FALSE} -question("How centralized is the ison_brandes network? Select all that apply.", - answer("It is more degree centralised than betweenness centralised.", - message = "Degree centralisation is at 0.18 for this network whereas betweenness centralisation is at 0.32. In other words, the network is better characterised as having 1 or 2 nodes lying on the shortest paths between others than one where 1 or 2 nodes have many more ties than the others."), - answer("It is more closeness centralised than betweenness centralised.", - message = "Closeness centralisation is at 0.23 for this network whereas betweenness centralisation is at 0.32. In other words, the network is better characterised as having 1 or 2 nodes lying on the shortest paths between others than one where 1 or 2 nodes can reach or access most other nodes."), - answer("It is more eigenvector centralised than betweenness centralised.", - correct = TRUE, - message = "That's right, eigenvector centralisation is at 0.48 for this network whereas betweenness centralisation is at 0.32. In other words, the network is better characterised as having a core (or cores) of well-connected nodes rather than a wide network with only 1 or 2 nodes lying on the shortest paths between others."), - random_answer_order = TRUE, - allow_retry = TRUE) -``` - -```{r centvcent, echo=FALSE, purl = FALSE} -question("What is the difference between centrality and centralisation according to the literature?", - answer("Centrality is for nodes and centralisation is for networks", - correct = TRUE), - answer("Centrality is a state and centralisation is a process"), - answer("Centrality is a ity and centralisation is a sation"), - answer("Centrality is to centralisation what polarity is to polarisation"), - allow_retry = FALSE, - random_answer_order = TRUE -) -``` - -## Tasks - -1. Name a plausible research question you could ask of this data -for each of the four main centrality measures -(degree, betweenness, closeness, eigenvector) -You may want to add these as titles or subtitles to each plot. diff --git a/inst/tutorials/tutorial3/centrality.html b/inst/tutorials/tutorial3/centrality.html deleted file mode 100644 index 17308e0c..00000000 --- a/inst/tutorials/tutorial3/centrality.html +++ /dev/null @@ -1,1098 +0,0 @@ - - - - - - - - - - - - - - - - - -Centrality - - - - - - - - - - - - - - - - - - - - - -Skip to Tutorial Content - - - -
    -
    - -
    - -
    -

    Calculating centrality

    -

    For this exercise, we’ll use the ison_brandes dataset in -{manynet}. This dataset is in a ‘tidygraph’ format, but -manynet makes it easy to coerce this into other forms to be -compatible with other packages. We can create a two-mode version of the -dataset by renaming the nodal attribute “twomode_type” to just “type”. -Let’s begin by graphing these datasets using -manynet::graphr().

    -
    - -
    -
    -
    # Let's graph the one-mode version
    -graphr(____)
    -
    -
    -
    # Now, let's create a two-mode version 'ison_brandes2' and graph it.
    -ison_brandes2 <- ison_brandes %>% rename(type = twomode_type)
    -graphr(____)
    -
    -
    -
    # plot the one-mode version
    -graphr(ison_brandes)
    -ison_brandes2 <- ison_brandes %>% rename(type = twomode_type)
    -# plot the two-mode version
    -graphr(ison_brandes2)
    -
    -

    The network is anonymous, but I think it would be nice to add some -names, even if it’s just pretend. Luckily, {manynet} has a -function for this. This makes plotting the network just a wee bit more -accessible and interpretable:

    -
    -
    ison_brandes <- to_named(ison_brandes)
    - -
    -
    -
    # Now, let's graph using the object names: "ison_brandes"
    -graphr(____)
    -
    -
    -
    ison_brandes <- to_named(ison_brandes)
    -# plot network with names
    -graphr(ison_brandes)
    -
    -

    Note that you will likely get a different set of names, as they are -assigned randomly from a pool of (American) first names.

    -
    -

    Degree centrality

    -

    Let’s start with calculating degree, as it is easy to calculate -yourself. Just sum the rows or columns of the matrix!

    -
    - -
    -
    -
    # We can calculate degree centrality like this:
    -(mat <- as_matrix(ison_brandes))
    -(degrees <- rowSums(mat))
    -rowSums(mat) == colSums(mat)
    -
    -
    -
    # Or by using a built in command in migraph like this:
    -node_degree(ison_brandes, normalized = FALSE)
    -
    -
    -
    # manually calculate degree centrality
    -mat <- as_matrix(ison_brandes)
    -degrees <- rowSums(mat)
    -rowSums(mat) == colSums(mat)
    -# You can also just use a built in command in migraph though:
    -node_degree(ison_brandes, normalized = FALSE)
    -
    -
    -
    -
    -
    -
    - -
    -
    -

    Often we are interested in the distribution of (degree) centrality in -a network. {migraph} offers a way to get a pretty good -first look at this distribution, though there are more elaborate ways to -do this in base and grid graphics.

    -
    - -
    -
    -
    # distribution of degree centrality scores of nodes
    -plot(node_degree(ison_brandes))
    -
    -

    What’s plotted here by default is both the degree distribution as a -histogram, as well as a density plot overlaid on it. What kind of shape -does this have?

    -
    -
    -

    Other centralities

    -

    Other measures of centrality can be a little trickier to calculate by -hand. Fortunately, we can use functions from {migraph} to -help calculate the betweenness, closeness, and eigenvector centralities -for each node in the network. Let’s collect the vectors of these -centralities for the ison_brandes dataset:

    -
    - -
    -
    -
    # Use the node_betweenness() function to calculate the
    -# betweenness centralities of nodes in a network
    -node_betweenness(ison_brandes)
    -
    -
    -
    # Use the node_closeness() function to calculate the 
    -# closeness centrality of nodes in a network
    -node_closeness(ison_brandes)
    -
    -
    -
    # Use the node_eigenvector() function to calculate 
    -# the eigenvector centrality of nodes in a network
    -node_eigenvector(ison_brandes)
    -
    -
    -
    node_betweenness(ison_brandes)
    -node_closeness(ison_brandes)
    -node_eigenvector(ison_brandes)
    -# TASK: Can you create degree distributions for each of these?
    -
    -

    What is returned here are vectors of betweenness, closeness, and -eigenvector scores for the nodes in the network. But what do they mean? -Try to answer the following questions for yourself:

    -
      -
    • in what ways is a higher degree actor more ‘central’?
    • -
    • can you explain why a node that has the smallest sum of geodesic -distances to all other nodes is said to be ‘central’?
    • -
    • why would an actor lying ‘between’ two other actors be -‘central’?
    • -
    • what does Bonacich mean when he says that power and influence are -not the same thing?
    • -
    • can you think of a real-world example when an actor might be central -but not powerful, or powerful but not central?
    • -
    -

    Note that all centrality measures in {migraph} return -normalized scores by default – for the raw scores, include -normalized = FALSE in the function as an extra -argument.

    -
    -
    -
    -

    Plotting centrality

    -

    It is straightforward in {migraph} to highlight nodes -and ties with maximum or minimum (e.g. degree) scores. If the vector is -numeric (i.e. a “measure”), then this can be easily converted into a -logical vector that identifies the node/tie with the maximum/minimum -score using e.g. node_is_max() or -tie_is_min(). By passing this attribute to the -graphr() argument “node_color” we can highlight which node -or nodes hold the maximum score in red.

    -
    - -
    -
    -
    # plot the network, highlighting the node with the highest centrality score with a different colour
    -ison_brandes %>%
    -  add_node_attribute("color", node_is_max(node_degree(ison_brandes))) %>%
    -  graphr(node_color = "color")
    -
    -ison_brandes %>%
    -  add_node_attribute("color", node_is_max(node_betweenness(ison_brandes))) %>%
    -  graphr(node_color = "color")
    -
    -ison_brandes %>%
    -  add_node_attribute("color", node_is_max(node_closeness(ison_brandes))) %>%
    -  graphr(node_color = "color")
    -
    -ison_brandes %>%
    -  add_node_attribute("color", node_is_max(node_eigenvector(ison_brandes))) %>%
    -  graphr(node_color = "color")
    -
    -

    How neat! Try it with the two-mode version. What can you see?

    -
    -
    # Instead of "ison_brandes", use "ison_brandes2"
    - -
    -
    -
    ison_brandes2 %>%
    -  add_node_attribute("color", node_is_max(node_degree(ison_brandes2))) %>%
    -  graphr(node_color = "color")
    -
    -ison_brandes2 %>%
    -  add_node_attribute("color", node_is_max(node_betweenness(ison_brandes2))) %>%
    -  graphr(node_color = "color")
    -
    -ison_brandes2 %>%
    -  add_node_attribute("color", node_is_max(node_closeness(ison_brandes2))) %>%
    -  graphr(node_color = "color")
    -
    -ison_brandes2 %>%
    -  add_node_attribute("color", node_is_max(node_eigenvector(ison_brandes2))) %>%
    -  graphr(node_color = "color")
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -

    Calculating centralization

    -

    {migraph} also implements network centralization -functions. Here we are no longer interested in the level of the node, -but in the level of the whole network, so the syntax replaces -node_ with network_:

    -
    - -
    -
    -
    network_degree(ison_brandes)
    -network_betweenness(ison_brandes)
    -network_closeness(ison_brandes)
    -network_eigenvector(ison_brandes)
    -
    -

    By default, scores are printed to 3 decimal places, but this can be -modified and, in any case, the unrounded values are retained internally. -This means that even if rounded values are printed, as much precision as -is available is used in further calculations.

    -

    Note that for centralization in two-mode networks, two values are -given (as a named vector), since normalization typically depends on the -(asymmetric) number of nodes in each mode.

    -

    What if we want to have a single image/figure with multiple plots? -This can be a little tricky with gg-based plots, but fortunately the -{patchwork} package is here to help.

    -
    - -
    -
    -
    ison_brandes <- ison_brandes %>%
    -  add_node_attribute("degree",
    -                              node_is_max(node_degree(ison_brandes))) %>%
    -  add_node_attribute("betweenness",
    -                              node_is_max(node_betweenness(ison_brandes))) %>%
    -  add_node_attribute("closeness",
    -                              node_is_max(node_closeness(ison_brandes))) %>%
    -  add_node_attribute("eigenvector",
    -                              node_is_max(node_eigenvector(ison_brandes)))
    -gd <- graphr(ison_brandes, node_color = "degree") + 
    -  ggtitle("Degree", subtitle = round(network_degree(ison_brandes), 2))
    -gc <- graphr(ison_brandes, node_color = "closeness") + 
    -  ggtitle("Closeness", subtitle = round(network_closeness(ison_brandes), 2))
    -gb <- graphr(ison_brandes, node_color = "betweenness") + 
    -  ggtitle("Betweenness", subtitle = round(network_betweenness(ison_brandes), 2))
    -ge <- graphr(ison_brandes, node_color = "eigenvector") + 
    -  ggtitle("Eigenvector", subtitle = round(network_eigenvector(ison_brandes), 2))
    -(gd | gb) / (gc | ge)
    -# ggsave("brandes-centralities.pdf")
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -

    Tasks

    -
      -
    1. Name a plausible research question you could ask of this data for -each of the four main centrality measures (degree, betweenness, -closeness, eigenvector) You may want to add these as titles or subtitles -to each plot. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    2. -
    - - - - - - -
    - -
    - -
    -
    -
    -
    - - -
    -

    Centrality

    -

    by James Hollway

    -
    - - -
    -
    -
    -
    - - -
    -
    - - - - - - - - - - - - - - - - From a94ca7690adcf2268571ce83a711694950d64793 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 18:59:46 +0200 Subject: [PATCH 86/97] Renamed regression tutorial the diversity tutorial --- inst/tutorials/tutorial8/diversity.Rmd | 25 + .../{regression.html => diversity.html} | 534 +++++++++++------- inst/tutorials/tutorial8/regression.Rmd | 483 ---------------- 3 files changed, 361 insertions(+), 681 deletions(-) create mode 100644 inst/tutorials/tutorial8/diversity.Rmd rename inst/tutorials/tutorial8/{regression.html => diversity.html} (83%) delete mode 100644 inst/tutorials/tutorial8/regression.Rmd diff --git a/inst/tutorials/tutorial8/diversity.Rmd b/inst/tutorials/tutorial8/diversity.Rmd new file mode 100644 index 00000000..ec31891a --- /dev/null +++ b/inst/tutorials/tutorial8/diversity.Rmd @@ -0,0 +1,25 @@ +--- +title: "Diversity and Regression" +author: "by James Hollway" +output: + learnr::tutorial: + theme: journal +runtime: shiny_prerendered +description: > + This tutorial aims to teach you how to measure and test network diversity, + moving from univariate to multivariate tests, including + network linear models (multiple regression quadratic assignment procedures). +--- + +```{r setup, include=FALSE} +library(learnr) +library(manynet) +library(migraph) +library(patchwork) +library(ggplot2) +knitr::opts_chunk$set(echo = FALSE) +marvel_friends <- to_unsigned(ison_marvel_relationships, keep = "positive") +marvel_friends <- to_giant(marvel_friends) +marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances)) +``` + diff --git a/inst/tutorials/tutorial8/regression.html b/inst/tutorials/tutorial8/diversity.html similarity index 83% rename from inst/tutorials/tutorial8/regression.html rename to inst/tutorials/tutorial8/diversity.html index a9796b13..db82a449 100644 --- a/inst/tutorials/tutorial8/regression.html +++ b/inst/tutorials/tutorial8/diversity.html @@ -15,7 +15,7 @@ -Regression +Diversity and Regression @@ -110,10 +110,10 @@
    -
    -

    Setting up

    -

    For this session, we’ll explore a couple of different datasets.

    -

    First, let’s examine homogeneity/heterogeneity in the Marvel +

    +

    Initial visualisation

    +

    For this session, we’ll explore a couple of different datasets. +First, let’s examine homogeneity/heterogeneity in the Marvel relationships dataset from {manynet}, ison_marvel_relationships. The dataset is quite complicated, so to make this simpler, let’s concentrate on:

    @@ -173,10 +173,10 @@

    Setting up

    marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances)) marvel_friends
    -

    This gives us a dataset of nearly twenty characters and a little more -than 100 edges. Recall that this data has several nodal attributes. -Explore a couple of these attributes, “Gender” and “PowerOrigin” -visually using graphr().

    +

    This gives us an undirected network of nearly twenty characters and a +little more than 100 edges. Recall that this data has several nodal +attributes. Let’s explore a couple of these attributes, “Gender” and +“PowerOrigin”, visually using graphr().

    @@ -201,26 +201,68 @@

    Setting up

    node_color = "PowerOrigin")

    These variables seem to be distributed unevenly across the network. -There seems to be some homophily, or like choosing like, operating here, -but it is difficult to tell because there are clearly more male than -female superheros shown here, as well as clearly more superheros of -mutant origin than others. To get started then, we need to establish how -diverse this network really is.

    +There seems to be some homophily – or like choosing like – operating +here, but it is difficult to say conclusively because there are clearly +more male than female superheros, as well as clearly more superheros of +mutant origin than others. So what might seem like homophily could just +be a result of there being many more opportunities for ties between +nodes of some categories. We therefore need to establish how diverse +this network really is.

    -
    -

    Calculating diversity

    -
    -

    Calculating Blau index

    -

    We can begin by calculating the diversity in the network for each -attribute. Recall that the Blau index for any given diversity variable -is:

    +
    +

    Measuring richness

    +

    We can begin by measuring the number of different categories there +are. Here we might assume that the more different categories there are, +the more diverse the network is. The measure of ‘richness’ is inherited +from the study of biodiversity, and calculates the number of different +categories are presented in a dataset for a given variable.

    +
    + +
    +
    +
    net_richness(____, ____)
    +
    +
    +
    net_richness(marvel_friends, "Gender")
    +net_richness(marvel_friends, "PowerOrigin")
    +net_richness(marvel_friends, "Attractive")
    +net_richness(marvel_friends, "Rich")
    +net_richness(marvel_friends, "Intellect")
    +
    +
    +
    +
    +
    +
    + +
    +
    +

    Note though that ‘richness’ as a network measure does not include any +sense of how distributed these categories are around the network. There +is a measure of nodal richness available, which counts the number of +different categories to which each node is tied, but this does not offer +a summary of how evenly distributed the appearance of categories are. +For that we would need to move on to something like the Blau index.

    +
    +
    +

    Measuring diversity

    +

    Another measure that reflects the diversity in the network for each +attribute is the Blau Index. Recall that the Blau index for any given +variable is:

    \[1 - \sum p_i^2\]

    where \(p\) represents the proportion belonging to any given category, and \(i\) indexes each of the given categories. A perfectly homogeneous group would receive a score of 0, while a perfectly heterogeneous group (with members spread evenly over the -maximum categories) would receive a score of 1.

    +maximum categories) would receive a score of 1. Obtain the network +diversity scores for our five attributes.

    @@ -229,16 +271,16 @@

    Calculating Blau index

    -
    network_diversity(____, ____)
    +
    net_diversity(____, ____)
    -
    network_diversity(marvel_friends, "Gender")
    -network_diversity(marvel_friends, "PowerOrigin")
    -network_diversity(marvel_friends, "Attractive")
    -network_diversity(marvel_friends, "Rich")
    -network_diversity(marvel_friends, "Intellect")
    +
    net_diversity(marvel_friends, "Gender")
    +net_diversity(marvel_friends, "PowerOrigin")
    +net_diversity(marvel_friends, "Attractive")
    +net_diversity(marvel_friends, "Rich")
    +net_diversity(marvel_friends, "Intellect")

    Looks like there is more diversity in terms of where these characters got their powers, whether they have significant intellectual powers, and @@ -256,26 +298,26 @@

    Calculating Blau index

    -
    network_diversity(____, ____, ____)
    +
    net_diversity(____, ____, ____)
    -
    network_diversity(marvel_friends, "Gender", "PowerOrigin")
    +
    net_diversity(marvel_friends, "Gender", "PowerOrigin")
     as.factor(node_attribute(marvel_friends, "PowerOrigin")) # view categories in PowerOrigin
    -network_diversity(marvel_friends, "Intellect", "Gender")
    +net_diversity(marvel_friends, "Intellect", "Gender")

    Note that the length of the vector returned as a result is the number of categories in the second category listed. It looks like some origin -stories are much more diverse than others. Gods (just Thor here) and +stories are more gender diverse than others. Gods (just Thor here) and humans are all men, whereas those with mutant or radiation origin -stories are more gender diverse. There doesn’t seem to be any -significant difference in intellect across gender categories -however.

    +stories are more gender diverse. There doesn’t appear to be much +difference in intellect across gender categories however.

    Ok, this tells us about how (un)even the distribution of these variables is in this network, but it doesn’t necessarily tell us whether -within this network there is homophily/heterophily.

    -
    +ties are appearing more frequently between nodes of similar (or +different) categories. For that we need to look at +homophily/heterophily.


      @@ -285,11 +327,12 @@

      Calculating Blau index

      class="footnote-back">↩︎

    -
    -

    Calculating EI index

    -

    A step in this direction is to calculate the EI (or E-I) index. -Calculating the EI index follows the same syntax. Recall that the EI -index is calculated as:

    +
    +
    +

    Measuring heterophily

    +

    The EI (or E-I) index offers a way to measure the degree to which +ties appear between rather than within groups of nodes of the same +category. Recall that the EI index is calculated as:

    \[\frac{E-I}{E+I}\]

    where \(E\) is the number of ties present between a variable’s categories (i.e. external), and Calculating EI index variable’s categories (i.e. internal). As such, an EI index of -1 suggests perfect homophily, whereas an EI index of +1 suggests perfect heterophily. (This is why the function is called -network_heterophily()).

    +net_heterophily()).

    Check how homophilic three variables in the network are, “Gender”, “PowerOrigin”, and “Attractive”.

    Calculating EI index
    -
    network_heterophily(____, ____)
    +
    net_heterophily(____, ____)
    -
    (obs.gender <- network_heterophily(marvel_friends, "Gender"))
    -(obs.powers <- network_heterophily(marvel_friends, "PowerOrigin")) 
    -(obs.attract <- network_heterophily(marvel_friends, "Attractive")) 
    +
    (obs.gender <- net_heterophily(marvel_friends, "Gender"))
    +(obs.powers <- net_heterophily(marvel_friends, "PowerOrigin")) 
    +(obs.attract <- net_heterophily(marvel_friends, "Attractive")) 
    @@ -330,21 +373,19 @@

    Calculating EI index

    chance for a network of this size and density and distribution of that attribute.

    -
    -
    -

    Testing scores

    -
    -

    Conditional uniform graph tests

    -

    To see whether we should be surprised by a score this high/low, we -will simulate a series of random graphs (Erdös-Renyi/Bernoulli) of the -same dimensions and distribution of the attribute to find out whether -there is more homophily or heterophily than expected by chance.

    -

    This is called a conditional uniform graph test, but -{migraph} chooses more descriptive function names, such as +

    +

    CUG tests

    +

    To see whether we should be surprised by scores this high/low, we +compare these scores with those from a series of random graphs +(Erdös-Renyi/Bernoulli) of the same dimensions and distribution of the +attribute. This can help us establish whether there is more homophily or +heterophily than expected by chance.

    +

    This is often called a conditional uniform graph or CUG test, but +{migraph} uses more descriptive function names, such as test_random(). Plot the results of running this function -with respect to the EI index on each of the three variables used above -one thousand times.

    +with respect to the EI index on each of the three variables. You can +specify that one thousand simulations should be used using +times = 1000.

    @@ -364,13 +405,13 @@

    Conditional uniform graph tests

    data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    rand.gender <- test_random(marvel_friends, 
    -                           network_heterophily, attribute = "Gender", 
    +                           net_heterophily, attribute = "Gender", 
                                times = 1000)
     rand.power <- test_random(marvel_friends, 
    -                          network_heterophily, attribute = "PowerOrigin", 
    +                          net_heterophily, attribute = "PowerOrigin", 
                               times = 1000)
     rand.attract <- test_random(marvel_friends, 
    -                            network_heterophily, attribute = "Attractive", 
    +                            net_heterophily, attribute = "Attractive", 
                                 times = 1000)
     plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute")
     plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute")
    @@ -398,16 +439,20 @@ 

    Conditional uniform graph tests

    returned larger EI scores, between .1 and .4. That is, there is significantly less heterophily here than expected.

    -
    -

    Quadratic assignment procedure tests

    -

    Ah, but perhaps the random graph is not the best reference group for +

    +

    QAP tests

    +

    Ah, but perhaps random graphs are not the best reference group for establishing whether there is a significant homophily effect here. After -all, social networks are not completely random; they are structured.

    -

    Another approach is to use permutations of the network. Permuting the -network retains the structure of the network, but reassigns any labels -(variables) randomly. Let’s first plot the observed data and some -permuted data next to each other.

    +all, social networks are not completely random; they are +structured in particular ways, such as some nodes having higher +degrees than others, or there being a core and periphery or community +topology.

    +

    Another approach to establishing a baseline for whether we should be +surprised by a given score or not is to use permutations of the +underlying network instead of random graphs. Permuting the network +retains the structure of the network because the ties are kept and only +the labels (variables) are reassigned randomly. Let’s first plot the +observed data and some permuted data next to each other.

    @@ -439,11 +484,11 @@

    Quadratic assignment procedure tests

    -

    This single permutation suggests there might otherwise be some more -even mixing of these attributes, but it is just a single permutation. -Let’s try a test that runs this over a succession of permutations, just -as we did with random graphs. Plot the results for gender and power -according to the random and permutation baselines.

    +

    This single permutation suggests a more even mixing of these +attributes is possible, but it is just a single permutation. Let’s try a +test that runs this over a succession of permutations, just as we did +with random graphs. Plot the results for gender and power according to +the random and permutation baselines.

    @@ -459,14 +504,20 @@

    Quadratic assignment procedure tests

    data-completion="1" data-diagnostics="1" data-startover="1" data-lines="0" data-pipe="|>">
    (perm.gender <- test_permutation(marvel_friends, 
    -                                network_heterophily, attribute = "Gender",
    +                                net_heterophily, attribute = "Gender",
                                     times = 1000))
     (perm.power <- test_permutation(marvel_friends, 
    -                                network_heterophily, attribute = "PowerOrigin",
    +                                net_heterophily, attribute = "PowerOrigin",
                                     times = 1000))
     
    -(plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") + theme(plot.title = element_text(size=8)) | plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") + theme(plot.title = element_text(size=8))) /
    -(plot(perm.gender) + ggtitle("QAP test results for 'Gender' attribute") + theme(plot.title = element_text(size=8)) | plot(perm.power) + ggtitle("QAP test results for 'PowerOrigin' attribute") + theme(plot.title = element_text(size=8)))
    +(plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") + + theme(plot.title = element_text(size=8)) | + plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") + + theme(plot.title = element_text(size=8))) / +(plot(perm.gender) + ggtitle("QAP test results for 'Gender' attribute") + + theme(plot.title = element_text(size=8)) | + plot(perm.power) + ggtitle("QAP test results for 'PowerOrigin' attribute") + + theme(plot.title = element_text(size=8)))

    Again, we see that there is perhaps nothing so surprising that we got the homophily score for gender that we did, but the lack of power origin @@ -475,7 +526,7 @@

    Quadratic assignment procedure tests

    distribution (be mindful of the scale of the x-axis). That is, taking into account the structure of the network leads us to expect a larger spread in the EI index than when the variable is distributed -around a random network.

    +across a random network.

    @@ -485,9 +536,8 @@

    Quadratic assignment procedure tests

    -
    -
    -

    Network linear models

    +
    +

    Network regression

    Next let us examine homophily in another network. The data were collected as part of an early experiment on communication between social network researchers who were using an Electronic Information Exchange @@ -509,14 +559,18 @@

    Network linear models

    categorical Discipline variables and come up with a couple of key hypotheses:

      -
    • \(H_1\): whether these researchers -send more emails to those who are cited more
    • -
    • \(H_2\): whether there is -disciplinary homophily
    • +
    • \(H_1\): researchers send more +emails to those who are cited more (popularity hypothesis)
    • +
    • \(H_2\): researchers send more +emails to those of the same discipline (disciplinary homophily +hypothesis)

    Let’s start with a pretty maximally specified model (note that it doesn’t make sense to include both ego and alter effects because these -are undirected).

    +networks are undirected). We are using times = 200 here +because of time-out limitations in the learnr tutorial +system, but for publication quality results you would want to base your +conclusions on 2000 simulations or more.

    @@ -546,9 +600,10 @@

    Network linear models

    data-lines="0" data-pipe="|>">
    -

    We can use tidy methods to get the salient information from this -model, and {migraph} includes also a plot method for these -results to facilitate the quick interpretation of these results.

    +

    We can use tidy methods (e.g. tidy(), +glance()) to get the salient information from this model, +and {migraph} includes also a plot method for these results +to facilitate the quick interpretation of these results.

    @@ -562,9 +617,9 @@

    Network linear models

    plot(model1)

    This violin plot presents the distribution of coefficients from -permutations of the network, with the fitted coefficient from the data -as a red dot. Subtle lines are used to indicate 95%, but here the -distributions are rendered so wide that they are often not seen.

    +permutations of the network, with the coefficient fitted from the data +as a red dot. Lines are used to indicate 95% thresholds, but here the +distributions are rendered so wide that they are often not visible.

    @@ -573,7 +628,11 @@

    Network linear models

    -

    +

    While these are the conclusions from this ‘play’ data, you may have +more and more interesting data at hand. How would you go about +specifying such a model? Why is such an approach more appropriate for +network data than linear or logistic regression? + + + + + + + + + - - + - + + - - + - + + - - + - + + - - + - + + - - + - + + - - + - + + - - + - + + - - + - + + - - + - + + - - + - + + - - +

    @@ -1271,7 +1408,8 @@

    Network linear models

    -

    Regression

    +

    Diversity and +Regression

    by James Hollway

    diff --git a/inst/tutorials/tutorial8/regression.Rmd b/inst/tutorials/tutorial8/regression.Rmd deleted file mode 100644 index ae285746..00000000 --- a/inst/tutorials/tutorial8/regression.Rmd +++ /dev/null @@ -1,483 +0,0 @@ ---- -title: "Regression" -author: "by James Hollway" -output: - learnr::tutorial: - theme: journal -runtime: shiny_prerendered -description: > - This tutorial aims to teach you how to measure and test network diversity, - moving from univariate to multivariate tests, including - network linear models (multiple regression quadratic assignment procedures). ---- - -```{r setup, include=FALSE} -library(learnr) -library(manynet) -library(migraph) -library(patchwork) -library(ggplot2) -knitr::opts_chunk$set(echo = FALSE) -marvel_friends <- to_unsigned(ison_marvel_relationships, keep = "positive") -marvel_friends <- to_giant(marvel_friends) -marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances)) -``` - -## Setting up - -For this session, we'll explore a couple of different datasets. - -First, let's examine homogeneity/heterogeneity in the Marvel relationships dataset from `{manynet}`, -`ison_marvel_relationships`. -The dataset is quite complicated, -so to make this simpler, let's concentrate on: - -- just the positive (friendship) ties and not the negative (enmity) ties -- the main (giant) component without any isolates -- just those characters that appear in the comics more than average - -Fortunately, all these data cleaning moves are easy to do in `{manynet}`, -and can be seen in the following chunk in order: - -```{r friends, exercise=TRUE, purl = FALSE} - -``` - -```{r friends-hint-1, purl = FALSE} -# since the dataset is a 'signed' graph, we want to get just the -# positively signed ties to get the friendship graph -# (and lose the enmity relations) -to_unsigned(____, keep = "positive") -``` - -```{r friends-hint-2, purl = FALSE} -# to_giant() is a quick easy way to get the giant/main component -to_giant(____) -``` - -```{r friends-hint-3, purl = FALSE} -to_subgraph(____, Appearances >= mean(Appearances)) -``` - -```{r friends-hint-4, purl = FALSE} -# don't forget to assign the results! -marvel_friends <- ____ -``` - -```{r friends-hint-5, purl = FALSE} -marvel_friends <- to_unsigned(ison_marvel_relationships, keep = "positive") -marvel_friends <- to_giant(marvel_friends) -marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances)) -marvel_friends -``` - -```{r friends-solution} -marvel_friends <- to_unsigned(ison_marvel_relationships, keep = "positive") -marvel_friends <- to_giant(marvel_friends) -marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances)) -marvel_friends -``` - -This gives us a dataset of nearly twenty characters and a little more than 100 edges. -Recall that this data has several nodal attributes. -Explore a couple of these attributes, "Gender" and "PowerOrigin" visually -using `graphr()`. - -```{r plotfriends, exercise=TRUE, purl = FALSE} - -``` - -```{r plotfriends-hint, purl = FALSE} -# Since both Gender and PowerOrigin are categorical variables -# you will need to use two different aesthetic dimensions to -# represent them together. -# Which will you present as shapes and which as colors? -graphr(____, - node_shape = ____, - node_color = ____) -``` - -```{r plotfriends-solution} -graphr(marvel_friends, - node_shape = "Gender", - node_color = "PowerOrigin") -``` - -These variables seem to be distributed unevenly across the network. -There seems to be some homophily, or like choosing like, -operating here, but it is difficult to tell because there are -clearly more male than female superheros shown here, -as well as clearly more superheros of mutant origin than others. -To get started then, we need to establish how diverse this network really is. - -## Calculating diversity - -### Calculating Blau index - -We can begin by calculating the diversity in the network for each attribute. -Recall that the Blau index for any given diversity variable is: - -$$1 - \sum p_i^2$$ - -where $p$ represents the proportion belonging to any given category, -and $i$ indexes each of the given categories. -A perfectly homogeneous group would receive a score of 0, -while a perfectly heterogeneous group (with members spread evenly over the maximum categories) -would receive a score of 1. - -```{r blau, exercise=TRUE, purl = FALSE} - -``` - -```{r blau-hint, purl = FALSE} -network_diversity(____, ____) -``` - -```{r blau-solution} -network_diversity(marvel_friends, "Gender") -network_diversity(marvel_friends, "PowerOrigin") -network_diversity(marvel_friends, "Attractive") -network_diversity(marvel_friends, "Rich") -network_diversity(marvel_friends, "Intellect") -``` - -Looks like there is more diversity in terms of where these characters got -their powers, whether they have significant intellectual powers, -and their gender, than their attractiveness or their wealth. - -We can also cross-reference this diversity. -For example, we might be interested in whether our comic book heroes -are equally gender diverse across their (power) origin stories, -or equally intellectually diverse across gender.^[Note that this works for calculated categorical variables too, such as cluster/group assignment from community detection or equivalence classes.] - -```{r crossref, exercise=TRUE, purl = FALSE} - -``` - -```{r crossref-hint, purl = FALSE} -network_diversity(____, ____, ____) -``` - -```{r crossref-solution} -network_diversity(marvel_friends, "Gender", "PowerOrigin") -as.factor(node_attribute(marvel_friends, "PowerOrigin")) # view categories in PowerOrigin -network_diversity(marvel_friends, "Intellect", "Gender") -``` - -Note that the length of the vector returned as a result -is the number of categories in the second category listed. -It looks like some origin stories are much more diverse than others. -Gods (just Thor here) and humans are all men, -whereas those with mutant or radiation origin stories are more gender diverse. -There doesn't seem to be any significant difference in intellect -across gender categories however. - -Ok, this tells us about how (un)even the distribution of these variables is in this network, -but it doesn't necessarily tell us whether within this network there is homophily/heterophily. - -### Calculating EI index - -A step in this direction is to calculate the EI (or E-I) index. -Calculating the EI index follows the same syntax. -Recall that the EI index is calculated as: - -$$\frac{E-I}{E+I}$$ - -where $E$ is the number of ties present between a variable's categories (i.e. external), -and $I$ is the number of ties present within a variable's categories (i.e. internal). -As such, an EI index of -1 suggests perfect homophily, whereas an EI index of +1 suggests perfect heterophily. -(This is why the function is called `network_heterophily()`). - -Check how homophilic three variables in the network are, -"Gender", "PowerOrigin", and "Attractive". - -```{r ei, exercise=TRUE, purl = FALSE} - -``` - -```{r ei-hint, purl = FALSE} -network_heterophily(____, ____) -``` - -```{r ei-solution} -(obs.gender <- network_heterophily(marvel_friends, "Gender")) -(obs.powers <- network_heterophily(marvel_friends, "PowerOrigin")) -(obs.attract <- network_heterophily(marvel_friends, "Attractive")) -``` - -```{r homophily-present, echo=FALSE, purl = FALSE} -question("For which variables is there a signal of homophily according to the EI index? (Choose all that apply)", - answer("Gender", - correct = TRUE, - message = "Yes, looks like there might be some gender homophily present."), - answer("PowerOrigin", - message = "The score for power origin homophily is so close to 0 that it does not seem to signal much."), - answer("Attractive", - correct = TRUE, - message = "And looks like a fairly large effect for homophily on the basis of looks..."), - allow_retry = TRUE -) -``` - -Ultimately though, these are just scores, -and doesn't tell us whether this is any more or less than -what we might expect the score to be by chance for a network -of this size and density and distribution of that attribute. - -## Testing scores - -### Conditional uniform graph tests - -To see whether we should be surprised by a score this high/low, -we will simulate a series of random graphs -(Erdös-Renyi/Bernoulli) of the same dimensions and -distribution of the attribute to find out whether there is -more homophily or heterophily than expected by chance. - -This is called a conditional uniform graph test, -but `{migraph}` chooses more descriptive function names, -such as `test_random()`. -Plot the results of running this function with respect to the EI index -on each of the three variables used above one thousand times. - -```{r rando, exercise=TRUE, purl = FALSE} - -``` - -```{r rando-hint-1, purl = FALSE} -rand.____ <- test_random(____, FUN = ____, attribute = ____, times = ___) -``` - -```{r rando-hint-2, purl = FALSE} -plot(rand.____) -``` - -```{r rando-hint-3, purl = FALSE} -rand.gender <- test_random(marvel_friends, - network_heterophily, attribute = "Gender", - times = 1000) -rand.power <- test_random(marvel_friends, - network_heterophily, attribute = "PowerOrigin", - times = 1000) -rand.attract <- test_random(marvel_friends, - network_heterophily, attribute = "Attractive", - times = 1000) -plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") -plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") -plot(rand.attract) + ggtitle("CUG test results for 'Attractive' attribute") -``` - -```{r rando-solution} -rand.gender <- test_random(marvel_friends, - network_heterophily, attribute = "Gender", - times = 1000) -rand.power <- test_random(marvel_friends, - network_heterophily, attribute = "PowerOrigin", - times = 1000) -rand.attract <- test_random(marvel_friends, - network_heterophily, attribute = "Attractive", - times = 1000) -plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") -plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") -plot(rand.attract) + ggtitle("CUG test results for 'Attractive' attribute") -``` - -The plots of these results use a dotted vertical line for 0 where this is in bounds, -a red vertical line for the observed score, -and a density plot of the scores from the randomly generated networks. -The grey tails of the distribution are a visual aid indicating the most extreme 5% of scores -from the distribution. - -The results are _really_ interesting. -Despite being the larger coefficients (in absolute terms), -it looks like we cannot reject the null hypothesis that there is no homophily -for gender nor for attractiveness. -Both observed scores fall within the range of scores we would expect from -randomly generated networks with the same distribution of that variable. - -However, we can reject the null hypothesis with respect to their power origin story. -While the coefficient itself is close to 0 (neither strong homophily nor heterophily), -all the random networks generated returned larger EI scores, between .1 and .4. -That is, there is significantly less heterophily here than expected. - -### Quadratic assignment procedure tests - -Ah, but perhaps the random graph is not the best reference group -for establishing whether there is a significant homophily effect here. -After all, social networks are not completely random; they are structured. - -Another approach is to use permutations of the network. -Permuting the network retains the structure of the network, -but reassigns any labels (variables) randomly. -Let's first plot the observed data and some permuted data next to each other. - -```{r perm, exercise=TRUE, purl = FALSE} - -``` - -```{r perm-hint, purl = FALSE} -graphr(generate_permutation(____, with_attr = TRUE), ____) -``` - -```{r perm-solution} -old <- graphr(marvel_friends, - labels = FALSE, node_size = 6, - node_color = "PowerOrigin", - node_shape = "Gender") + ggtitle("Original network") -new <- graphr(generate_permutation(marvel_friends, with_attr = TRUE), - labels = FALSE, node_size = 6, - node_color = "PowerOrigin", - node_shape = "Gender") + ggtitle("Permuted network") -old + new -``` - -```{r cupqap-qn, echo=FALSE, purl = FALSE} -question("Which of the following is true?", - answer("Random networks retain the structure of the original network.", - message = learnr::random_encouragement()), - answer("Permuted networks retain the structure of the original network.", - correct = TRUE, - message = learnr::random_praise()), - answer("Both random and permuted networks retain the distribution of attributes.", - correct = TRUE, - message = learnr::random_praise()), - answer("Permuted networks retain the ties among the same nodes from the original network.", - message = "Permuted networks randomly reassign any variables and change positions of nodes by swapping the rows and columns of an adjacency matrix."), - random_answer_order = TRUE, - allow_retry = TRUE -) -``` - -This single permutation suggests there might otherwise be some more even mixing of these -attributes, but it is just a single permutation. -Let's try a test that runs this over a succession of permutations, -just as we did with random graphs. -Plot the results for gender and power according to the random and permutation baselines. - -```{r testperm, exercise=TRUE, exercise.setup = "rando-solution", purl = FALSE} - -``` - -```{r testperm-hint, purl = FALSE} -test_permutation(____, FUN = ____, attribute = ____, - times = ____) -``` - -```{r testperm-solution, purl = FALSE} -(perm.gender <- test_permutation(marvel_friends, - network_heterophily, attribute = "Gender", - times = 1000)) -(perm.power <- test_permutation(marvel_friends, - network_heterophily, attribute = "PowerOrigin", - times = 1000)) - -(plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") + theme(plot.title = element_text(size=8)) | plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") + theme(plot.title = element_text(size=8))) / -(plot(perm.gender) + ggtitle("QAP test results for 'Gender' attribute") + theme(plot.title = element_text(size=8)) | plot(perm.power) + ggtitle("QAP test results for 'PowerOrigin' attribute") + theme(plot.title = element_text(size=8))) -``` - -Again, we see that there is perhaps nothing so surprising that we got the homophily score -for gender that we did, but the lack of power origin heterophily is surprising. -Note how the distributions are generally wider when permuting the observed network -than creating a random distribution (be mindful of the scale of the _x_-axis). -That is, taking into account the structure of the network leads us to -expect a larger spread in the EI index than when the variable is distributed around a random network. - -```{r cupqap-results, echo=FALSE, purl = FALSE} -question("What can we say from these results?", - answer("We can reject the null hypothesis that there is no homophily for gender in the comparison with random networks", - message = "We cannot reject the null hypothesis since the result is in the range of expected scores across randomised networks, indicated by the red line between the grey shaded zones."), - answer("We can reject the null hypothesis that there is no homophily for power origin in the comparison with random networks", - correct = TRUE, - message = learnr::random_praise()), - answer("We can reject the null hypothesis that there is no homophily for power origin in both CUG and QAP tests", - correct = TRUE, - message = learnr::random_praise()), - answer("We can reject the null hypothesis that there is no homophily for gender in both CUG and QAP tests", - message = "We cannot reject the null hypothesis since the result is in the range of expected scores across randomised and permuted networks, indicated by the red lines between the grey shaded zones in both plots."), - allow_retry = TRUE -) -``` - -## Network linear models - -Next let us examine homophily in another network. -The data were collected as part of an early experiment on communication between social network researchers who were using an Electronic Information Exchange System (EIES). -You may recognise some of the names. -The main network consists of 32 scholars with directed ties weighted by the total number of messages sent from $i$ to $j$ over the period of the study. -Nodal attributes collected include the primary discipline and number of citations in the social science citation index at the start of the study. - -```{r introeies, exercise=TRUE, purl = FALSE} -ison_networkers -graphr(ison_networkers, node_color = "Discipline") -``` - -Let's use both the continuous `Citations` and the categorical `Discipline` variables -and come up with a couple of key hypotheses: - -- $H_1$: whether these researchers send more emails to those who are cited more -- $H_2$: whether there is disciplinary homophily - -Let's start with a pretty maximally specified model -(note that it doesn't make sense to include both ego and alter effects because these are undirected). - -```{r qapmax, exercise=TRUE, exercise.timelimit = 3600, purl = FALSE} - -``` - -```{r qapmax-hint-1, purl = FALSE} -network_reg(____, ison_networkers, times = 200) -``` - -```{r qapmax-hint-2, purl = FALSE} -weight ~ alter(Citations) + sim(Citations) + - alter(Discipline) + same(Discipline) -``` - -```{r qapmax-hint-3, purl = FALSE} -model1 <- network_reg(weight ~ alter(Citations) + sim(Citations) + - alter(Discipline) + same(Discipline), - ison_networkers, times = 200) -# If the model runs into a timeout error, please reduce the number of 'times' in the function above. -``` - -```{r qapmax-solution} -model1 <- network_reg(weight ~ alter(Citations) + sim(Citations) + - alter(Discipline) + same(Discipline), - ison_networkers, times = 200) -``` - -We can use tidy methods to get the salient information from this model, -and `{migraph}` includes also a plot method for these results to -facilitate the quick interpretation of these results. - -```{r qapinterp, exercise=TRUE, exercise.setup = "qapmax-solution", purl = FALSE} - -``` - -```{r qapinterp-solution} -tidy(model1) -glance(model1) -plot(model1) -``` - -This violin plot presents the distribution of coefficients from permutations of the network, -with the fitted coefficient from the data as a red dot. -Subtle lines are used to indicate 95%, -but here the distributions are rendered so wide that they are often not seen. - -```{r qap-interp, echo=FALSE, purl = FALSE} -question("What can we say from these results?", - answer("Researchers send more messages to those who are cited more", - message = "Looks like alter Citations is not significant."), - answer("Researchers send more messages to those who similarly cited", - message = "Looks like sim Citations is not significant."), - answer("Researchers send more messages to mathematicians than anthropologists", - message = "Looks like alter Discipline Mathematics is not significant."), - answer("Researchers send more messages to sociologists than anthropologists", - message = "Looks like alter Discipline Sociology is not significant."), - answer("Not much", - correct = TRUE, - message = "Yes, the fitted coefficients are, if not typical, at least unsurprising from permutations of the network and so there's no evidence for rejecting the null hypothesis on the basis of this data."), - allow_retry = TRUE -) -``` From c305c0fbc5bb0ae0db283a773cba9954cc220881 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 19:00:13 +0200 Subject: [PATCH 87/97] Initial section of diversity tutorial now about visualisation --- inst/tutorials/tutorial8/diversity.Rmd | 88 ++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/inst/tutorials/tutorial8/diversity.Rmd b/inst/tutorials/tutorial8/diversity.Rmd index ec31891a..4b17488b 100644 --- a/inst/tutorials/tutorial8/diversity.Rmd +++ b/inst/tutorials/tutorial8/diversity.Rmd @@ -23,3 +23,91 @@ marvel_friends <- to_giant(marvel_friends) marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances)) ``` +## Initial visualisation + +For this session, we'll explore a couple of different datasets. +First, let's examine homogeneity/heterogeneity in the Marvel relationships dataset from `{manynet}`, +`ison_marvel_relationships`. +The dataset is quite complicated, +so to make this simpler, let's concentrate on: + +- just the positive (friendship) ties and not the negative (enmity) ties +- the main (giant) component without any isolates +- just those characters that appear in the comics more than average + +Fortunately, all these data cleaning moves are easy to do in `{manynet}`, +and can be seen in the following chunk in order: + +```{r friends, exercise=TRUE, purl = FALSE} + +``` + +```{r friends-hint-1, purl = FALSE} +# since the dataset is a 'signed' graph, we want to get just the +# positively signed ties to get the friendship graph +# (and lose the enmity relations) +to_unsigned(____, keep = "positive") +``` + +```{r friends-hint-2, purl = FALSE} +# to_giant() is a quick easy way to get the giant/main component +to_giant(____) +``` + +```{r friends-hint-3, purl = FALSE} +to_subgraph(____, Appearances >= mean(Appearances)) +``` + +```{r friends-hint-4, purl = FALSE} +# don't forget to assign the results! +marvel_friends <- ____ +``` + +```{r friends-hint-5, purl = FALSE} +marvel_friends <- to_unsigned(ison_marvel_relationships, keep = "positive") +marvel_friends <- to_giant(marvel_friends) +marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances)) +marvel_friends +``` + +```{r friends-solution} +marvel_friends <- to_unsigned(ison_marvel_relationships, keep = "positive") +marvel_friends <- to_giant(marvel_friends) +marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances)) +marvel_friends +``` + +This gives us an undirected network of nearly twenty characters and a little more than 100 edges. +Recall that this data has several nodal attributes. +Let's explore a couple of these attributes, "Gender" and "PowerOrigin", visually +using `graphr()`. + +```{r plotfriends, exercise=TRUE, purl = FALSE} + +``` + +```{r plotfriends-hint, purl = FALSE} +# Since both Gender and PowerOrigin are categorical variables +# you will need to use two different aesthetic dimensions to +# represent them together. +# Which will you present as shapes and which as colors? +graphr(____, + node_shape = ____, + node_color = ____) +``` + +```{r plotfriends-solution} +graphr(marvel_friends, + node_shape = "Gender", + node_color = "PowerOrigin") +``` + +These variables seem to be distributed unevenly across the network. +There seems to be some homophily -- or like choosing like -- +operating here, but it is difficult to say conclusively because there are +clearly more male than female superheros, +as well as clearly more superheros of mutant origin than others. +So what might seem like homophily could just be a result of there being +many more opportunities for ties between nodes of some categories. +We therefore need to establish how diverse this network really is. + From fff75c2bf1a67cebe13d780b223e2b8667ba5ac3 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 19:00:26 +0200 Subject: [PATCH 88/97] Added richness section --- inst/tutorials/tutorial8/diversity.Rmd | 47 ++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/inst/tutorials/tutorial8/diversity.Rmd b/inst/tutorials/tutorial8/diversity.Rmd index 4b17488b..9685f3c9 100644 --- a/inst/tutorials/tutorial8/diversity.Rmd +++ b/inst/tutorials/tutorial8/diversity.Rmd @@ -111,3 +111,50 @@ So what might seem like homophily could just be a result of there being many more opportunities for ties between nodes of some categories. We therefore need to establish how diverse this network really is. +## Measuring richness + +We can begin by measuring the number of different categories there are. +Here we might assume that the more different categories there are, +the more diverse the network is. +The measure of 'richness' is inherited from the study of biodiversity, +and calculates the number of different categories are presented in a +dataset for a given variable. + +```{r rich, exercise=TRUE, purl = FALSE} + +``` + +```{r rich-hint, purl = FALSE} +net_richness(____, ____) +``` + +```{r rich-solution} +net_richness(marvel_friends, "Gender") +net_richness(marvel_friends, "PowerOrigin") +net_richness(marvel_friends, "Attractive") +net_richness(marvel_friends, "Rich") +net_richness(marvel_friends, "Intellect") +``` + +```{r richness-question, echo=FALSE, purl = FALSE} +question("Which variable is the most 'diverse' according to this richness measure?", + answer("Gender"), + answer("PowerOrigin", + correct = TRUE, + message = "There are four categories available in this data for power origin, while the other variables include only two categories each."), + answer("Attractive"), + answer("Rich"), + answer("Intellect"), + random_answer_order = TRUE, + allow_retry = TRUE +) +``` + +Note though that 'richness' as a network measure does not include +any sense of how distributed these categories are around the network. +There is a measure of nodal richness available, +which counts the number of different categories to which each node is tied, +but this does not offer a summary of how evenly distributed the appearance +of categories are. +For that we would need to move on to something like the Blau index. + From d1cdef4cd4a413e65e7f2fb0b17eabf7e742c690 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 19:01:15 +0200 Subject: [PATCH 89/97] Diversity section now split from heterophily section to make passage through the tutorial more straightforward --- inst/tutorials/tutorial8/diversity.Rmd | 116 +++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/inst/tutorials/tutorial8/diversity.Rmd b/inst/tutorials/tutorial8/diversity.Rmd index 9685f3c9..0859ef73 100644 --- a/inst/tutorials/tutorial8/diversity.Rmd +++ b/inst/tutorials/tutorial8/diversity.Rmd @@ -158,3 +158,119 @@ but this does not offer a summary of how evenly distributed the appearance of categories are. For that we would need to move on to something like the Blau index. +## Measuring diversity + +Another measure that reflects the diversity in the network for each attribute +is the Blau Index. +Recall that the Blau index for any given variable is: + +$$1 - \sum p_i^2$$ + +where $p$ represents the proportion belonging to any given category, +and $i$ indexes each of the given categories. +A perfectly homogeneous group would receive a score of 0, +while a perfectly heterogeneous group (with members spread evenly over the maximum categories) +would receive a score of 1. +Obtain the network diversity scores for our five attributes. + +```{r blau, exercise=TRUE, purl = FALSE} + +``` + +```{r blau-hint, purl = FALSE} +net_diversity(____, ____) +``` + +```{r blau-solution} +net_diversity(marvel_friends, "Gender") +net_diversity(marvel_friends, "PowerOrigin") +net_diversity(marvel_friends, "Attractive") +net_diversity(marvel_friends, "Rich") +net_diversity(marvel_friends, "Intellect") +``` + +Looks like there is more diversity in terms of where these characters got +their powers, whether they have significant intellectual powers, +and their gender, than their attractiveness or their wealth. + +We can also cross-reference this diversity. +For example, we might be interested in whether our comic book heroes +are equally gender diverse across their (power) origin stories, +or equally intellectually diverse across gender.^[Note that this works for calculated categorical variables too, such as cluster/group assignment from community detection or equivalence classes.] + +```{r crossref, exercise=TRUE, purl = FALSE} + +``` + +```{r crossref-hint, purl = FALSE} +net_diversity(____, ____, ____) +``` + +```{r crossref-solution} +net_diversity(marvel_friends, "Gender", "PowerOrigin") +as.factor(node_attribute(marvel_friends, "PowerOrigin")) # view categories in PowerOrigin +net_diversity(marvel_friends, "Intellect", "Gender") +``` + +Note that the length of the vector returned as a result +is the number of categories in the second category listed. +It looks like some origin stories are more gender diverse than others. +Gods (just Thor here) and humans are all men, +whereas those with mutant or radiation origin stories are more gender diverse. +There doesn't appear to be much difference in intellect +across gender categories however. + +Ok, this tells us about how (un)even the distribution of these variables is in this network, +but it doesn't necessarily tell us whether ties are appearing more frequently +between nodes of similar (or different) categories. +For that we need to look at homophily/heterophily. + +## Measuring heterophily + +The EI (or E-I) index offers a way to measure the degree to which ties +appear between rather than within groups of nodes of the same category. +Recall that the EI index is calculated as: + +$$\frac{E-I}{E+I}$$ + +where $E$ is the number of ties present between a variable's categories (i.e. external), +and $I$ is the number of ties present within a variable's categories (i.e. internal). +As such, an EI index of -1 suggests perfect homophily, whereas an EI index of +1 suggests perfect heterophily. +(This is why the function is called `net_heterophily()`). + +Check how homophilic three variables in the network are, +"Gender", "PowerOrigin", and "Attractive". + +```{r ei, exercise=TRUE, purl = FALSE} + +``` + +```{r ei-hint, purl = FALSE} +net_heterophily(____, ____) +``` + +```{r ei-solution} +(obs.gender <- net_heterophily(marvel_friends, "Gender")) +(obs.powers <- net_heterophily(marvel_friends, "PowerOrigin")) +(obs.attract <- net_heterophily(marvel_friends, "Attractive")) +``` + +```{r homophily-present, echo=FALSE, purl = FALSE} +question("For which variables is there a signal of homophily according to the EI index? (Choose all that apply)", + answer("Gender", + correct = TRUE, + message = "Yes, looks like there might be some gender homophily present."), + answer("PowerOrigin", + message = "The score for power origin homophily is so close to 0 that it does not seem to signal much."), + answer("Attractive", + correct = TRUE, + message = "And looks like a fairly large effect for homophily on the basis of looks..."), + allow_retry = TRUE +) +``` + +Ultimately though, these are just scores, +and doesn't tell us whether this is any more or less than +what we might expect the score to be by chance for a network +of this size and density and distribution of that attribute. + From 2931c54e821460d258801278ed88e1647f2d6b35 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 19:02:45 +0200 Subject: [PATCH 90/97] Updated CUG test section --- inst/tutorials/tutorial8/diversity.Rmd | 76 +++++++++++++++++++++++++ inst/tutorials/tutorial8/diversity.html | 72 +++++++++++------------ 2 files changed, 112 insertions(+), 36 deletions(-) diff --git a/inst/tutorials/tutorial8/diversity.Rmd b/inst/tutorials/tutorial8/diversity.Rmd index 0859ef73..9e2c8371 100644 --- a/inst/tutorials/tutorial8/diversity.Rmd +++ b/inst/tutorials/tutorial8/diversity.Rmd @@ -274,3 +274,79 @@ and doesn't tell us whether this is any more or less than what we might expect the score to be by chance for a network of this size and density and distribution of that attribute. +## CUG tests + +To see whether we should be surprised by scores this high/low, +we compare these scores with those from a series of random graphs +(Erdös-Renyi/Bernoulli) of the same dimensions and +distribution of the attribute. +This can help us establish whether there is +more homophily or heterophily than expected by chance. + +This is often called a conditional uniform graph or CUG test, +but `{migraph}` uses more descriptive function names, +such as `test_random()`. +Plot the results of running this function with respect to the EI index +on each of the three variables. +You can specify that one thousand simulations should be used using `times = 1000`. + +```{r rando, exercise=TRUE, purl = FALSE} + +``` + +```{r rando-hint-1, purl = FALSE} +rand.____ <- test_random(____, FUN = ____, attribute = ____, times = ___) +``` + +```{r rando-hint-2, purl = FALSE} +plot(rand.____) +``` + +```{r rando-hint-3, purl = FALSE} +rand.gender <- test_random(marvel_friends, + net_heterophily, attribute = "Gender", + times = 1000) +rand.power <- test_random(marvel_friends, + net_heterophily, attribute = "PowerOrigin", + times = 1000) +rand.attract <- test_random(marvel_friends, + net_heterophily, attribute = "Attractive", + times = 1000) +plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") +plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") +plot(rand.attract) + ggtitle("CUG test results for 'Attractive' attribute") +``` + +```{r rando-solution} +rand.gender <- test_random(marvel_friends, + net_heterophily, attribute = "Gender", + times = 1000) +rand.power <- test_random(marvel_friends, + net_heterophily, attribute = "PowerOrigin", + times = 1000) +rand.attract <- test_random(marvel_friends, + net_heterophily, attribute = "Attractive", + times = 1000) +plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") +plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") +plot(rand.attract) + ggtitle("CUG test results for 'Attractive' attribute") +``` + +The plots of these results use a dotted vertical line for 0 where this is in bounds, +a red vertical line for the observed score, +and a density plot of the scores from the randomly generated networks. +The grey tails of the distribution are a visual aid indicating the most extreme 5% of scores +from the distribution. + +The results are _really_ interesting. +Despite being the larger coefficients (in absolute terms), +it looks like we cannot reject the null hypothesis that there is no homophily +for gender nor for attractiveness. +Both observed scores fall within the range of scores we would expect from +randomly generated networks with the same distribution of that variable. + +However, we can reject the null hypothesis with respect to their power origin story. +While the coefficient itself is close to 0 (neither strong homophily nor heterophily), +all the random networks generated returned larger EI scores, between .1 and .4. +That is, there is significantly less heterophily here than expected. + diff --git a/inst/tutorials/tutorial8/diversity.html b/inst/tutorials/tutorial8/diversity.html index db82a449..4fc1b829 100644 --- a/inst/tutorials/tutorial8/diversity.html +++ b/inst/tutorials/tutorial8/diversity.html @@ -798,20 +798,20 @@

    Network regression

    @@ -961,15 +961,15 @@

    Network regression

    @@ -1003,11 +1003,11 @@

    Network regression

    label = "\"rando\"", exercise = "TRUE", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, check = NULL, solution = structure(c("rand.gender <- test_random(marvel_friends, ", - " network_heterophily, attribute = \"Gender\", ", + " net_heterophily, attribute = \"Gender\", ", " times = 1000)", "rand.power <- test_random(marvel_friends, ", - " network_heterophily, attribute = \"PowerOrigin\", ", + " net_heterophily, attribute = \"PowerOrigin\", ", " times = 1000)", "rand.attract <- test_random(marvel_friends, ", - " network_heterophily, attribute = \"Attractive\", ", + " net_heterophily, attribute = \"Attractive\", ", " times = 1000)", "plot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\")", "plot(rand.power) + ggtitle(\"CUG test results for 'PowerOrigin' attribute\")", "plot(rand.attract) + ggtitle(\"CUG test results for 'Attractive' attribute\")" @@ -1085,25 +1085,25 @@

    Network regression

    @@ -1134,8 +1134,8 @@

    Network regression

    "library(manynet)", "library(migraph)", "library(patchwork)", "library(ggplot2)", "knitr::opts_chunk$set(echo = FALSE)", "marvel_friends <- to_unsigned(ison_marvel_relationships, keep = \"positive\")", "marvel_friends <- to_giant(marvel_friends)", "marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances))" -), chunk_opts = list(label = "setup", include = FALSE)), setup = "rand.gender <- test_random(marvel_friends, \n network_heterophily, attribute = \"Gender\", \n times = 1000)\nrand.power <- test_random(marvel_friends, \n network_heterophily, attribute = \"PowerOrigin\", \n times = 1000)\nrand.attract <- test_random(marvel_friends, \n network_heterophily, attribute = \"Attractive\", \n times = 1000)\nplot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\")\nplot(rand.power) + ggtitle(\"CUG test results for 'PowerOrigin' attribute\")\nplot(rand.attract) + ggtitle(\"CUG test results for 'Attractive' attribute\")", - chunks = list(list(label = "rando-solution", code = "rand.gender <- test_random(marvel_friends, \n network_heterophily, attribute = \"Gender\", \n times = 1000)\nrand.power <- test_random(marvel_friends, \n network_heterophily, attribute = \"PowerOrigin\", \n times = 1000)\nrand.attract <- test_random(marvel_friends, \n network_heterophily, attribute = \"Attractive\", \n times = 1000)\nplot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\")\nplot(rand.power) + ggtitle(\"CUG test results for 'PowerOrigin' attribute\")\nplot(rand.attract) + ggtitle(\"CUG test results for 'Attractive' attribute\")", +), chunk_opts = list(label = "setup", include = FALSE)), setup = "rand.gender <- test_random(marvel_friends, \n net_heterophily, attribute = \"Gender\", \n times = 1000)\nrand.power <- test_random(marvel_friends, \n net_heterophily, attribute = \"PowerOrigin\", \n times = 1000)\nrand.attract <- test_random(marvel_friends, \n net_heterophily, attribute = \"Attractive\", \n times = 1000)\nplot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\")\nplot(rand.power) + ggtitle(\"CUG test results for 'PowerOrigin' attribute\")\nplot(rand.attract) + ggtitle(\"CUG test results for 'Attractive' attribute\")", + chunks = list(list(label = "rando-solution", code = "rand.gender <- test_random(marvel_friends, \n net_heterophily, attribute = \"Gender\", \n times = 1000)\nrand.power <- test_random(marvel_friends, \n net_heterophily, attribute = \"PowerOrigin\", \n times = 1000)\nrand.attract <- test_random(marvel_friends, \n net_heterophily, attribute = \"Attractive\", \n times = 1000)\nplot(rand.gender) + ggtitle(\"CUG test results for 'Gender' attribute\")\nplot(rand.power) + ggtitle(\"CUG test results for 'PowerOrigin' attribute\")\nplot(rand.attract) + ggtitle(\"CUG test results for 'Attractive' attribute\")", opts = list(label = "\"rando-solution\""), engine = "r"), list(label = "testperm", code = "", opts = list(label = "\"testperm\"", exercise = "TRUE", exercise.setup = "\"rando-solution\"", @@ -1178,25 +1178,25 @@

    Network regression

    @@ -1347,31 +1347,31 @@

    Network regression

    From 7251a422ad95b34f7d1f617beb9bc120cca44e0a Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 19:03:04 +0200 Subject: [PATCH 91/97] Updated QAP test section --- inst/tutorials/tutorial8/diversity.Rmd | 108 +++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/inst/tutorials/tutorial8/diversity.Rmd b/inst/tutorials/tutorial8/diversity.Rmd index 9e2c8371..7d4d2bf6 100644 --- a/inst/tutorials/tutorial8/diversity.Rmd +++ b/inst/tutorials/tutorial8/diversity.Rmd @@ -350,3 +350,111 @@ While the coefficient itself is close to 0 (neither strong homophily nor heterop all the random networks generated returned larger EI scores, between .1 and .4. That is, there is significantly less heterophily here than expected. +## QAP tests + +Ah, but perhaps random graphs are not the best reference group +for establishing whether there is a significant homophily effect here. +After all, social networks are not completely random; +they are _structured_ in particular ways, such as some nodes having higher degrees +than others, or there being a core and periphery or community topology. + +Another approach to establishing a baseline for whether we should be surprised +by a given score or not is to use permutations of the underlying network +instead of random graphs. +Permuting the network retains the structure of the network +because the ties are kept and only the labels (variables) are reassigned randomly. +Let's first plot the observed data and some permuted data next to each other. + +```{r perm, exercise=TRUE, purl = FALSE} + +``` + +```{r perm-hint, purl = FALSE} +graphr(generate_permutation(____, with_attr = TRUE), ____) +``` + +```{r perm-solution} +old <- graphr(marvel_friends, + labels = FALSE, node_size = 6, + node_color = "PowerOrigin", + node_shape = "Gender") + ggtitle("Original network") +new <- graphr(generate_permutation(marvel_friends, with_attr = TRUE), + labels = FALSE, node_size = 6, + node_color = "PowerOrigin", + node_shape = "Gender") + ggtitle("Permuted network") +old + new +``` + +```{r cupqap-qn, echo=FALSE, purl = FALSE} +question("Which of the following is true?", + answer("Random networks retain the structure of the original network.", + message = learnr::random_encouragement()), + answer("Permuted networks retain the structure of the original network.", + correct = TRUE, + message = learnr::random_praise()), + answer("Both random and permuted networks retain the proportion of attributes from the original network.", + correct = TRUE, + message = learnr::random_praise()), + answer("Permuted networks retain the ties among the same nodes from the original network.", + message = "Permuted networks randomly reassign any variables and change positions of nodes by swapping the rows and columns of an adjacency matrix."), + random_answer_order = TRUE, + allow_retry = TRUE +) +``` + +This single permutation suggests a more even mixing of these +attributes is possible, but it is just a single permutation. +Let's try a test that runs this over a succession of permutations, +just as we did with random graphs. +Plot the results for gender and power according to the random and permutation baselines. + +```{r testperm, exercise=TRUE, exercise.setup = "rando-solution", purl = FALSE} + +``` + +```{r testperm-hint, purl = FALSE} +test_permutation(____, FUN = ____, attribute = ____, + times = ____) +``` + +```{r testperm-solution, purl = FALSE} +(perm.gender <- test_permutation(marvel_friends, + net_heterophily, attribute = "Gender", + times = 1000)) +(perm.power <- test_permutation(marvel_friends, + net_heterophily, attribute = "PowerOrigin", + times = 1000)) + +(plot(rand.gender) + ggtitle("CUG test results for 'Gender' attribute") + + theme(plot.title = element_text(size=8)) | + plot(rand.power) + ggtitle("CUG test results for 'PowerOrigin' attribute") + + theme(plot.title = element_text(size=8))) / +(plot(perm.gender) + ggtitle("QAP test results for 'Gender' attribute") + + theme(plot.title = element_text(size=8)) | + plot(perm.power) + ggtitle("QAP test results for 'PowerOrigin' attribute") + + theme(plot.title = element_text(size=8))) +``` + +Again, we see that there is perhaps nothing so surprising that we got the homophily score +for gender that we did, but the lack of power origin heterophily is surprising. +Note how the distributions are generally wider when permuting the observed network +than creating a random distribution (be mindful of the scale of the _x_-axis). +That is, taking into account the structure of the network leads us to +expect a larger spread in the EI index than when the variable is distributed across a random network. + +```{r cupqap-results, echo=FALSE, purl = FALSE} +question("What can we say from these results?", + answer("We can reject the null hypothesis that there is no homophily for gender in the comparison with random networks", + message = "We cannot reject the null hypothesis since the result is in the range of expected scores across randomised networks, indicated by the red line between the grey shaded zones."), + answer("We can reject the null hypothesis that there is no homophily for power origin in the comparison with random networks", + correct = TRUE, + message = learnr::random_praise()), + answer("We can reject the null hypothesis that there is no homophily for power origin in both CUG and QAP tests", + correct = TRUE, + message = learnr::random_praise()), + answer("We can reject the null hypothesis that there is no homophily for gender in both CUG and QAP tests", + message = "We cannot reject the null hypothesis since the result is in the range of expected scores across randomised and permuted networks, indicated by the red lines between the grey shaded zones in both plots."), + allow_retry = TRUE +) +``` + From e26c4038b3f3c38c4fb23a39164ab5435aaaf853 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 19:05:46 +0200 Subject: [PATCH 92/97] Updated network regression section of diversity tutorial, making sure that it includes best practice in terms of specification --- inst/tutorials/tutorial8/diversity.Rmd | 86 +++++++++++++++++++++++++ inst/tutorials/tutorial8/diversity.html | 81 +++++++++++------------ 2 files changed, 123 insertions(+), 44 deletions(-) diff --git a/inst/tutorials/tutorial8/diversity.Rmd b/inst/tutorials/tutorial8/diversity.Rmd index 7d4d2bf6..0e1d5515 100644 --- a/inst/tutorials/tutorial8/diversity.Rmd +++ b/inst/tutorials/tutorial8/diversity.Rmd @@ -458,3 +458,89 @@ question("What can we say from these results?", ) ``` +## Network regression + +Next let us examine homophily in another network. +The data were collected as part of an early experiment on communication between social network researchers who were using an Electronic Information Exchange System (EIES). +You may recognise some of the names. +The main network consists of 32 scholars with directed ties weighted by the total number of messages sent from $i$ to $j$ over the period of the study. +Nodal attributes collected include the primary discipline and number of citations in the social science citation index at the start of the study. + +```{r introeies, exercise=TRUE, purl = FALSE} +ison_networkers +graphr(ison_networkers, node_color = "Discipline") +``` + +Let's use both the continuous `Citations` and the categorical `Discipline` variables +and come up with a couple of key hypotheses: + +- $H_1$: researchers send more emails to those who are cited more (popularity hypothesis) +- $H_2$: researchers send more emails to those of the same discipline (disciplinary homophily hypothesis) + +Let's start with a pretty maximally specified model +(note that it doesn't make sense to include both ego and alter effects because these networks are undirected). +We are using `times = 200` here because of time-out limitations in the `learnr` tutorial system, +but for publication quality results you would want to base your conclusions on 2000 +simulations or more. + +```{r qapmax, exercise=TRUE, exercise.timelimit = 3600, purl = FALSE} + +``` + +```{r qapmax-hint-1, purl = FALSE} +network_reg(____, ison_networkers, times = 200) +# If the model runs into a timeout error, please reduce the number of 'times' in the function above. +``` + +```{r qapmax-hint-2, purl = FALSE} +weight ~ alter(Citations) + sim(Citations) + + alter(Discipline) + same(Discipline) +``` + +```{r qapmax-solution} +model1 <- network_reg(weight ~ ego(Citations) + alter(Citations) + sim(Citations) + + ego(Discipline) + alter(Discipline) + same(Discipline), + ison_networkers, times = 200) +``` + +We can use tidy methods (e.g. `tidy()`, `glance()`) to get the salient information from this model, +and `{migraph}` includes also a plot method for these results to +facilitate the quick interpretation of these results. + +```{r qapinterp, exercise=TRUE, exercise.setup = "qapmax-solution", purl = FALSE} + +``` + +```{r qapinterp-solution} +tidy(model1) +glance(model1) +plot(model1) +``` + +This violin plot presents the distribution of coefficients from permutations of the network, +with the coefficient fitted from the data as a red dot. +Lines are used to indicate 95% thresholds, +but here the distributions are rendered so wide that they are often not visible. + +```{r qap-interp, echo=FALSE, purl = FALSE} +question("What can we say from the results from model 1?", + answer("Researchers send more messages to those who are cited more", + message = "Looks like alter Citations is not significant."), + answer("Researchers send more messages to those who similarly cited", + message = "Looks like sim Citations is not significant."), + answer("Researchers send more messages to mathematicians than anthropologists", + message = "Looks like alter Discipline Mathematics is not significant."), + answer("Researchers send more messages to sociologists than anthropologists", + message = "Looks like alter Discipline Sociology is not significant."), + answer("Not much", + correct = TRUE, + message = "Yes, the fitted coefficients are, if not typical, at least unsurprising from permutations of the network and so there's no evidence for rejecting the null hypothesis on the basis of this data."), + allow_retry = TRUE +) +``` + +While these are the conclusions from this 'play' data, +you may have more and more interesting data at hand. +How would you go about specifying such a model? +Why is such an approach more appropriate for network data than linear +or logistic regression? diff --git a/inst/tutorials/tutorial8/diversity.html b/inst/tutorials/tutorial8/diversity.html index 4fc1b829..770a6bb5 100644 --- a/inst/tutorials/tutorial8/diversity.html +++ b/inst/tutorials/tutorial8/diversity.html @@ -579,7 +579,8 @@

    Network regression

    -
    network_reg(____, ison_networkers, times = 200)
    +
    network_reg(____, ison_networkers, times = 200)
    +# If the model runs into a timeout error, please reduce the number of 'times' in the function above.
    Network regression
    weight ~ alter(Citations) + sim(Citations) + 
                           alter(Discipline) + same(Discipline)
    -
    -
    model1 <- network_reg(weight ~ alter(Citations) + sim(Citations) + 
    -                      alter(Discipline) + same(Discipline), 
    -                      ison_networkers, times = 200)
    -# If the model runs into a timeout error, please reduce the number of 'times' in the function above.
    -
    @@ -798,20 +791,20 @@

    Network regression

    @@ -961,15 +954,15 @@

    Network regression

    @@ -1085,25 +1078,25 @@

    Network regression

    @@ -1178,25 +1171,25 @@

    Network regression

    @@ -1273,8 +1266,8 @@

    Network regression

    chunks = list(list(label = "qapmax", code = "", opts = list( label = "\"qapmax\"", exercise = "TRUE", exercise.timelimit = "3600", purl = "FALSE"), engine = "r")), code_check = NULL, error_check = NULL, - check = NULL, solution = structure(c("model1 <- network_reg(weight ~ alter(Citations) + sim(Citations) + ", - " alter(Discipline) + same(Discipline), ", + check = NULL, solution = structure(c("model1 <- network_reg(weight ~ ego(Citations) + alter(Citations) + sim(Citations) + ", + " ego(Discipline) + alter(Discipline) + same(Discipline), ", " ison_networkers, times = 200)"), chunk_opts = list( label = "qapmax-solution")), tests = NULL, options = list( eval = FALSE, echo = TRUE, results = "markup", tidy = FALSE, @@ -1313,8 +1306,8 @@

    Network regression

    "library(manynet)", "library(migraph)", "library(patchwork)", "library(ggplot2)", "knitr::opts_chunk$set(echo = FALSE)", "marvel_friends <- to_unsigned(ison_marvel_relationships, keep = \"positive\")", "marvel_friends <- to_giant(marvel_friends)", "marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances))" -), chunk_opts = list(label = "setup", include = FALSE)), setup = "model1 <- network_reg(weight ~ alter(Citations) + sim(Citations) + \n alter(Discipline) + same(Discipline), \n ison_networkers, times = 200)", - chunks = list(list(label = "qapmax-solution", code = "model1 <- network_reg(weight ~ alter(Citations) + sim(Citations) + \n alter(Discipline) + same(Discipline), \n ison_networkers, times = 200)", +), chunk_opts = list(label = "setup", include = FALSE)), setup = "model1 <- network_reg(weight ~ ego(Citations) + alter(Citations) + sim(Citations) + \n ego(Discipline) + alter(Discipline) + same(Discipline), \n ison_networkers, times = 200)", + chunks = list(list(label = "qapmax-solution", code = "model1 <- network_reg(weight ~ ego(Citations) + alter(Citations) + sim(Citations) + \n ego(Discipline) + alter(Discipline) + same(Discipline), \n ison_networkers, times = 200)", opts = list(label = "\"qapmax-solution\""), engine = "r"), list(label = "qapinterp", code = "", opts = list(label = "\"qapinterp\"", exercise = "TRUE", exercise.setup = "\"qapmax-solution\"", @@ -1347,31 +1340,31 @@

    Network regression

    From d7e0e15daf9ecfea99d704fdfbe6ab29f4bf7a80 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 20:32:15 +0200 Subject: [PATCH 93/97] Reinstated test tests --- tests/testthat/test-model_tests.R | 142 +++++++++++++++--------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/tests/testthat/test-model_tests.R b/tests/testthat/test-model_tests.R index cb98b352..318c8ed6 100644 --- a/tests/testthat/test-model_tests.R +++ b/tests/testthat/test-model_tests.R @@ -1,75 +1,75 @@ # # Making sure the tests family of functions works as intended. marvel_friends <- manynet::to_giant(manynet::to_unsigned(manynet::ison_marvel_relationships)) %>% manynet::to_subgraph(PowerOrigin == "Human") -# cugtest <- test_random(marvel_friends, -# manynet::net_heterophily, -# attribute = "Attractive", -# times = 200) -# cugtest2 <- test_random(marvel_friends, -# manynet::net_betweenness, -# times = 200) -# cugtest3 <- test_random(ison_southern_women, -# manynet::net_equivalency, -# times = 200) +cugtest <- test_random(marvel_friends, + manynet::net_heterophily, + attribute = "Attractive", + times = 200) +cugtest2 <- test_random(marvel_friends, + manynet::net_betweenness, + times = 200) +cugtest3 <- test_random(ison_southern_women, + manynet::net_equivalency, + times = 200) -# test_that("test_random works", { -# # Set the cugtest up -# # Test stuff cug1 -# expect_equal(as.numeric(cugtest$testval), -0.85714, tolerance = 0.001) -# expect_equal(length(cugtest$testdist), 200) # NB: Stochastic -# expect_false(cugtest$mode) -# expect_false(cugtest$diag) -# expect_equal(cugtest$cmode, "edges") -# expect_equal(class(cugtest$plteobs), "numeric") -# expect_equal(class(cugtest$pgteobs), "numeric") -# expect_equal(cugtest$reps, 200) -# expect_s3_class(cugtest, "network_test") -# # Test stuff cug2 -# expect_equal(as.numeric(cugtest2$testval), 0.2375, tolerance = 0.001) -# # expect_equal(mean(cugtest3$testdist), 0.3600, tolerance = 0.02) -# expect_equal(length(cugtest2$testdist), 200) # NB: Stochastic -# expect_false(cugtest2$mode) -# expect_false(cugtest2$diag) -# expect_equal(cugtest2$cmode, "edges") -# expect_equal(round(cugtest2$plteobs), 1) -# expect_equal(round(cugtest2$pgteobs), 0) -# expect_equal(cugtest2$reps, 200) -# expect_s3_class(cugtest2, "network_test") -# }) -# -# # Set the qaptest up -# marvel_friends <- manynet::to_unsigned(manynet::ison_marvel_relationships) -# marvel_friends <- manynet::to_giant(marvel_friends) -# marvel_friends <- manynet::to_subgraph(marvel_friends, PowerOrigin == "Human") -# qaptest <- test_permutation(marvel_friends, -# manynet::net_heterophily, -# attribute = "Attractive", -# times = 200) -# test_that("test_permutation works", { -# expect_equal(as.numeric(qaptest$testval), -0.85714, tolerance = 0.001) -# expect_equal(length(qaptest$testdist), 200) # NB: Stochastic -# expect_equal(class(qaptest$plteobs), "numeric") # NB: Stochastic -# expect_equal(class(qaptest$pgteobs), "numeric") # NB: Stochastic -# expect_equal(qaptest$reps, 200) -# expect_s3_class(qaptest, "network_test") -# }) -# -# cugplot <- plot(cugtest) -# test_that("cug plot works", { -# expect_s3_class(cugplot, "gg") -# expect_s3_class(cugplot$layers[[1]], "ggproto") -# expect_s3_class(cugplot$layers[[1]]$geom, "GeomDensity") -# expect_s3_class(cugplot$layers[[1]]$stat, "StatDensity") -# expect_identical(cugplot$labels$x, "Statistic") -# expect_identical(cugplot$labels$y, "Density") -# }) -# -# qapplot <- plot(qaptest) -# test_that("qap plot works", { -# expect_s3_class(qapplot, "gg") -# expect_s3_class(qapplot$layers[[1]], "ggproto") -# expect_s3_class(qapplot$layers[[1]]$geom, "GeomDensity") -# expect_s3_class(qapplot$layers[[1]]$stat, "StatDensity") -# expect_identical(qapplot$labels$x, "Statistic") -# expect_identical(qapplot$labels$y, "Density") -# }) +test_that("test_random works", { + # Set the cugtest up + # Test stuff cug1 + expect_equal(as.numeric(cugtest$testval), -0.85714, tolerance = 0.001) + expect_equal(length(cugtest$testdist), 200) # NB: Stochastic + expect_false(cugtest$mode) + expect_false(cugtest$diag) + expect_equal(cugtest$cmode, "edges") + expect_equal(class(cugtest$plteobs), "numeric") + expect_equal(class(cugtest$pgteobs), "numeric") + expect_equal(cugtest$reps, 200) + expect_s3_class(cugtest, "network_test") + # Test stuff cug2 + expect_equal(as.numeric(cugtest2$testval), 0.2375, tolerance = 0.001) + # expect_equal(mean(cugtest3$testdist), 0.3600, tolerance = 0.02) + expect_equal(length(cugtest2$testdist), 200) # NB: Stochastic + expect_false(cugtest2$mode) + expect_false(cugtest2$diag) + expect_equal(cugtest2$cmode, "edges") + expect_equal(round(cugtest2$plteobs), 1) + expect_equal(round(cugtest2$pgteobs), 0) + expect_equal(cugtest2$reps, 200) + expect_s3_class(cugtest2, "network_test") +}) + +# Set the qaptest up +marvel_friends <- manynet::to_unsigned(manynet::ison_marvel_relationships) +marvel_friends <- manynet::to_giant(marvel_friends) +marvel_friends <- manynet::to_subgraph(marvel_friends, PowerOrigin == "Human") +qaptest <- test_permutation(marvel_friends, + manynet::net_heterophily, + attribute = "Attractive", + times = 200) +test_that("test_permutation works", { + expect_equal(as.numeric(qaptest$testval), -0.85714, tolerance = 0.001) + expect_equal(length(qaptest$testdist), 200) # NB: Stochastic + expect_equal(class(qaptest$plteobs), "numeric") # NB: Stochastic + expect_equal(class(qaptest$pgteobs), "numeric") # NB: Stochastic + expect_equal(qaptest$reps, 200) + expect_s3_class(qaptest, "network_test") +}) + +cugplot <- plot(cugtest) +test_that("cug plot works", { + expect_s3_class(cugplot, "gg") + expect_s3_class(cugplot$layers[[1]], "ggproto") + expect_s3_class(cugplot$layers[[1]]$geom, "GeomDensity") + expect_s3_class(cugplot$layers[[1]]$stat, "StatDensity") + expect_identical(cugplot$labels$x, "Statistic") + expect_identical(cugplot$labels$y, "Density") +}) + +qapplot <- plot(qaptest) +test_that("qap plot works", { + expect_s3_class(qapplot, "gg") + expect_s3_class(qapplot$layers[[1]], "ggproto") + expect_s3_class(qapplot$layers[[1]]$geom, "GeomDensity") + expect_s3_class(qapplot$layers[[1]]$stat, "StatDensity") + expect_identical(qapplot$labels$x, "Statistic") + expect_identical(qapplot$labels$y, "Density") +}) From 3679d3d41f4cd08bfbf0854d7ceca14e0ec6f467 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 22:00:14 +0200 Subject: [PATCH 94/97] Updated pkgdown and favicons --- pkgdown/_pkgdown.yml | 38 ------------------- pkgdown/favicon/apple-touch-icon-120x120.png | Bin 7804 -> 8857 bytes pkgdown/favicon/apple-touch-icon-152x152.png | Bin 10083 -> 11678 bytes pkgdown/favicon/apple-touch-icon-180x180.png | Bin 12519 -> 14215 bytes pkgdown/favicon/apple-touch-icon-60x60.png | Bin 3652 -> 4230 bytes pkgdown/favicon/apple-touch-icon-76x76.png | Bin 4584 -> 5328 bytes pkgdown/favicon/apple-touch-icon.png | Bin 12519 -> 14215 bytes pkgdown/favicon/favicon-16x16.png | Bin 1065 -> 1122 bytes pkgdown/favicon/favicon-32x32.png | Bin 1907 -> 2187 bytes pkgdown/favicon/favicon.ico | Bin 15086 -> 15086 bytes 10 files changed, 38 deletions(-) diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml index 7a57d41c..bf1227cf 100644 --- a/pkgdown/_pkgdown.yml +++ b/pkgdown/_pkgdown.yml @@ -31,49 +31,11 @@ navbar: icon: "fab fa-github fa-lg" href: https://github.com/stocnet/migraph reference: - - title: "Measures" - desc: | - Functions for measuring networks and returning a numeric vector or value. - Note that all `node_` and `tie_` measures return a single vector - so that they can be added directly to graph objects. - `network_` measures return one or, in some cases of two-mode measures, - two values. - contents: - - cohesion - - ends_with("_centrality") - - closure - - holes - - heterogeneity - - features - - periods - - over - - hierarchy - - ends_with("_diffusion") - - title: "Motifs" - desc: | - Functions for calculating subgraphs in multimodal networks. - These functions have an additional dimension than `node_` and `network_` - measures and marks that capture the different motifs surveyed. - contents: - - ends_with("_census") - - title: "Memberships" - desc: | - Functions for identifying community, cluster, or class memberships - in partitions within multimodal networks. - They return integer vectors the length of the nodes in the network. - contents: - - contains("_in_") - - components - - equivalence - - core - - cliques - title: "Models" desc: "Functions for modelling multimodal networks:" contents: - starts_with("test") - regression - - cluster - - kselect - title: "Data" desc: | The package contains multimodal, multilevel, and multiplex network data, diff --git a/pkgdown/favicon/apple-touch-icon-120x120.png b/pkgdown/favicon/apple-touch-icon-120x120.png index 24f5e3636bc6b3c37cb6af29a289a513133ec4d2..81c8d1a45f2c6d8ad27e5c4939f24d2fbfdbb798 100644 GIT binary patch delta 8714 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 delta 7643 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 diff --git a/pkgdown/favicon/apple-touch-icon-152x152.png b/pkgdown/favicon/apple-touch-icon-152x152.png index a083b94d9495a03b78acd587198cd2ce1b4ba2c1..211bc440cdfecd58cfa077f6d1875edc66046e5e 100644 GIT binary patch literal 11678 zcmZ{KWmuGLwDr&fk_v)!hYa0Fcb9;`i*!qOcgTmA@ByOiK46& zw%k@6TM_jw?l!ggXT*SpPX8pPA%j@ z*X5NMYUE07{aYGbqQPb1hcU>eABTioafHc0qqn!9Dr4bQP7R9@^7~JF?qpwbTX6B5 zQg+U>NAH$JjYbT8d8d>yKcuShQU1Pm98(_e?I9+}xjf|28p$n9&i8B){l!qIbCZ3m zT%198QI0WZ&VO2eYg}0o$}e&upqzY&@nDd+A^c~%-_Nd+tTW9)m}ti$oTm)Y9i6ez zv7v$5SyDXqHC!||X=m&6a(r!R!U$1eSp zwfOX}Je1YB%;UBqzSi-CKZuGD?res$fLr4EpPo(f-!4(4$q-!smkwL;DH*d)IMdzQ z?!P~5@%-qwGjA!mv{z-O)iJt$y_JJji2u3}B|MShA-PHaQHE#4w`AEj2P-I zha%8KdVe-=@G>!JKyPu3-THAL>~mpN*?OT@+)VIN|D1R)jL-l=g&Z1xE|PPIt~E(s zAB$-z{hep*1Opk5>|4*=iqE$%{cQZCv5y7TdVjicM5DE+n&CV|h4=#l1K?xb4}N>) z(8|aCJG+73ow>5^Z2OFdqatuNU&b+Fl*2KGcrvh9k&%%BT3S47pJd59*SaGlm-gcwr>(0PvON()aV72T4}=qFh3TPP zF?4ivcNZtlM}DnVepiHQ_aa6W*AfbAhyP@>by1uvo5@Wmjj9&+XXO*>w2CIrpG$Z< zwBNhm?37i8dqb0x%IFDyIIM_d3b>$pd3ntz(B8{U){QaH(-Sw?&Ig~JxiZ@G?fBm{ z5WTrTfRgwgGBRd$GnNqN^Vx|Xs|KK()aMuecx5@788rEibe;cT*1PpVJ+6<-q;@`- z*tOS13p$smDuN!ne&*l)$W;S-3{fdsjL*r5OGtR0szeXzSk0&`Sf7mx*1!^JCrtm^ zWyKwmR!DKdfxO%HkRmsK`wG%=b;YleBN7uEi>*9aR}f5jN6X21VnvBNPVTuHq=qw+ zUz?9&`}lBQTvjG2BO~*bRz9Gzbf*;^9eq+SN?>d(Vb9&l1oGkqc8lL%mY$zK^IOUh zVSS@c#@Hxjd}1GCvmat$Lsr(-ooQT_tIj`U1Y&(OD`!Oy&b|BKaJZU*0r^gz9=CRR zpt3bf*2>`u^U#SXMz9+0l%BE?u$tjXo&uZrAh#P@T*0oUo!D&5)&)}l=R65z5n};W_rslbQgHP&uqv0#e@W+eW z`*i^UfyV323`yb8XM^x`>4%Gk_ON`$;7+4PMf~1Af!M{jIy#I=pFdM^a2(e#%M(a< z9bkn$uo6CE(f!?SG5O0< z0&QMN3A*K2cG%)R`5&(byjFupDN5WbLPEmzrrnBX=i>$(Lk1zj=TmRhw6s>e9#quv zDL^n?1P3F&_wu@q)?=2V#O;_UknLp0{O+)Vou$%1YiFtZ5*$HJUOs4Si%V5WDQT!i zzw6YOVeE9v{ct%Z#n4}1O43&v_8-;-2=;t%;^X7vfBB3L-%3kyKp5x+>qVJcJ|0ZX z%>3D&D41*Wdjs4p@ryz}VSH}xW3A;_*ZMK$k*CRZ+G# zMh)zgv~P(O{%0LFw49ccQ_0N6CaaKt2Whm@&C4fR*UA^&Q;X|jBzT6G|lm)<( zqif$}aApkMWILfT4;@%?(0>lC1Z=Hm8gdKnbTDSDi$Uhf-1>R~aA`>bt)HRRbY)LZ zkCg3l%d6d)ZyAX*7|wrs&@+X7UN*b$OITP~6gNX5xYBr7SXjlSrNOhi!hNTA0Xye6 zMN;ann;RQ>`T5jS%9%VvG9kkEXOn99VWvbD4FJx#Fi+FYcV~BphK4?6W(rltcWrMo zid?NCeJLs`sH<~T?|Ob3w9ZdUM@JB5wJ$t=JE0{c zBuFexM^VG6LCS#mN68tR1&3xk^S%f8(ER-Q^D2+SWi`Izn$UVwpUpH&F{Ta1!Z*_D zzR||1&8H_Pm>U}#!0SJ#VLBa4fR)jYhkkr5H5W@ihUnutYmDkHY8AIEpk#|CTm3~DW~-1iphOUZpSh)2DywAx;O^Xa zmlY(9%`nq77^|^Wl$Rek0vXe#k`Wez>T|u3GO@CPQ!tUr2>;`OFMU1K-`~HTJEK>8 z6g0cr`=PQGRRVg@xQ37BZJpY zLPcdX7)^NJ{S7v`(8ttNqTk-T-&Vaul9mkF@BAO@c%LC7k_nAHP8qScP|7FpO)bF8 zi1+3#b5OwfXiIz*J}jkVW!WuMoAw2NU@>z3He2$xh@G1|w5F!Ue0^>VHGAt*LP9Xe zjYj?EY=}1{IXM=@eb_MHf6fykzE|uZ7ISBJ*QM0&zUDKoz(0Qc$jrhb z4eDpU^=Fr@(Y5ngLs@O@m#<&H?xHVl8o#>te{$6K?=OSIa$~lx1NewA1LA218a~Xj zmh0A9$S>A@`QLMfeYK8egfAimbyPxpnV6Y}^wrgaqNAgku|@SUq}3hw<~Xi=MF8L` zS9TjlBG>CmNFeI7zKfpx_nT?RnSQ8dq+!W@an5B-xZ%r!tvvT!&f}dWH#c{O5ql3Z zVvqwP{KT$on%GcJ58l$!B7GUQu(06xw;wMlIoSlnkmAHfRmaw89*9dfH#c1A>M(Ft zF5(z8TKN-E;BduX;nK54W5SoDnp)|1b7TDDrGr zn0+V7>Na$@If3@E%cL6rz0ZFAa5Bq(M%6km>rKUpiHXOjrb55{*FX)zU;f~g3a$h$ z2#nux9dU7Si&E+>PD@R0Dj~Ub2W{uP8}*WvY|HnSHys6Rn&JgXyW1Z2xaQLzb?yJ; zQ%?0XnihmrAEu)G`&nLZ{d<$;KU_k>2D6Y|S3#$vRq@mji@o{UtYYGj4rq$d+mxVVfA>YqO*PIqQ8#~qK+ zzSGQ1hL9;;(YH!7T-HdA%zd$OmNhg;Nopq-ib^KAy!)qI|uU@1X?FaOn$ZD9u86KiPzGS zc5~xlEUcQhjS~5!6N?*9=f%$@L&6gyQIOjhoXC=#-qt4K>h4Z0DoO!5o;-UM&l)L* zhhbt{jShB)>-@mkt+2(7&{CGR=+aU+C~7LI6Yp7P3CO5wpHqc)Y@CGH5WoEImxU!Y zlh_uMF=%F7?~t2z5Or*?F>aoVCw>W(rgDgpg&zXWIb@4Jz&FKK1_gW$5y zp)g2%n4E7ZC~>W=t&A|3l#LUH>!NF`lSLyi-;-iPCEUkw-;XlmkvY(@n(RjMR$aBz?{Hl~`X zG!)$uhL4Pl5RsAf#*)2x`R(t9LYO%;pXLm*P3J*&eeYjfN^iZ|cU%oOhD1ZgEnISd z%lc|_lf0F@AE+SSv8K?m>Z)y?5Uu?HY7UNrg$(-zj97EF8**HT_GzD@Ih0CHNl8jy zpY-J91oUuWaUwU+Z{NN#va-rpSZtOj&+wCCgX%<0M~9-TtE+h9sEznZTe!_*g@;gi z1rJjCb#3ghHNpj{8w-Kz_Je)oWo8O_3S`dm=^%TAqKs(tg>IBr%`1-&0#&dw3X()$ zdNN!>^VCyvnPl^7ixFbbspJ9kPft&K9=2YN|Nb2fCX6qIh3`+&lQgELr#lZXLAgf^ zuBuZE(nf?y;=ZtM{JX-V93qcH#4iy4dC!U=(C6@dPS&a4=8xLXMtS+|!IYG2Y&f7h z7gtn#X7k~L)76o2`TORVyct*^({j>ZVPj!EHMVJKX>!WS@8jLeot+rzY0yuXT1e8p zKM{5sv3FS18Uv^+uB?@ z5G)7UX25!$l#R-cDg>XE#@6+$}xp&7!$u{kfN_97QRCR#Qt$ zymGdnxOltfVfwnH2sCftr4hmNy1_qqGc?N+6G0CT{{^Y4f= zQ&Y&zOR*#lEywW8^Ji~WSy))W6elGvj=*a>S7qilSfSme(Xr?LW@l$7K0UpOlEFzo z)w{H!;wKm$zcL`s&(E_HVZQUt(GpPx9xCM4p?U=xy=P4`yIoUnwX_Ig$%WyYn-+7n zydad^dCpz&DtbOc-yo2Xl1hOvtEsIewEITb=QR0Y0Ju}_?b{HKWiK>qYimX(CUIxy zlO4|7XF3sne`M!GM-@D(MpIQh?&k&#ghl&JLdbnUmQDaO*U*?$KIGN3(E zP*hB*OD>zYHBc62d2UQ&>Z7h@*)Z3$tAME-Z zlZpfy2)nzx8QFy_Mb7J;Q*Xh*cotm?CS(v*jIUomb)s;2;ZFk+w5JdL{m4rA(jbaD z%{cR_svLFGQ=$s9pXQ#ry1Me>sTYMwus00tt*vBRqgmZM2xQQ6U4+&e_F9aw1fE4FnV4vZtx^m+a)vs2_k`zz_ju38AfYqoJVB zsor|LKl+c4oxmhvNU-sfO-UHw)O)v*B07Sq)tB7z2^Hzi>sv+HH@COy@88D&@U-%# zt|E08W+9<~>DUV~Fra~+ThVJb-lhI)c5=DwRtkw>f4zYzwkXtb-o`H~GT(-X^fZ4f z^F=~_{$08&`*7jPRT;~9of+cH^mN$rvVrYFoptA6Oj&983WW^>;=8pRV>DkFz%G7z zJX6iOjq-9)ak67L|7LwU!CUV+!s)dy7$_yo%xItD-e}fb2bCb>SDrd?O+&UhRAYVQ z5vH0+~DMDj1|P-mJ9KcHXg`K(VdZ_(`W5 z##jhb(r87p$U~g$B%X3`4C#s0ivcw)tO2LZ0UC$j2#vm+x#~T#B*x<|ZzH^{Qyrsl zJzv^aLUkuVfe0NqI)(uXnd<1qJX+w+h$#3A|BJJ(y@)H2j&5$}HLAiRiX9faB*;TC zKCK3zUw`i|cyK&mwL{()@%bK{4S%brz@tAb&IYyWKApQq`W3s$eBJ8OTj8oVNLM$OQQ!;m>%IwmF}>v|Y5f|b=Fj+> zzg=aA^=sd2U}lBVDlzD*u2IF-WI-}avG1}ZL!~1s_gF&JMfvjhMbD>}mt&vMsVIAM z7iVZ>*%cUP`cZb%psP0K9k zO$Pl44!Ul{c?2v?>fMe+<4*DG1&nb(QSAL9qc>`%TnrzL$il}wCpL{gEd5GRQrA4z zz@b7uRoJX?{K8kng^YudlGi-{<_yxq-@1itzj7S8&D(Jm1nF*ixZFBvDcpMelf?6K z$%AmOyr|b=f*TZ;S=*tQTA273U9_x@E;D>FC_*3S_%1)uxsYcpN+G@l4UVB$P^tP6 zDN?p+N9JsHHUgn%Y>*1ye7#&5HiEqPXu6gDf0@B+PHdjp;u_`Xy4Ihrnk((WU5Xtj zLMF+8co8i`6i!L0oV+>p4CWb|#v2)mJ9qNjv95+0PQCrll7w_{F)6$mWhdp>g|#uX7rTdAt_Ewm-#9&P=W#cpE<7+ zy5FZ`MOLMwOnr|v8D8s4os3&#t}z;SO1U>U%zehzHi?l_Ovz;L{M@NcO*z~1_?RuY zXdM0buW;E>RpI^RRua%}7`N_P8xTjE&ktefeE7hOiiYOYjm1YvO>N@j!+!3LC$V}V z55lu|R`e~hZd&H`l0kB0WARYs94;L}0RQh$w~|j)8$S!`7e$!Vx8$h`@k=j`5lp+? zDfpAcWd^A)51+$QrY2kTD320Fp1XW;V7$xFb z_uaValC+}z!MlfHc=5&mN5u4&5%&>56;+J5FI_e>owm<$ zjc3GH8I=7^`-nzkJmb^IQNq)vK58ch1{VLZoy7f>08`_Ee;sw&b|XE2jRlMM75H?7 zIYr>m7X(6g&4en-R)98wYdsAz6q;4lXp92rmDJRaprs2o*9FsM{*NDk1Vqy=BR~x? zmN6V;xSkOC6|vK1F_rZ}a@PpwcTIpvpiBFAOKKO1$IsMz{fj4&hj)J&M1Sn@Y|*CT z2tQUD=_V7<9n)(~wyE-bQz}f)RmXxLj5*_KqW+k{_qDqu#5K=uz0P&z6dU9;y9s>{ zw|>UI4>R1elz?)_$p|9EaTAgXxGNjf*LD|O$$Yyx1JGmOD(Ov9H zNJH%H9NTAO%%wXIBZQBaeTdv4w3De(~xoTInZTyB@L)-H&zK;9HEN z!;rH(L3ng!HV#B6i#$ABBhel0)pb;3rae4%d_*hSiE#9j$4FRb8Asn^KuvCy%Lwr^ z*0mT&oC(Dxije`N73vf7>?verV9rjZ2}FZ24{ESi5T!Y%uq#_DPM*Ly>Se{?C5 zN-85vqi5VkD+7FMiHM4v#fcATsBx;nrT%--WyI1e@g(0{u2g%5Hof;zV)$Tqol}#e zS#PQVodyo)d(?@>@4Ahv_uqe1^3Runm1jS!L@+8E^%wRAX$&%#o)EMXU2RSEBQM>L z-F25Quos{fB>hqS?9gpfW!4Wr;V$uR)^s+wW2!wu1J`bv#z%Rog*&pFCcngm^gWWw7dl-$>*;{kfAJ2$?6bXXWoBVPO-+r6 zgoI>eV=J+1MEKxaLF})axj%=C(Ih^TWTU0^U)BW&sqaDWkiW4E!s(Wb(Ud4cvT<9n z%}xpjTDx)q@m<2lkyj|I^SuF#*67+ve|uF?)zOW9oysZJQBwWncHp8LNQ}KXCwU9d zKGa}!GpPfcAvgkVZebz80Oemcj1V8-csIfd2_1=66z2cyX4MB&t81T8SDwgEpR%gL z_sJ-J#|o%mK&kk*h<;Wr#zv?18d59w{~eqO(_gaTL9a^Jo=ID!Pei}&4fFIn!er-! z{~(Y1W@BS~c%{buL{Ysdz@fLs*b^!GWa9qy*cS>#tO-S5xqH!82E+E(4P{=%DENaXgb-x1+GMoNg$wKOQ)d0A%F(&es%bl) zBYg;UleVLOj}F*)ZeDJa+(HtA-ow-CL8TW0Ks8wOHn&{wNKkwq1MG|i#C2>AJ( z%)?=Ur|fp*+WPTm!_Y)h?`3R#rn0u?2CDKTuT5?>CQ&5SmoW1=92lx8*}jY7b@Cav zI(~az>CQW4`nM8*N&>`!w%NefjgFokWI&Gvd-d~XZ&6I_p5M|V+RIu-ryxslNKV%6 z6Hmh#ait+RR7x~sHL~BlO{2cN-l=RmS{GP4g-;FS=u;T!6hXdWo9R4XO%`fo*h>D_ zE_yo5HU7`Fd}w2Vdgx?DL%|^?E^ZbO`e5Xwfoba-V13O02u5ekckci_EvS?1CypB` zd(d`!Fhe67yLt);^fSx2m}v=3>1Z_lkDCSJVpTNryoWw)O|8Tf6n#NRXt|UBh5->? z3v_6#KBq81+?cKZjQJQ7^PVRoD)g)M_Tizdxj7vGs3J9m6++}SON-j;u>{%y!~30g zgsoVL7iNaO$I>l8Xq{_v`_M!yzoMyi&TLUD&{kE2dwqRfX5o?yb_xDXm!!N=bTKhO z1alrxmV;>J_kq}v0))in^==D(%uLbX4%k~b*S6g=o?X}5zdTm%S* z-eUl|iG!aXn!Q!+wEk0dKN2&&8%)=LL}M7LxkVB8G+X>`Hv*Xd#;t6hYURWB zM-gHYlDx@(Fz^-G%yb{f`<$N0wn+<@&#KR%$m26Js9;Esj6^rHw4}j>0&WVSu~9lVsC@Mk&Bt?>jl#GlC za8Z>GES}cd+nwJW`;iga)&1kgj}Z|4XAifBIBtYpk{ysI#aYJEk^xz~>SMlV18itz z-AhE2nK>#cDM_Ee;%zd+t_~1)>KYnMZEZ0Df9J?g3Qi4J%g|0EF%=c;o0}UoUEN5) zD1~X

    r36@}(&~swQv5r*%i+@glx7TWRz21ajojk1;>{Z@}{!TIWMAqv*aD7eh&S zZFMFr00m^?4isGja80~j?zD|Q`$=Wn$f`U>&He$Mo&V8oQg{L%Au^QD|fUE4dD0G z0p$ny3r%h9{K`tzyd?51uLnz+f@3oIgfD0mzU)&=jWA;tBk_yFl{lY+A84vV$324b z2@inxGpx~paR81=r``X)hASh17PuEkHJI4gU2Be%yu2^HTgkyl@i8(osI=7ahdyXi zFtkVh{oz00$WplkXh6)&$k@Ts@Y{JKM%OGk?Eh>;1x4I)Z>~%+zm9;|D=8>E2NCos zJG%`w{FM>T?{Pq?k}VXuThWXSN)~Bfr%5&C>(>~9S=e9|0dQL&E5S;PeYo)hEwqab ztXmL+y^$^xcmDs9KL;WtTGRqo*Sl3j0>76{DQ%<$sH7l@D1nqXr3`e=d@*%=z-2%A znuCJ_sPEO))lc-LtB5&HJQiIiO-!s^AuX7lfR(~e3EK? zt*x1U{rV+g&-tW>Fw>b;+9CDt*fukD=o!vZ(izVAC3Y` zHkLq7xd+P!HJlNIrt{B;AT8%J|7~w?2O3ny;Y%Nr>n67|LnZ7%=GgKsCZsDXFhq^J zxw`|WJ_#d$BM0E{F)B(DU;?r@*x~|h6~E5~%-h>rQ{kU1Ktuh?*>(c%2xj9~lP8Cr zUVDoTIG4*lY}vji1A9!h*S&zAECzDh-;E8Hrui>Pf6o3*uJU68RFEma1GG1Q1f2%^ zC07nJuxu+h-aiY&qQPgZ(58F?}-lj9Ie10~48 z|6LQ(L3maZ@aVs{Q2#98W-`Z_R{o}#xI`7eEhg18WN>Ro@GSsMkyXUgx~28GDuYPsNUyv@IQWUEx4HZ_y~D3>=taBkVNh-x>FpRnjdP+ z>4FBx_UNp=Jgsh*KC-8ZGxd&-mBs4@Do;Gx>#^GdUsI&q{V@RyYmka?Q?3! zLtbleZ}wvZoU6x@+q>fCw!iwHLE@GaWn+x;IwS#94vpVem#_XUU;S)dWNR;u1z9?D zH2Qf$a7SaGEYZp9vD0>dW+f-rzGp**56;ES#GDm22uOjF5!iXn%_OKHRC;(Dx3_Co z8LXXYB3qyG#F|X(`g12l@i3ca&2=wCuU12tsdc>R^v?<8?ZL91@9p9WswwVXz=r?d zPvQj*k1Ymo5HbJxIfx#3J*u|xUr~5(=am^W25KQ>Z2ow#_)X&XhPL$eX=}Iy53d$s zh`kr()Dk+0Hi|9$cOyTeCYW8buMI-XiBdXTh|*FUqAU2H-fIknZleejbxl2&*z^@b zr;@Tje``8J^2uBU)6JtR9Nhemp5klQOi1j83Z8_`=8d0(98#ZiA6787s)z@u0sr?A z!ix^#p`D1$vm8IG_XSvacU-bkVexhu4p_esZHI3YG}x{aoO@0p}Vm5XKs95a4m%9z)7~&h=f-2Qt|OD zHSTF~ruR4<@TeY;yZ59+_fzG34@w&5E0yh6ae4OsbJfJfKaf|h*W0@(w^P+Gr6Nmh zF5fCRosj;^Kd2`1D@n~`x)b!b?ALj!_D z^NiK>*$bK%ii!A0FDRt~xx3AfXlgYnhvugGdxm>Rd(egg<#H8RAv=V4t|t;apTS2! N_9i3QA%v`i@R5Wh8P~|p%3j%f@0ImE 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 diff --git a/pkgdown/favicon/apple-touch-icon-180x180.png b/pkgdown/favicon/apple-touch-icon-180x180.png index 7ccc1790bb2dbe0041834c97f771e0c7798bdfd3..04edb8903b0a75d0aee05d3cf7710076d15a15b2 100644 GIT binary patch literal 14215 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 literal 12519 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 diff --git a/pkgdown/favicon/apple-touch-icon-76x76.png b/pkgdown/favicon/apple-touch-icon-76x76.png index 08a78d3bbb6898583bff144b88cb26bce18e89a1..d810fa5db82507ede5b522bd8430405e0564c285 100644 GIT binary patch delta 5148 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 delta 4361 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 m^mPw*({y7FgsbOi@#{)eK0p91}89N+`RTtr?3 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 delta 858 zcmZutYivtl7(VOSrBj=*OUlZK*bgH)>xS76%+^`gS+J5>I!?E4A%;YX4N2X_L@c|+ z4=gSvVT*~4qCZ@!hM86`c4;k*bzN{)+S7Z_#Vh`aCr|Rd-0921&Eg=kqz8&Vhje=n99!kw}DL7%1SX)9H5Jrlnoxuy>R=QJ}U=><731Hhmp zNrHjbOWIxLa5Oaj&05o)ap>_ni%V~IzB#NZtmzgs_T?zxizW?X1#X_1)PDtiR^bE^ar$@`YU?4`K} zyymM{xASGPFZaB;ribK-&)c*|n}kix(NLtY(LampORmKoUz3v)A93dK(-*wd@d7h5 zB?_ssyivegYk$u1B%T+a#Iul1hu187gKIqq(%z1yNrcO>yyZE0QY^nfm{)-1XJc3a phF!0^F$rlbQHrXR3c0erVDEm#?uKSWhzbAS@F{NY_I488{~J}T?F;|_ diff --git a/pkgdown/favicon/favicon-32x32.png b/pkgdown/favicon/favicon-32x32.png index 6fb71c3948661cd466ca4b0d44423c72bafbcd42..18bd1b18767050c9caf8d3edb7e71b2802d4d62c 100644 GIT binary patch delta 1982 zcmV;v2SNDr4vP_xcz@^z5)vU8{-TQD000LpNklGgNS^y5!{)dGHE z5&byZ`@|Q2`}XgISAX?-O~Gp-(A(RK;o)J_DUKD-%fc@MviuuCl2(g$d3C_$diNW8 zdY`H|0+%jbLVs6RSJecBYK->o-3tJs&*yu(XTydgYuekNLtVYx_Uv;Aex(n=-c61b zk92HOy$!u%qob2kQ&SV$wr!(OC{$B5?n6&c53XIihQo&sHx3RC?w^^NNm`ag@pznK z@i^TJ(=;g(i6lay(7uBQ5Bfu)5IQ?M|F;V4-n|>9X@3gAVDJkYH*S2hv$J!%s;Umd zFraA~mInghd|?L}V{p6OiqGf!ysE073x~rKqobqY?c2B0;NW0&S$B1H;o`-MICSVx z;QaaXKaWPEnrWKzSx!$+lcs636e^VpMIw>gp-^bofddD8XV0ERTU*%V2;7pa_6Oy=VY{vsg0Tu!uSt1T-{0($TSIRRiM!DwWE-vsf&K`uciUmNh>U zmVzwHykpIp&9epDdj5~$ky6QE0B!k@-mCC?7zev07L)~O>1E$M1VyEkJ}BG+XK!yOw&X-9LB0u ztKe`rs?PpyamKSVU>LjaOz3{%>!?_a1S%)CZ1i_OwW*_FZMz?paskO?3O1V!xm*sM zbAPC+I`6QS7Xa)w0nN+Z@H)+p!qMzrg7hy@fC&IN^5$WD=iA?M3=Q4*@NOmN^LZK_ z9i_{cFHh zX?VR}xZUomhtnN9B3irxLFcC>(byGc7u3U+9I*mvq0!2~K(9i%;e5lUn2(UX3 zV@S>>;c~ekNfJgT6NqUAhysJaIe$2xV=vh_^11;cK(-6W7YvL~r}5aMe$?03!|iq> znM`7GauObo2db(rSlx5c<{b*&w+iQ?RTcS=w_GAsg0 zh6%q{f#2(dWD}s5Drj8hf=^Z8aogciBrpbW&Y>s@+-^7W`8+gDgGGd^Q-4GF^UaGi zspKxjST6kDjS$3&Sph^QTPAzu--*%HAEzT|54K?K@;1~tIqIBtFfh0s9D2!yI;R~r z8%MoMfnsN29%c&LMCP21bl=2B1s;fdJ7V*^$w6 zC4mbs6X>5#NEw$UJ?V5gzg$;WXRq~|eFt}wN+naeEymtgVEe1iN`4N0(lpJ2WA1YD z2{`8%7#P6#__(X5r{`9}DSOKv*TG%1-((yd#!=<3z0(R1g{?K^t( zXpo4oWy_XDV=cN(Mn*=kXU`sVcXy}HoH_HM$K&~%Wm!I1mRs$1yLfL~hzPo_BNmGx zl}Z&8iNt#o6B93TO9*x1;j1ePqVD2f;u7{J)rn5(C!=lQm_wjVY% zHLa8E5{sm60{|3AnAJ4O<#N}f(dcW}uU|je)YO#Uv17-Qx2LLm+t=5JQ>RYh`0?Yd zUF$#fLP|FJ&kSEsLBLaOpV7P}`>~t1hL803_fPfp_2KmC(|=X@ty$tPzw%Q&_K}mn zzd3WzfcXLdh~S66`GNn%v+FeL)xAHf$)8x0HGq%18OB@E76X3Ii9G{=5yKze{!-kM z>XlmE;Xf`k&HIq4AV~lK03~!qSaf7zbY(hYa%Ew3WdJfTGBhnPH!U$ZR53U@Gc!6e zG%GMLIxsNp1vBQt0000bbVXQnWMOn=I&E)cX=Zr_YO1000IQNkl_S)W&vfABo*la%Z3I*mu6Wxt-medHLbqHBKGd=YRB(R=e7reV=FEdES|q zVUr-D%JZv?;q$dXWXJZSAWd@a)?aJ)9>DGkmp2=(0%NlS8Dn6Kp|`ge=ZKj3X!kc& zsql<)#WQr^`(JOra2aRLoT*v>+w8!$wl?(j^&ykV)b7~1^9Uxd{mTE~N}O{JYhTB- zw`1oYu1`+>y?^O5O~u{qyQ>zmF3z4ki-v{S?$XlI zs}mCwUj~3vr%v5JadUGs5{U$chK6d=>GUs4rBafJ$aP&Rl}dCswALhqxSmR-p6c)K zkBp9vZk@cmo|BW4Us+mOIu`_iBqCBuQ9hq1tu@^XzJKq#i;Ih|jE|4+CL;9o^lYBE zrltntK3Q>7zo3={w1U5G19fjqp)661Q&MI?~tI7ruJ+>Y9A)=dURMVA3Z? z6EkEntDZl&@Wtll=I3Iu*pE2pc6qQ;3a;xS8jWsxLO~F?`F#GhOeXXDX9rrRYGW~O zFwzl+Nq+#uwFW>4s{k(sn)Y@+7|zAx@h^o!p@$e_tLoo%U09a2>fJ^#O*2$iSN9Xg zw!e082b*{|Ma|qmLUBCJfIP=aERzWPwZ=DWZh$C&>$S$`JFSr9@X7K_0&&8o@EXm26REc?m- zEf{YCOo9P;x;Mc1TYtmDk33;yv)R*SrwbvdP$-b^`y{1Yv+TBlY&Ls(|M#9S7B2n{ z$6pU%{HdEGskUQwwEyFD83w}PFhZdaq?A}*UIyoU%QL?lsrTQaD}D$5_$XihEHF(I zrhjQ791cTDiBhQqt@WoSWW@vPKq&>K6e5ubfEDwVN+od4VcRws+w@U#Ppq2(DP@I- zF$UYVD`JEY@I0@olB`NV5CkA1SeCWwJ!1@x;~*RkLn#Fz1cD&gvVeOofs_)C;{f=$ z8M!m%Wupec%AR2u1{}w!x=hy;;CUVxV}DReRW=~QFu*y7)*6g47{*HSa=9D|g#zO7 z_$ndg?^O#RBKW=!&N)U#Mk+qwoI@!EDJ7!OD1;D|GL=#y6bhlGrKMt2(=_2Y&W1+i z0Ki}X+91XlJkJB?9Hwa^5{Xpy{#-5x$8pfu*a+LUQ79B3gg||LJ)+TQg~+ljaDUF> zc^-riYgddiRyfN7{;N;p&~F;7Txs5JFdslPvJ!CDu3eRXZr;2J%d*ha)C9}2(AwIH z+1XjNwY7c1A7!K3whbvIgb*KP(L}*tvb%oUXkXDMB>@ zxln7(PH3%G1+A^EU3C_irir?`x_?#VT5Awd^p@$jRzylV8;E{_?;O6n4X+}Z+WJ0y`CG+p+NaB5>Vu} z8N$r+bs2LSpSOU4z|-%#QvM(oi#}=FcH^fZKuS4Z5XG0Jly6vu^DTp!!+&El|0(W| zAN*unJ}@wVOeVuSIy%0yZQHhAN2Ag2nx<)Og*XTTSu7U+ef#$97X}9h--*ZLs;jGO z;~x(nK8)GfSqu*k*QL|xW5r@|V!bBxZYZU6u~-~QrBX+RhK6dUrlzoW-`?tH@bXJ9 z0RYCv#=fwyu<&Oo<>E%&kxm@l- z5Cq;Dt+>o)vv1tEapT)3Po6X{Uc7k!#CM{*yBl+Ja~K{TuAiBi`9&_jn7EwmrOU}) z%I0rhOQ+ILUAlCsCYem4v$J#4ajQPidwP2C_Cr6ze(%Zdslt0_0Dqt@`qjriwEAD) zckNjmJ9ez9cw6cyj{aj00JIU&IRIeH_%T4qzx;5l>RA5=ojV$vTDOJf0000bbVXQn zWMOn=I%9HWVRU5xGB7eSEig1KF*H;#I65*kIxsmaFfckWFa|HGQ2+n{C3HntbYx+4 uWjbwdWNBu305UK#G8ru}G%YbSR4_O?GBi3cIV&(QIxsMIauV&690+fa;xIJ; diff --git a/pkgdown/favicon/favicon.ico b/pkgdown/favicon/favicon.ico index bde0d26d0333b153b27afdc73112d5af367039c5..6982eb34e8211aa173a26b9596140d3fa6ae33f6 100644 GIT binary patch literal 15086 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 U)`Ofit}dV)fHr80KJbVBKbPuRssI20 literal 15086 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 RfzUoOpOJM~mu=_|{Xga)CCLB) From e4caeb6345a7297f521abf4118adabc5784e5a57 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 22:01:13 +0200 Subject: [PATCH 95/97] #minor bump and updated description to match package trim --- DESCRIPTION | 19 ++++++++--------- NEWS.md | 47 +++++++++++++++++------------------------- man/migraph-package.Rd | 4 ++-- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 7b4beca8..afd0d4c4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,24 +1,24 @@ Package: migraph -Title: Many Network Measures, Motifs, Members, and Models +Title: Univariate and multivariate tests for multimodal and other networks Version: 1.4.0 -Date: 2024-07-08 -Description: A set of tools for analysing multimodal networks. - It includes functions for measuring - centrality, centralization, cohesion, closure, constraint and diversity, - as well as for network block-modelling, regression, and diffusion models. - The package is released as a complement to +Date: 2024-07-18 +Description: A set of tools for testing networks. + It includes functions for univariate and multivariate + conditional uniform graph and quadratic assignment procedure testing, + and network regression. + The package is a complement to 'Multimodal Political Networks' (2021, ISBN:9781108985000), and includes various datasets used in the book. Built on the 'manynet' package, all functions operate with matrices, edge lists, and 'igraph', 'network', and 'tidygraph' objects, - and on one-mode, two-mode (bipartite), and sometimes three-mode networks. + and on one-mode and two-mode (bipartite) networks. URL: https://stocnet.github.io/migraph/ BugReports: https://github.com/stocnet/migraph/issues License: MIT + file LICENSE Language: en-GB Encoding: UTF-8 LazyData: true -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 Depends: R (>= 3.6.0), manynet @@ -68,4 +68,3 @@ Roxygen: list(markdown = TRUE, roclets = c("namespace", "rd")) Config/testthat/parallel: true Config/testthat/edition: 3 Config/testthat/start-first: helper-functions - diff --git a/NEWS.md b/NEWS.md index 22fbc9b1..99b80fbb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,45 +1,36 @@ # migraph 1.4.0 -2024-05-23 +2024-07-18 ## Package - Updated migraph logo with stocnet address, colorsafe colorway, and larger nodes and ties - Copied thisRequires() helper into migraph from manynet +- testthat tests now parallelised +- Fixed precision issues in testthat tests +- Declared global variables `.data` and `.graph_context` -## Measures - -- All measure functions can now be used in e.g. `mutate()` without specifying `.data` +## Measures, Motifs, and Memberships -## Members +- All measures, motifs, and memberships have migrated to `{manynet}` + - see `{manynet}` > v1.0.0 for more details -- All membership functions can now be used in e.g. `mutate()` without specifying `.data` -- The `node_member` class is now categorical - - `make_node_member()` now converts numeric results to LETTER character results - - `print.node_member()` now works with categorical membership vectors - - `print.node_member()` now declares how many groups before reporting the vectors -- Fixed `node_constraint()` to work with weighted two-mode networks, thanks to Toshitaka Izumi for spotting this -- Added `network_independence()` for calculating the number of nodes in the largest independent set +## Models -## Motifs +- Added `test_distribution()` to test whether two vectors/distributions are from the same distribution +- `test_gof()` renamed to `test_fit()` to improve readability + - Split tests documentation into two + - `test_fit()` no longer measures fit against steps where there is no covariance +- Fixed bug in `test_random()` where parameters were passed to `manynet::generate_random()` instead of the original object, which is processed more intuitively within `manynet::generate_random()` (thanks @RWKrause) +- Corrected that `test_random()` returns results on edge-conditioned uniform graphs, not size +- Reexported `ggplot2::scale_y_discrete()` +- Specification advice in `network_reg()` now ignores absent ego terms for undirected networks -- `node_tie_census()` now works on longitudinal network data -- Added `to_correlation()` for calculating the Pearson correlation - - This takes a method argument for "all", "diag", "recip", or "complex" - - These are similar to functions implemented by Ron Breiger and shared by him in correspondence - - -- Fixed bug where `print.node_motif()` wasn't printing the requested number of lines +## Tutorials -## Models +- Added descriptions to tutorials +- Renamed regression tutorial the diversity tutorial -- Several improvements to `cluster_concor()` - - `cluster_concor()` now uses `to_correlation()` for initial correlation - - It still uses `stats::cor()` for subsequent iterations - - Fixed how `cluster_concor()` handles unlabelled networks - - Fixed how `cluster_concor()` handles two-mode networks - - Fixed bug where `cluster_concor()` cutoff resulted in unsplit groups -- `cluster_hierarchical()` now also uses `to_correlation()` - # migraph 1.3.4 2024-03-07 diff --git a/man/migraph-package.Rd b/man/migraph-package.Rd index fe13b768..d0f9c796 100644 --- a/man/migraph-package.Rd +++ b/man/migraph-package.Rd @@ -4,11 +4,11 @@ \name{migraph-package} \alias{migraph} \alias{migraph-package} -\title{migraph: Many Network Measures, Motifs, Members, and Models} +\title{migraph: Univariate and multivariate tests for multimodal and other networks} \description{ \if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}} -A set of tools for analysing multimodal networks. It includes functions for measuring centrality, centralization, cohesion, closure, constraint and diversity, as well as for network block-modelling, regression, and diffusion models. The package is released as a complement to 'Multimodal Political Networks' (2021, ISBN:9781108985000), and includes various datasets used in the book. Built on the 'manynet' package, all functions operate with matrices, edge lists, and 'igraph', 'network', and 'tidygraph' objects, and on one-mode, two-mode (bipartite), and sometimes three-mode networks. +A set of tools for testing networks. It includes functions for univariate and multivariate conditional uniform graph and quadratic assignment procedure testing, and network regression. The package is a complement to 'Multimodal Political Networks' (2021, ISBN:9781108985000), and includes various datasets used in the book. Built on the 'manynet' package, all functions operate with matrices, edge lists, and 'igraph', 'network', and 'tidygraph' objects, and on one-mode and two-mode (bipartite) networks. } \seealso{ Useful links: From d5e8d7eb66d84e81d5f24f220ddd68ff19f544d3 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 22:01:39 +0200 Subject: [PATCH 96/97] Updated README to match package trim, added alt text --- README.Rmd | 118 ++++++++-------------------------- README.md | 183 ++++++++++++++++++----------------------------------- 2 files changed, 89 insertions(+), 212 deletions(-) diff --git a/README.Rmd b/README.Rmd index a60d7c0a..dd79175b 100644 --- a/README.Rmd +++ b/README.Rmd @@ -20,7 +20,7 @@ list_data <- function(string){ } ``` -# migraph +# migraph migraph logo [![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html#maturing) @@ -48,9 +48,7 @@ Translating between packages various syntaxes and expectations can introduce sig driving confusion, inefficiencies, and errors. `{migraph}` builds upon [`{manynet}`](https://stocnet.github.io/manynet/) to offer smart solutions to these problems. -`{migraph}` includes functions for measuring networks and their nodes and ties, -identifying motifs and memberships in them, -and modelling these networks or simulating processes such as diffusion upon them. +`{migraph}` includes functions for analysing and modelling these networks. Since it is based on `{manynet}`, every function works for any compatible network format - from base R matrices or edgelists as data frames, [`{igraph}`](https://igraph.org/r/), @@ -63,19 +61,16 @@ and uses the most efficient algorithm available for each task. - [About the package](#about-the-package) - [Package background](#package-background) - [How does migraph help?](#how-does-migraph-help) - - [Measures](#measures) - - [Motifs and Memberships](#motifs-and-memberships) - - [Models](#models) +- [Tutorials](#tutorials) - [Installation](#installation) - [Stable](#stable) - [Development](#development) - - [Tutorials](#tutorials) - [Relationship to other packages](#relationship-to-other-packages) - [Funding details](#funding-details) ### Package background - +Cover image of the book Multimodal Political Networks The package is intended as a software companion to the book: @@ -83,92 +78,44 @@ The package is intended as a software companion to the book: Cambridge University Press: Cambridge. Most datasets used in the book are included in this package, -and the package implements most methods discussed in the book. +and `manynet` and `{migraph}` together implement most methods discussed in the book. Since many of theses datasets and routines are discussed and analysed more there, -if you like the package please check out the book, and vice versa. +if you like the package(s) please check out the book, and vice versa. ## How does migraph help? -`{migraph}` includes four special groups of functions, -each with their own pretty `print()` and `plot()` methods: -measures, memberships, motifs, and models. -Measures are numeric scalars or vectors, memberships categorical, -and motifs and models result in tabular outputs. - -`{migraph}` uses a common syntax to help new and experienced network analysts -find the right function and use it correctly. -All `network_*()` functions return a value for the network/graph or for each mode in the network. -All `node_*()` functions return values for each node or vertex in the network. -And all `tie_*()` functions return values for each tie or edge in the network. -Functions are given intuitive and succinct names that avoid conflicts -with existing function names wherever possible. -All results are normalised by default, facilitating comparison. - -### Measures - -`{migraph}` also offers a large and growing smorgasbord of measures that -can be used at the node, tie, and network level. -Each recognises whether the network is directed or undirected, -weighted or unweighted, one-mode or two-mode. -All return normalized values wherever possible, -though this can be overrided. -Here are some examples: - -- _Centrality_: `node_degree()`, `node_closeness()`, `node_betweenness()`, and `node_eigenvector()` -- _Centralization_: `network_degree()`, `network_closeness()`, `network_betweenness()`, and `network_eigenvector()` -- _Cohesion_: `network_density()`, `network_reciprocity()`, `network_transitivity()`, `network_equivalency()`, and `network_congruency()` -- _Connectedness_: `network_components()`, `network_cohesion()`, `network_adhesion()`, `network_diameter()`, `network_length()` -- _Diversity_: `network_diversity()`, `network_homophily()`, `network_assortativity()`, - `node_diversity()`, `node_homophily()`, `node_assortativity()`, `node_richness()` -- _Innovation_: e.g. `node_redundancy()`, `node_effsize()`, `node_efficiency()`, `node_constraint()`, `node_hierarchy()` -- _Topological features_: e.g. `network_core()`, `network_factions()`, `network_modularity()`, `network_smallworld()`, `network_balance()` - -Please explore [the list of functions](https://stocnet.github.io/migraph/reference/index.html) to find out more. - -### Motifs and Memberships - -The package also include functions for returning various censuses of motifs -at the network or node level, e.g.: - -- `r list_functions("network_.*_census")` -- `r list_functions("node_.*_census")` - -For example `node_brokerage_census()` returns -the frequency of nodes' participation in -Gould-Fernandez brokerage roles for a one-mode network, -and the Jasny-Lubell brokerage roles for a two-mode network. - -These can be analysed alone, or used as a profile for establishing equivalence. -`{migraph}` offers both HCA and CONCOR algorithms, -as well as elbow, silhouette, and strict methods for _k_-cluster selection. - -- `r list_functions("node.*_equivalence")` - -![](https://www.jameshollway.com/post/migraph/dendroPlot.png) - -`{migraph}` also includes functions for establishing membership on other bases, -such as typical community detection algorithms, -as well as component and core-periphery partitioning algorithms. - -### Models - -All measures can be tested against conditional uniform graph (CUG) -or quadratic assignment procedure (QAP) distributions using: +`{migraph}` allows the testing of `{manynet}` measures against +conditional uniform graph (CUG) or quadratic assignment procedure (QAP) distributions using: - `r list_functions("^test_")` -![](https://www.jameshollway.com/post/migraph/tests-2.png) +![A plot showing the results of a QAP test](https://www.jameshollway.com/post/migraph/tests-2.png) Hypotheses can also be tested within multivariate models via multiple (linear or logistic) regression QAP: - `network_reg()` -![](https://www.jameshollway.com/post/migraph/regression-1.png) +![A violin plot showing the results of an MRQAP](https://www.jameshollway.com/post/migraph/regression-1.png) `{migraph}` is the only package that offers these testing frameworks for two-mode networks as well as one-mode networks. +## Tutorials + +Together with `{manynet}`, this package makes available interactive `{learnr}` tutorials. +The easiest way to access the tutorials is via `run_tute()`. +If no tutorial name is provided, the function will return a list of tutorials +currently available in either package: + +```{r learnr-tutes} +library(migraph) +run_tute() +# run_tute("tutorial5") +``` + +For more details on the `{learnr}` package, see [here](https://rstudio.github.io/learnr/). + ## Installation ### Stable @@ -217,20 +164,11 @@ please install the `{remotes}` or `{devtools}` package from CRAN and then: - For latest development version: `remotes::install_github("stocnet/migraph@develop")` -### Tutorials - -Together with `{manynet}`, this package makes available interactive `{learnr}` tutorials. -The easiest way to access the tutorials is via `run_tute()`. -If no tutorial name is provided, the function will return a list of tutorials -currently available in either package: +### Other sources -```{r learnr-tutes} -library(migraph) -run_tute() -# run_tute("tutorial5") -``` +Those using Mac computers may also install using Macports: -For more details on the `{learnr}` package, see [here](https://rstudio.github.io/learnr/). +`sudo port install R-migraph` ## Relationship to other packages diff --git a/README.md b/README.md index 04c4265e..5427371a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# migraph +# migraph migraph logo @@ -39,11 +39,9 @@ transaction costs though, driving confusion, inefficiencies, and errors. `{migraph}` builds upon [`{manynet}`](https://stocnet.github.io/manynet/) to offer smart solutions to these problems. `{migraph}` includes functions for -measuring networks and their nodes and ties, identifying motifs and -memberships in them, and modelling these networks or simulating -processes such as diffusion upon them. Since it is based on `{manynet}`, -every function works for any compatible network format - from base R -matrices or edgelists as data frames, +analysing and modelling these networks. Since it is based on +`{manynet}`, every function works for any compatible network format - +from base R matrices or edgelists as data frames, [`{igraph}`](https://igraph.org/r/), [`{network}`](https://statnet.org), or [`{tidygraph}`](https://tidygraph.data-imaginist.com/index.html) objects. This means it is compatible with your existing workflow, is @@ -53,19 +51,16 @@ available for each task. - [About the package](#about-the-package) - [Package background](#package-background) - [How does migraph help?](#how-does-migraph-help) - - [Measures](#measures) - - [Motifs and Memberships](#motifs-and-memberships) - - [Models](#models) +- [Tutorials](#tutorials) - [Installation](#installation) - [Stable](#stable) - [Development](#development) - - [Tutorials](#tutorials) - [Relationship to other packages](#relationship-to-other-packages) - [Funding details](#funding-details) ### Package background - +Cover image of the book Multimodal Political Networks The package is intended as a software companion to the book: @@ -74,102 +69,71 @@ The package is intended as a software companion to the book: > Networks*](https://www.cambridge.org/core/books/multimodal-political-networks/43EE8C192A1B0DCD65B4D9B9A7842128). > Cambridge University Press: Cambridge. -Most datasets used in the book are included in this package, and the -package implements most methods discussed in the book. Since many of -theses datasets and routines are discussed and analysed more there, if -you like the package please check out the book, and vice versa. +Most datasets used in the book are included in this package, and +`manynet` and `{migraph}` together implement most methods discussed in +the book. Since many of theses datasets and routines are discussed and +analysed more there, if you like the package(s) please check out the +book, and vice versa. ## How does migraph help? -`{migraph}` includes four special groups of functions, each with their -own pretty `print()` and `plot()` methods: measures, memberships, -motifs, and models. Measures are numeric scalars or vectors, memberships -categorical, and motifs and models result in tabular outputs. - -`{migraph}` uses a common syntax to help new and experienced network -analysts find the right function and use it correctly. All `network_*()` -functions return a value for the network/graph or for each mode in the -network. All `node_*()` functions return values for each node or vertex -in the network. And all `tie_*()` functions return values for each tie -or edge in the network. Functions are given intuitive and succinct names -that avoid conflicts with existing function names wherever possible. All -results are normalised by default, facilitating comparison. - -### Measures - -`{migraph}` also offers a large and growing smorgasbord of measures that -can be used at the node, tie, and network level. Each recognises whether -the network is directed or undirected, weighted or unweighted, one-mode -or two-mode. All return normalized values wherever possible, though this -can be overrided. Here are some examples: - -- *Centrality*: `node_degree()`, `node_closeness()`, - `node_betweenness()`, and `node_eigenvector()` -- *Centralization*: `network_degree()`, `network_closeness()`, - `network_betweenness()`, and `network_eigenvector()` -- *Cohesion*: `network_density()`, `network_reciprocity()`, - `network_transitivity()`, `network_equivalency()`, and - `network_congruency()` -- *Connectedness*: `network_components()`, `network_cohesion()`, - `network_adhesion()`, `network_diameter()`, `network_length()` -- *Diversity*: `network_diversity()`, `network_homophily()`, - `network_assortativity()`, `node_diversity()`, `node_homophily()`, - `node_assortativity()`, `node_richness()` -- *Innovation*: e.g. `node_redundancy()`, `node_effsize()`, - `node_efficiency()`, `node_constraint()`, `node_hierarchy()` -- *Topological features*: e.g. `network_core()`, `network_factions()`, - `network_modularity()`, `network_smallworld()`, `network_balance()` - -Please explore [the list of -functions](https://stocnet.github.io/migraph/reference/index.html) to -find out more. - -### Motifs and Memberships - -The package also include functions for returning various censuses of -motifs at the network or node level, e.g.: - -- `network_brokerage_census()`, `network_dyad_census()`, - `network_mixed_census()`, `network_triad_census()` -- `node_brokerage_census()`, `node_path_census()`, `node_quad_census()`, - `node_tie_census()`, `node_triad_census()` - -For example `node_brokerage_census()` returns the frequency of nodes’ -participation in Gould-Fernandez brokerage roles for a one-mode network, -and the Jasny-Lubell brokerage roles for a two-mode network. - -These can be analysed alone, or used as a profile for establishing -equivalence. `{migraph}` offers both HCA and CONCOR algorithms, as well -as elbow, silhouette, and strict methods for *k*-cluster selection. - -- `node_automorphic_equivalence()`, `node_equivalence()`, - `node_regular_equivalence()`, `node_structural_equivalence()` - -![](https://www.jameshollway.com/post/migraph/dendroPlot.png) - -`{migraph}` also includes functions for establishing membership on other -bases, such as typical community detection algorithms, as well as -component and core-periphery partitioning algorithms. - -### Models - -All measures can be tested against conditional uniform graph (CUG) or -quadratic assignment procedure (QAP) distributions using: - -- `test_gof()`, `test_permutation()`, `test_random()` - -![](https://www.jameshollway.com/post/migraph/tests-2.png) +`{migraph}` allows the testing of `{manynet}` measures against +conditional uniform graph (CUG) or quadratic assignment procedure (QAP) +distributions using: + +- `test_distribution()`, `test_fit()`, `test_gof()`, + `test_permutation()`, `test_random()` + +

    + + +
    Hypotheses can also be tested within multivariate models via multiple (linear or logistic) regression QAP: - `network_reg()` -![](https://www.jameshollway.com/post/migraph/regression-1.png) +
    + + +
    `{migraph}` is the only package that offers these testing frameworks for two-mode networks as well as one-mode networks. +## Tutorials + +Together with `{manynet}`, this package makes available interactive +`{learnr}` tutorials. The easiest way to access the tutorials is via +`run_tute()`. If no tutorial name is provided, the function will return +a list of tutorials currently available in either package: + +``` r +library(migraph) +run_tute() +#> # A tibble: 9 × 3 +#> package name title +#> +#> 1 manynet tutorial0 Intro to R +#> 2 manynet tutorial1 Data +#> 3 manynet tutorial2 Visualisation +#> 4 manynet tutorial3 Centrality +#> 5 manynet tutorial4 Community +#> 6 manynet tutorial5 Position +#> 7 manynet tutorial6 Topology +#> 8 manynet tutorial7 Diffusion +#> 9 migraph tutorial8 Diversity and Regression +# run_tute("tutorial5") +``` + +For more details on the `{learnr}` package, see +[here](https://rstudio.github.io/learnr/). + ## Installation ### Stable @@ -223,36 +187,11 @@ and then: - For latest development version: `remotes::install_github("stocnet/migraph@develop")` -### Tutorials +### Other sources -Together with `{manynet}`, this package makes available interactive -`{learnr}` tutorials. The easiest way to access the tutorials is via -`run_tute()`. If no tutorial name is provided, the function will return -a list of tutorials currently available in either package: +Those using Mac computers may also install using Macports: -``` r -library(migraph) -run_tute() -#> # A tibble: 9 × 3 -#> package name title -#> -#> 1 manynet tutorial0 Intro to R -#> 2 manynet tutorial1 Data -#> 3 manynet tutorial2 Visualisation -#> 4 migraph tutorial3 Centrality -#> 5 migraph tutorial4 Community -#> 6 migraph tutorial5 Position -#> 7 migraph tutorial6 Topology -#> 8 manynet tutorial7 Diffusion -#> 9 migraph tutorial8 Regression -``` - -``` r -# run_tute("tutorial5") -``` - -For more details on the `{learnr}` package, see -[here](https://rstudio.github.io/learnr/). +`sudo port install R-migraph` ## Relationship to other packages From a729dd6891db4b06f49ed33dd5fd2127799cb92f Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 18 Jul 2024 22:17:42 +0200 Subject: [PATCH 97/97] Using html instead of markdown for images so alt text doesn't appear as title --- README.Rmd | 4 ++-- README.md | 14 ++------------ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/README.Rmd b/README.Rmd index dd79175b..2aef052c 100644 --- a/README.Rmd +++ b/README.Rmd @@ -89,14 +89,14 @@ conditional uniform graph (CUG) or quadratic assignment procedure (QAP) distribu - `r list_functions("^test_")` -![A plot showing the results of a QAP test](https://www.jameshollway.com/post/migraph/tests-2.png) +Plot showing the results of a QAP test Hypotheses can also be tested within multivariate models via multiple (linear or logistic) regression QAP: - `network_reg()` -![A violin plot showing the results of an MRQAP](https://www.jameshollway.com/post/migraph/regression-1.png) +A violin plot showing the results of an MRQAP `{migraph}` is the only package that offers these testing frameworks for two-mode networks as well as one-mode networks. diff --git a/README.md b/README.md index 5427371a..79557314 100644 --- a/README.md +++ b/README.md @@ -84,24 +84,14 @@ distributions using: - `test_distribution()`, `test_fit()`, `test_gof()`, `test_permutation()`, `test_random()` -
    - - -
    +Plot showing the results of a QAP test Hypotheses can also be tested within multivariate models via multiple (linear or logistic) regression QAP: - `network_reg()` -
    - - -
    +A violin plot showing the results of an MRQAP `{migraph}` is the only package that offers these testing frameworks for two-mode networks as well as one-mode networks.

    V-F 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 U5z&QKZ4&UOB&Q}@ByEEKKNRBaC;$Ke literal 0 HcmV?d00001 From 77a94a7fd55a16a67866906391eced4a9e6fae8b Mon Sep 17 00:00:00 2001 From: James Hollway Date: Mon, 20 May 2024 21:07:45 +0200 Subject: [PATCH 04/97] Added .corDiag() and .corRecip() for calculating nodal correlations without the diagonal and including reciprocated ties --- R/motif_correlation.R | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 R/motif_correlation.R diff --git a/R/motif_correlation.R b/R/motif_correlation.R new file mode 100644 index 00000000..04cd173a --- /dev/null +++ b/R/motif_correlation.R @@ -0,0 +1,35 @@ + +.corTwomode <- function(m0){ + stats::cor(m0) +} + +# Though warnings need to be suppressed, +# this is bench::mark()ed at about 17-18 times faster than corrColsExcludeDiag(), +# and uses 188 times less memory +.corDiag <- function(M){ + diag(M) <- NA + out <- suppressWarnings(stats::cor(M, use = "pairwise.complete.obs")) + out[is.na(out)] <- 0 + diag(out) <- 1 + out +} + +# Though warnings need to be suppressed, +# this is bench::mark()ed at about 2 times faster than corrColsRecipRLB() +.corRecip <- function(M){ + all.pairs <- combn(1:ncol(M),2) + corres <- apply(all.pairs, 2, function(i){ + x <- c(M[-i,i[1]], M[i[1],i[2]]) + y <- c(M[-i,i[2]], M[i[2],i[1]]) + suppressWarnings(stats::cor(x = x, y = y)) + }) + out <- matrix(1,nrow(M),ncol(M)) + out[lower.tri(out)] <- corres + out <- .makeSymm(out) + out[is.na(out)] <- 0 + diag(out) <- 1 + rownames(out) <- rownames(M) + colnames(out) <- colnames(M) + out +} + From 8b320f8697d75985c15496d86816565b8ca0c441 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 22 May 2024 14:48:48 +0200 Subject: [PATCH 05/97] equivalence functions can now be used in e.g. mutate() without specifying .data --- R/member_equivalence.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/R/member_equivalence.R b/R/member_equivalence.R index 040cb631..55fa1134 100644 --- a/R/member_equivalence.R +++ b/R/member_equivalence.R @@ -56,6 +56,7 @@ node_equivalence <- function(.data, census, distance = c("euclidean", "maximum", "manhattan", "canberra", "binary", "minkowski"), range = 8L){ + if(missing(.data)) {expect_nodes(); .data <- .G()} hc <- switch(match.arg(cluster), hierarchical = cluster_hierarchical(`if`(manynet::is_twomode(.data), manynet::to_onemode(census), census), @@ -87,6 +88,7 @@ node_structural_equivalence <- function(.data, distance = c("euclidean", "maximum", "manhattan", "canberra", "binary", "minkowski"), range = 8L){ + if(missing(.data)) {expect_nodes(); .data <- .G()} mat <- node_tie_census(.data) if(any(colSums(t(mat))==0)){ mat <- cbind(mat, (colSums(t(mat))==0)) @@ -109,6 +111,7 @@ node_regular_equivalence <- function(.data, distance = c("euclidean", "maximum", "manhattan", "canberra", "binary", "minkowski"), range = 8L){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(manynet::is_twomode(.data)){ mat <- as.matrix(node_quad_census(.data)) } else { @@ -133,6 +136,7 @@ node_automorphic_equivalence <- function(.data, distance = c("euclidean", "maximum", "manhattan", "canberra", "binary", "minkowski"), range = 8L){ + if(missing(.data)) {expect_nodes(); .data <- .G()} mat <- node_path_census(.data) node_equivalence(.data, mat, k = k, cluster = cluster, distance = distance, range = range) From 77d3aceca2719b5c7d91013f09b206e82e6de5ae Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 22 May 2024 15:47:53 +0200 Subject: [PATCH 06/97] Fixed bug in node_tie_census() where census only conducted on second mode of two-mode networks --- R/motif_census.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/motif_census.R b/R/motif_census.R index 527fd644..b6edb643 100644 --- a/R/motif_census.R +++ b/R/motif_census.R @@ -47,6 +47,8 @@ node_tie_census <- function(.data){ function(x){ manynet::as_matrix(manynet::to_uniplex(object, x)) })) + } else if (manynet::is_twomode(.data)) { + mat <- manynet::as_matrix(manynet::to_multilevel(object)) } else { mat <- manynet::as_matrix(object) } From 5721384f74dffb2b29fb96fb7c3d936f035419fa Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 22 May 2024 15:48:18 +0200 Subject: [PATCH 07/97] Added thisRequires() helper into migraph (copy from manynet) --- R/migraph-package.R | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/R/migraph-package.R b/R/migraph-package.R index a65cf643..252ff1b3 100644 --- a/R/migraph-package.R +++ b/R/migraph-package.R @@ -4,3 +4,15 @@ ## usethis namespace: start ## usethis namespace: end NULL + +# Helper function for checking and downloading packages +thisRequires <- function(pkgname){ + if (!requireNamespace(pkgname, quietly = TRUE)) { + if(utils::askYesNo(msg = paste("The", pkgname, + "package is required to run this function. Would you like to install", pkgname, "from CRAN?"))) { + utils::install.packages(pkgname) + } else { + stop(paste("Please install", pkgname, "from CRAN to run this function.")) + } + } +} From 78102cac9cfe8008cff4ff810868682978e8e0f9 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 22 May 2024 15:52:28 +0200 Subject: [PATCH 08/97] Using thisRequires() for ggdendro dependency --- R/class_members.R | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/R/class_members.R b/R/class_members.R index 71c2f824..238020ba 100644 --- a/R/class_members.R +++ b/R/class_members.R @@ -55,9 +55,7 @@ summary.node_member <- function(object, ..., #' @importFrom stats cutree #' @export plot.node_member <- function(x, ...) { - if (!("ggdendro" %in% rownames(utils::installed.packages()))) { - message("Please install package `{ggdendro}`.") - } else { + thisRequires("ggdendro") hc <- attr(x, "hc") k <- attr(x, "k") memb <- x[hc$order] @@ -71,7 +69,6 @@ plot.node_member <- function(x, ...) { ggplot2::theme(axis.text.x = ggplot2::element_text(colour = "#5c666f"), axis.text.y = suppressWarnings( ggplot2::element_text(colour = colors))) - } } # plot(as_matrix(ison_adolescents), From 06a3c2e62445dc95f4229337c02c245539040771 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 22 May 2024 21:04:59 +0200 Subject: [PATCH 09/97] Added .corComplex() --- R/motif_correlation.R | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/R/motif_correlation.R b/R/motif_correlation.R index 04cd173a..08534385 100644 --- a/R/motif_correlation.R +++ b/R/motif_correlation.R @@ -33,3 +33,26 @@ out } +# Though warnings need to be suppressed, +# this is bench::mark()ed at about 2.3 times faster than corrColsRecipUCI() +.corComplex <- function(M){ + all.pairs <- combn(1:ncol(M),2) + corres <- apply(all.pairs, 2, function(i){ + x <- c(M[-i,i[1]], M[i[1],i[2]], M[i[1],i[1]]) + y <- c(M[-i,i[2]], M[i[2],i[1]], M[i[2],i[2]]) + suppressWarnings(stats::cor(x = x, y = y)) + }) + out <- matrix(1,nrow(M),ncol(M)) + out[lower.tri(out)] <- corres + out <- .makeSymm(out) + out[is.na(out)] <- 0 + diag(out) <- 1 + rownames(out) <- rownames(M) + colnames(out) <- colnames(M) + out +} + +.makeSymm <- function(m) { + m[upper.tri(m)] <- t(m)[upper.tri(m)] + return(m) +} From dc264a13e5b9a0bd7d159f170f63ca3687095cf8 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 22 May 2024 21:14:22 +0200 Subject: [PATCH 10/97] Added to_correlation() --- NAMESPACE | 1 + R/motif_correlation.R | 33 +++++++++++++++++++++++++++++++++ man/brokerage_census.Rd | 3 ++- man/network_census.Rd | 3 ++- man/node_census.Rd | 3 ++- man/node_correlation.Rd | 39 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 man/node_correlation.Rd diff --git a/NAMESPACE b/NAMESPACE index 51377d71..bad296b2 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -208,6 +208,7 @@ export(tie_closeness) export(tie_cohesion) export(tie_degree) export(tie_eigenvector) +export(to_correlation) export(with_graph) export(xlab) export(ylab) diff --git a/R/motif_correlation.R b/R/motif_correlation.R index 08534385..c9b62ddd 100644 --- a/R/motif_correlation.R +++ b/R/motif_correlation.R @@ -1,3 +1,36 @@ +#' Node correlation +#' +#' @description +#' This function performs a Pearson pairwise correlation on a given matrix or network data. +#' It includes a switch: +#' whereas for a two-mode network it will perform a regular correlation, +#' including all rows, +#' for an undirected network it will perform a correlation on a matrix +#' with the diagonals removed, +#' for a reciprocated network it will include the difference +#' between reciprocated ties, +#' and for complex networks it will include also the difference +#' between the self ties in each pairwise calculation. +#' This function runs in \eqn{O(mn^2)} complexity. +#' @name node_correlation +#' @inheritParams cohesion +#' @family motifs +#' @export +to_correlation <- function(.data){ + mat <- manynet::as_matrix(.data) + if(manynet::is_twomode(.data)){ + # if(!any(colnames(m0) %in% rownames(m0))) + # mat <- node_tie_census(mat) + out <- .corTwomode(mat) + } else if(manynet::is_complex(.data)){ + out <- .corComplex(mat) + } else if(manynet::is_directed(.data)){ + out <- .corRecip(mat) + } else { + out <- .corDiag(mat) + } + out +} .corTwomode <- function(m0){ stats::cor(m0) diff --git a/man/brokerage_census.Rd b/man/brokerage_census.Rd index 75daea70..5bf6ef48 100644 --- a/man/brokerage_census.Rd +++ b/man/brokerage_census.Rd @@ -69,6 +69,7 @@ and their application to multi-level environmental governance networks" \seealso{ Other motifs: \code{\link{network_census}}, -\code{\link{node_census}} +\code{\link{node_census}}, +\code{\link{node_correlation}} } \concept{motifs} diff --git a/man/network_census.Rd b/man/network_census.Rd index 3f6eeaf0..91150f76 100644 --- a/man/network_census.Rd +++ b/man/network_census.Rd @@ -56,6 +56,7 @@ Hollway, James, Alessandro Lomi, Francesca Pallotti, and Christoph Stadtfeld. 20 \seealso{ Other motifs: \code{\link{brokerage_census}}, -\code{\link{node_census}} +\code{\link{node_census}}, +\code{\link{node_correlation}} } \concept{motifs} diff --git a/man/node_census.Rd b/man/node_census.Rd index a9841eda..2cf1b560 100644 --- a/man/node_census.Rd +++ b/man/node_census.Rd @@ -100,6 +100,7 @@ Opsahl, Tore, Filip Agneessens, and John Skvoretz. 2010. \seealso{ Other motifs: \code{\link{brokerage_census}}, -\code{\link{network_census}} +\code{\link{network_census}}, +\code{\link{node_correlation}} } \concept{motifs} diff --git a/man/node_correlation.Rd b/man/node_correlation.Rd new file mode 100644 index 00000000..b83fa09a --- /dev/null +++ b/man/node_correlation.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/motif_correlation.R +\name{node_correlation} +\alias{node_correlation} +\alias{to_correlation} +\title{Node correlation} +\usage{ +to_correlation(.data) +} +\arguments{ +\item{.data}{An object of a \code{{manynet}}-consistent class: +\itemize{ +\item matrix (adjacency or incidence) from \code{{base}} R +\item edgelist, a data frame from \code{{base}} R or tibble from \code{{tibble}} +\item igraph, from the \code{{igraph}} package +\item network, from the \code{{network}} package +\item tbl_graph, from the \code{{tidygraph}} package +}} +} +\description{ +This function performs a Pearson pairwise correlation on a given matrix or network data. +It includes a switch: +whereas for a two-mode network it will perform a regular correlation, +including all rows, +for an undirected network it will perform a correlation on a matrix +with the diagonals removed, +for a reciprocated network it will include the difference +between reciprocated ties, +and for complex networks it will include also the difference +between the self ties in each pairwise calculation. +This function runs in \eqn{O(mn^2)} complexity. +} +\seealso{ +Other motifs: +\code{\link{brokerage_census}}, +\code{\link{network_census}}, +\code{\link{node_census}} +} +\concept{motifs} From 3071deffdd146ebfc2ab79e7c8b6d332ae053c2c Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 22 May 2024 21:17:08 +0200 Subject: [PATCH 11/97] make_node_member() now converts numeric results to LETTER character results --- R/class_members.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/R/class_members.R b/R/class_members.R index 238020ba..59aad934 100644 --- a/R/class_members.R +++ b/R/class_members.R @@ -1,10 +1,14 @@ make_node_member <- function(out, .data) { if (manynet::is_labelled(.data)) names(out) <- manynet::node_names(.data) + if(is.numeric(out)) + out <- MORELETTERS[out] class(out) <- c("node_member", class(out)) attr(out, "mode") <- manynet::node_mode(.data) out } +MORELETTERS <- c(LETTERS, sapply(LETTERS, function(x) paste0(x, LETTERS))) + #' @export print.node_member <- function(x, ..., n = NULL) { if (any(attr(x, "mode"))) { From ab2e8863f567147abf13cb3bdda666cf1189e914 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 22 May 2024 21:20:14 +0200 Subject: [PATCH 12/97] Fixed how cluster_concor handles unlabelled networks --- R/model_cluster.R | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/R/model_cluster.R b/R/model_cluster.R index c4b9f246..dee96819 100644 --- a/R/model_cluster.R +++ b/R/model_cluster.R @@ -69,6 +69,8 @@ cluster_concor <- function(.data, census){ } } p_list <- list(t(census)) + if(is.null(colnames(p_list[[1]]))) + colnames(p_list[[1]]) <- paste0("V",1:ncol(p_list[[1]])) p_group <- list() i <- 1 while(!all(vapply(p_list, function(x) ncol(x)==1, logical(1)))){ @@ -80,14 +82,25 @@ cluster_concor <- function(.data, census){ i <- i+1 } - merges <- sapply(rev(1:(i-1)), - function(p) lapply(p_group[[p]], - function(s){ - g <- match(s, manynet::node_names(.data)) - if(length(g)==1) c(g, 0, p) else - if(length(g)==2) c(g, p) else - c(t(cbind(t(utils::combn(g, 2)), p))) - } )) + if(manynet::is_labelled(.data)){ + merges <- sapply(rev(1:(i-1)), + function(p) lapply(p_group[[p]], + function(s){ + g <- match(s, manynet::node_names(.data)) + if(length(g)==1) c(g, 0, p) else + if(length(g)==2) c(g, p) else + c(t(cbind(t(utils::combn(g, 2)), p))) + } )) + } else { + merges <- sapply(rev(1:(i-1)), + function(p) lapply(p_group[[p]], + function(s){ + g <- as.numeric(gsub("^V","",s)) + if(length(g)==1) c(g, 0, p) else + if(length(g)==2) c(g, p) else + c(t(cbind(t(utils::combn(g, 2)), p))) + } )) + } merges <- c(merges, list(c(t(cbind(t(utils::combn(seq_len(manynet::network_nodes(.data)), 2)), 0))))) merged <- matrix(unlist(merges), ncol = 3, byrow = TRUE) @@ -108,3 +121,4 @@ cluster_concor <- function(.data, census){ hc$distances <- distances hc } + From 88136a262c1c0f6603533d4b4a53a39e847b5e1d Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 22 May 2024 21:24:09 +0200 Subject: [PATCH 13/97] cluster_hierarchical() and cluster_concor() now use to_correlation() instead of stats::cor() --- R/model_cluster.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/model_cluster.R b/R/model_cluster.R index dee96819..5a9af3c0 100644 --- a/R/model_cluster.R +++ b/R/model_cluster.R @@ -18,7 +18,7 @@ NULL #' @rdname cluster #' @export cluster_hierarchical <- function(census, distance){ - correlations <- cor(t(census)) + correlations <- to_correlation(t(census)) dissimilarity <- 1 - correlations distances <- stats::dist(dissimilarity, method = distance) hc <- stats::hclust(distances) @@ -56,11 +56,11 @@ cluster_hierarchical <- function(census, distance){ #' @export cluster_concor <- function(.data, census){ split_cor <- function(m0, cutoff = 1) { - if (ncol(m0) < 2 | all(stats::cor(m0)==1)) list(m0) + if (ncol(m0) < 2 | all(to_correlation(m0)==1)) list(m0) else { - mi <- stats::cor(m0) + mi <- to_correlation(m0) while (any(abs(mi) <= cutoff)) { - mi <- cor(mi) + mi <- stats::cor(mi) cutoff <- cutoff - 0.0001 } group <- mi[, 1] > 0 From 560b61d96db02cb0ddbe5e578f3ffa0a5c3800cf Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 22 May 2024 21:24:48 +0200 Subject: [PATCH 14/97] Fixed how cluster_concor() handles two-mode networks --- R/model_cluster.R | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/R/model_cluster.R b/R/model_cluster.R index 5a9af3c0..fb60b0c8 100644 --- a/R/model_cluster.R +++ b/R/model_cluster.R @@ -72,7 +72,12 @@ cluster_concor <- function(.data, census){ if(is.null(colnames(p_list[[1]]))) colnames(p_list[[1]]) <- paste0("V",1:ncol(p_list[[1]])) p_group <- list() - i <- 1 + if(manynet::is_twomode(.data)){ + p_list <- list(p_list[[1]][node_mode(.data), !node_mode(.data), drop = FALSE], + p_list[[1]][!node_mode(.data), node_mode(.data), drop = FALSE]) + p_group[[i]] <- lapply(p_list, function(z) colnames(z)) + i <- 2 + } else i <- 1 while(!all(vapply(p_list, function(x) ncol(x)==1, logical(1)))){ p_list <- unlist(lapply(p_list, function(y) split_cor(y)), From 48db250fc5a0cbb9d84907998c016a05fcaf72b0 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Wed, 22 May 2024 21:27:52 +0200 Subject: [PATCH 15/97] Fixed bug where cluster_concor() cutoff resulted in unsplit groups --- R/model_cluster.R | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/R/model_cluster.R b/R/model_cluster.R index fb60b0c8..d9d4575d 100644 --- a/R/model_cluster.R +++ b/R/model_cluster.R @@ -64,8 +64,12 @@ cluster_concor <- function(.data, census){ cutoff <- cutoff - 0.0001 } group <- mi[, 1] > 0 - list(m0[, group, drop = FALSE], + if(all(group)){ + list(m0) + } else { + list(m0[, group, drop = FALSE], m0[, !group, drop = FALSE]) + } } } p_list <- list(t(census)) From f9f08d9a5fb777d62051262a3e7948e5f5e8814c Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 23 May 2024 11:29:43 +0200 Subject: [PATCH 16/97] node_tie_census() now works on longitudinal network data --- R/motif_census.R | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/R/motif_census.R b/R/motif_census.R index b6edb643..ecbde57d 100644 --- a/R/motif_census.R +++ b/R/motif_census.R @@ -37,6 +37,13 @@ node_tie_census <- function(.data){ rc <- manynet::as_matrix(manynet::to_uniplex(object, x)) rbind(rc, t(rc)) })) + } else if (manynet::is_longitudinal(object)){ + mat <- do.call(rbind, lapply(unique(manynet::tie_attribute(object, "wave")), + function(x){ + rc <- manynet::as_matrix(manynet::to_waves(object)[[x]]) + rbind(rc, t(rc)) + })) + } else { rc <- manynet::as_matrix(object) mat <- rbind(rc, t(rc)) @@ -47,6 +54,11 @@ node_tie_census <- function(.data){ function(x){ manynet::as_matrix(manynet::to_uniplex(object, x)) })) + } else if (manynet::is_longitudinal(object)){ + mat <- do.call(rbind, lapply(unique(manynet::tie_attribute(object, "wave")), + function(x){ + manynet::as_matrix(manynet::to_waves(object)[[x]]) + })) } else if (manynet::is_twomode(.data)) { mat <- manynet::as_matrix(manynet::to_multilevel(object)) } else { @@ -59,6 +71,11 @@ node_tie_census <- function(.data){ paste0("to", manynet::node_names(object))), unique(manynet::tie_attribute(object, "type"))), 1, paste, collapse = "_") + } else if (manynet::is_longitudinal(object)){ + rownames(mat) <- apply(expand.grid(c(paste0("from", manynet::node_names(object)), + paste0("to", manynet::node_names(object))), + unique(manynet::tie_attribute(object, "wave"))), + 1, paste, collapse = "_wave") } else { rownames(mat) <- rep(c(paste0("from", manynet::node_names(object)), paste0("to", manynet::node_names(object)))) From 9460c7c0fe8ec51913537e52f72af0e38d9abadf Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 23 May 2024 15:48:39 +0200 Subject: [PATCH 17/97] print.node_member() now works with categorical membership vectors, declares how many groups before reporting the vectors --- R/class_members.R | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/R/class_members.R b/R/class_members.R index 59aad934..2335a1d3 100644 --- a/R/class_members.R +++ b/R/class_members.R @@ -1,7 +1,7 @@ make_node_member <- function(out, .data) { - if (manynet::is_labelled(.data)) names(out) <- manynet::node_names(.data) if(is.numeric(out)) out <- MORELETTERS[out] + if (manynet::is_labelled(.data)) names(out) <- manynet::node_names(.data) class(out) <- c("node_member", class(out)) attr(out, "mode") <- manynet::node_mode(.data) out @@ -11,15 +11,16 @@ MORELETTERS <- c(LETTERS, sapply(LETTERS, function(x) paste0(x, LETTERS))) #' @export print.node_member <- function(x, ..., n = NULL) { + cat(pillar::style_subtle(paste(length(unique(x)), "groups\n"))) if (any(attr(x, "mode"))) { for(m in c(FALSE, TRUE)){ - suppressWarnings(print_tblvec(y = as.numeric(x)[attr(x, "mode") == m], + suppressWarnings(print_tblvec(y = x[attr(x, "mode") == m], names = list(names(x)[attr(x, "mode") == m]), n = n)) if(!m) cat("\n") } } else { - suppressWarnings(print_tblvec(y = `if`(all(is.na(as.numeric(x))), x, as.numeric(x)), + suppressWarnings(print_tblvec(y = x, names = list(names(x)), n = n)) } From 0c760bbd13af0ac10b339224933b416715314ddc Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 23 May 2024 16:37:09 +0200 Subject: [PATCH 18/97] All measures and membership functions now infer network data where not present --- R/measure_centrality.R | 11 +++++++++++ R/measure_closure.R | 6 ++++++ R/measure_cohesion.R | 7 +++++++ R/measure_diffusion.R | 1 + R/measure_features.R | 10 ++++++++++ R/measure_heterogeneity.R | 8 ++++++++ R/measure_hierarchy.R | 3 +++ R/measure_holes.R | 9 +++++++++ R/measure_over.R | 2 ++ R/member_cliques.R | 1 + R/member_community.R | 11 +++++++++++ R/member_components.R | 3 +++ R/member_core.R | 2 ++ R/model_cluster.R | 1 + R/model_tests.R | 2 ++ R/motif_census.R | 12 ++++++++++++ R/motif_correlation.R | 1 + 17 files changed, 90 insertions(+) diff --git a/R/measure_centrality.R b/R/measure_centrality.R index d6cfcdf1..cd3923d1 100644 --- a/R/measure_centrality.R +++ b/R/measure_centrality.R @@ -134,18 +134,21 @@ node_degree <- function (.data, normalized = TRUE, alpha = 1, #' @rdname degree_centrality #' @export node_deg <- function (.data, alpha = 0, direction = c("all","out","in")){ + if(missing(.data)) {expect_nodes(); .data <- .G()} node_degree(.data, normalized = FALSE, alpha = alpha, direction = direction) } #' @rdname degree_centrality #' @export node_outdegree <- function (.data, normalized = TRUE, alpha = 0){ + if(missing(.data)) {expect_nodes(); .data <- .G()} node_degree(.data, normalized = normalized, alpha = alpha, direction = "out") } #' @rdname degree_centrality #' @export node_indegree <- function (.data, normalized = TRUE, alpha = 0){ + if(missing(.data)) {expect_nodes(); .data <- .G()} node_degree(.data, normalized = normalized, alpha = alpha, direction = "in") } @@ -154,6 +157,7 @@ node_indegree <- function (.data, normalized = TRUE, alpha = 0){ #' @param tie2 Character string indicating the second uniplex network. #' @export node_multidegree <- function (.data, tie1, tie2){ + if(missing(.data)) {expect_nodes(); .data <- .G()} stopifnot(manynet::is_multiplex(.data)) out <- node_degree(manynet::to_uniplex(.data, tie1)) - node_degree(manynet::to_uniplex(.data, tie2)) @@ -168,6 +172,7 @@ node_multidegree <- function (.data, tie1, tie2){ #' \doi{10.1016/j.socnet.2014.03.005}. #' @export node_posneg <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} stopifnot(manynet::is_signed(.data)) pos <- manynet::as_matrix(manynet::to_unsigned(.data, keep = "positive")) neg <- manynet::as_matrix(manynet::to_unsigned(.data, keep = "negative")) @@ -234,12 +239,14 @@ network_degree <- function(.data, normalized = TRUE, #' @rdname degree_centrality #' @export network_outdegree <- function(.data, normalized = TRUE){ + if(missing(.data)) {expect_nodes(); .data <- .G()} network_degree(.data, normalized = normalized, direction = "out") } #' @rdname degree_centrality #' @export network_indegree <- function(.data, normalized = TRUE){ + if(missing(.data)) {expect_nodes(); .data <- .G()} network_degree(.data, normalized = normalized, direction = "in") } @@ -322,6 +329,7 @@ node_betweenness <- function(.data, normalized = TRUE, #' @export node_induced <- function(.data, normalized = TRUE, cutoff = NULL){ + if(missing(.data)) {expect_nodes(); .data <- .G()} endog <- sum(node_betweenness(.data, normalized = normalized, cutoff = cutoff), na.rm = TRUE) exog <- vapply(seq.int(manynet::network_nodes(.data)), @@ -338,6 +346,7 @@ node_induced <- function(.data, normalized = TRUE, #' @importFrom sna flowbet #' @export node_flow <- function(.data, normalized = TRUE){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- sna::flowbet(manynet::as_network(.data), gmode = ifelse(manynet::is_directed(.data), "digraph", "graph"), diag = manynet::is_complex(.data), @@ -518,6 +527,7 @@ node_harmonic <- function(.data, normalized = TRUE, k = -1){ #' @importFrom sna infocent #' @export node_information <- function(.data, normalized = TRUE){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- sna::infocent(manynet::as_network(.data), gmode = ifelse(manynet::is_directed(.data), "digraph", "graph"), diag = manynet::is_complex(.data)) @@ -824,6 +834,7 @@ tie_eigenvector <- function(.data, normalized = TRUE){ #' network_eigenvector(ison_southern_women) #' @export network_eigenvector <- function(.data, normalized = TRUE){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if (manynet::is_twomode(.data)) { out <- c(igraph::centr_eigen(manynet::as_igraph(manynet::to_mode1(.data)), normalized = normalized)$centralization, diff --git a/R/measure_closure.R b/R/measure_closure.R index 25da08b8..42582b9e 100644 --- a/R/measure_closure.R +++ b/R/measure_closure.R @@ -46,6 +46,7 @@ NULL #' network_reciprocity(ison_southern_women) #' @export network_reciprocity <- function(.data, method = "default") { + if(missing(.data)) {expect_nodes(); .data <- .G()} make_network_measure(igraph::reciprocity(manynet::as_igraph(.data), mode = method), .data) } @@ -55,6 +56,7 @@ network_reciprocity <- function(.data, method = "default") { #' node_reciprocity(to_unweighted(ison_networkers)) #' @export node_reciprocity <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- manynet::as_matrix(.data) make_node_measure(rowSums(out * t(out))/rowSums(out), .data) @@ -66,6 +68,7 @@ node_reciprocity <- function(.data) { #' network_transitivity(ison_adolescents) #' @export network_transitivity <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} make_network_measure(igraph::transitivity(manynet::as_igraph(.data)), .data) } @@ -75,6 +78,7 @@ network_transitivity <- function(.data) { #' node_transitivity(ison_adolescents) #' @export node_transitivity <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} make_node_measure(igraph::transitivity(manynet::as_igraph(.data), type = "local"), .data) @@ -89,6 +93,7 @@ node_transitivity <- function(.data) { #' network_equivalency(ison_southern_women) #' @export network_equivalency <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} if (manynet::is_twomode(.data)) { mat <- manynet::as_matrix(.data) c <- ncol(mat) @@ -108,6 +113,7 @@ network_equivalency <- function(.data) { #' @rdname closure #' @export network_congruency <- function(.data, object2){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(missing(.data) | missing(object2)) stop("This function expects two two-mode networks") if(!manynet::is_twomode(.data) | !manynet::is_twomode(object2)) stop("This function expects two two-mode networks") if(manynet::network_dims(.data)[2] != manynet::network_dims(object2)[1]) diff --git a/R/measure_cohesion.R b/R/measure_cohesion.R index d66e1a48..91f955a8 100644 --- a/R/measure_cohesion.R +++ b/R/measure_cohesion.R @@ -35,6 +35,7 @@ NULL #' network_density(mpn_elite_usa_advice) #' @export network_density <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} if (manynet::is_twomode(.data)) { mat <- manynet::as_matrix(.data) out <- sum(mat) / (nrow(mat) * ncol(mat)) @@ -54,6 +55,7 @@ network_density <- function(.data) { #' network_components(manynet::to_undirected(mpn_ryanair)) #' @export network_components <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} object <- manynet::as_igraph(.data) make_network_measure(igraph::components(object, mode = "strong")$no, object) @@ -70,6 +72,7 @@ network_components <- function(.data){ #' network_cohesion(manynet::to_giant(manynet::ison_marvel_relationships)) #' @export network_cohesion <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} make_network_measure(igraph::cohesion(manynet::as_igraph(.data)), .data) } @@ -80,6 +83,7 @@ network_cohesion <- function(.data){ #' network_adhesion(manynet::to_giant(manynet::ison_marvel_relationships)) #' @export network_adhesion <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} make_network_measure(igraph::adhesion(manynet::as_igraph(.data)), .data) } @@ -90,6 +94,7 @@ network_adhesion <- function(.data){ #' network_diameter(manynet::to_giant(manynet::ison_marvel_relationships)) #' @export network_diameter <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} object <- manynet::as_igraph(.data) make_network_measure(igraph::diameter(object, directed = manynet::is_directed(object)), @@ -103,6 +108,7 @@ network_diameter <- function(.data){ #' network_length(manynet::to_giant(manynet::ison_marvel_relationships)) #' @export network_length <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} object <- manynet::as_igraph(.data) make_network_measure(igraph::mean_distance(object, directed = manynet::is_directed(object)), @@ -115,6 +121,7 @@ network_length <- function(.data){ #' network_independence(manynet::ison_adolescents) #' @export network_independence <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(manynet::is_twomode(.data)){ out <- igraph::ivs_size(manynet::to_mode1(manynet::as_igraph(.data))) } else { diff --git a/R/measure_diffusion.R b/R/measure_diffusion.R index 3bb59484..835b8ff2 100644 --- a/R/measure_diffusion.R +++ b/R/measure_diffusion.R @@ -379,6 +379,7 @@ node_infection_length <- function(diff_model){ #' node_exposure(smeg_diff) #' @export node_exposure <- function(.data, mark, time = 0){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(missing(mark) && inherits(.data, "diff_model")){ mark <- manynet::node_is_infected(.data, time = time) .data <- attr(.data, "network") diff --git a/R/measure_features.R b/R/measure_features.R index 63ee5d49..ac3e0709 100644 --- a/R/measure_features.R +++ b/R/measure_features.R @@ -45,6 +45,7 @@ NULL #' @export network_core <- function(.data, membership = NULL){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(is.null(membership)) membership <- node_core(.data) out <- stats::cor(c(manynet::as_matrix(.data)), c(manynet::as_matrix(manynet::create_core(.data, @@ -57,6 +58,7 @@ network_core <- function(.data, #' network_richclub(ison_adolescents) #' @export network_richclub <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} coefs <- vector() temp <- .data for(k in seq_len(max(node_degree(temp, normalized = FALSE)))){ @@ -103,6 +105,7 @@ network_richclub <- function(.data){ #' @export network_factions <- function(.data, membership = NULL){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(is.null(membership)) membership <- node_kernighanlin(.data) out <- stats::cor(c(manynet::as_matrix(.data)), @@ -145,8 +148,10 @@ network_factions <- function(.data, network_modularity <- function(.data, membership = NULL, resolution = 1){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(is.null(membership)) membership <- node_kernighanlin(.data) + if(!is.numeric(membership)) membership <- as.numeric(as.factor(membership)) if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) if(manynet::is_twomode(.data)){ make_network_measure(igraph::modularity(manynet::to_multilevel(.data), @@ -206,6 +211,7 @@ network_smallworld <- function(.data, method = c("omega", "sigma", "SWI"), times = 100) { + if(missing(.data)) {expect_nodes(); .data <- .G()} method <- match.arg(method) if(manynet::is_twomode(.data)){ @@ -250,6 +256,7 @@ network_smallworld <- function(.data, #' network_scalefree(create_lattice(100)) #' @export network_scalefree <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::fit_power_law(node_degree(.data, normalized = FALSE)) if ("KS.p" %in% names(out)) { if(out$KS.p < 0.05) @@ -267,6 +274,7 @@ network_scalefree <- function(.data){ #' @export network_balance <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} count_signed_triangles <- function(.data){ g <- manynet::as_igraph(.data) if (!"sign" %in% igraph::edge_attr_names(g)) { @@ -344,6 +352,7 @@ NULL #' @param object2 A network object. #' @export network_change <- function(.data, object2){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(manynet::is_list(.data)){ } else if(!missing(object2)){ @@ -360,6 +369,7 @@ network_change <- function(.data, object2){ #' @rdname periods #' @export network_stability <- function(.data, object2){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(manynet::is_list(.data)){ } else if(!missing(object2)){ diff --git a/R/measure_heterogeneity.R b/R/measure_heterogeneity.R index b146836a..f40bb626 100644 --- a/R/measure_heterogeneity.R +++ b/R/measure_heterogeneity.R @@ -34,6 +34,7 @@ NULL #' network_richness(mpn_bristol) #' @export network_richness <- function(.data, attribute){ + if(missing(.data)) {expect_nodes(); .data <- .G()} make_network_measure(length(unique(manynet::node_attribute(.data, attribute))), .data) } @@ -43,6 +44,7 @@ network_richness <- function(.data, attribute){ #' node_richness(mpn_bristol, "type") #' @export node_richness <- function(.data, attribute){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- vapply(manynet::to_egos(.data, min_dist = 1), function(x) length(unique(manynet::node_attribute(x, attribute))), FUN.VALUE = numeric(1)) @@ -75,6 +77,7 @@ node_richness <- function(.data, attribute){ #' network_diversity(marvel_friends, "Gender", "Rich") #' @export network_diversity <- function(.data, attribute, clusters = NULL){ + if(missing(.data)) {expect_nodes(); .data <- .G()} blau <- function(features) { 1 - sum((table(features)/length(features))^2) } attr <- manynet::node_attribute(.data, attribute) if (is.null(clusters)) { @@ -101,6 +104,7 @@ network_diversity <- function(.data, attribute, clusters = NULL){ #' node_diversity(marvel_friends, "Attractive") #' @export node_diversity <- function(.data, attribute){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- vapply(igraph::ego(manynet::as_igraph(.data)), function(x) network_diversity( igraph::induced_subgraph(manynet::as_igraph(.data), x), @@ -127,6 +131,7 @@ node_diversity <- function(.data, attribute){ #' network_heterophily(marvel_friends, "Attractive") #' @export network_heterophily <- function(.data, attribute){ + if(missing(.data)) {expect_nodes(); .data <- .G()} m <- manynet::as_matrix(.data) if (length(attribute) == 1 && is.character(attribute)) { attribute <- manynet::node_attribute(.data, attribute) @@ -147,6 +152,7 @@ network_heterophily <- function(.data, attribute){ #' node_heterophily(marvel_friends, "Attractive") #' @export node_heterophily <- function(.data, attribute){ + if(missing(.data)) {expect_nodes(); .data <- .G()} m <- manynet::as_matrix(.data) if (length(attribute) == 1 && is.character(attribute)) { attribute <- manynet::node_attribute(.data, attribute) @@ -172,6 +178,7 @@ node_heterophily <- function(.data, attribute){ #' network_assortativity(mpn_elite_mex) #' @export network_assortativity <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} make_network_measure(igraph::assortativity_degree(manynet::as_igraph(.data), directed = manynet::is_directed(.data)), .data) @@ -187,6 +194,7 @@ network_assortativity <- function(.data){ #' network_spatial(ison_lawfirm, "age") #' @export network_spatial <- function(.data, attribute){ + if(missing(.data)) {expect_nodes(); .data <- .G()} N <- manynet::network_nodes(.data) x <- manynet::node_attribute(.data, attribute) stopifnot(is.numeric(x)) diff --git a/R/measure_hierarchy.R b/R/measure_hierarchy.R index ea6861f9..f698ccfd 100644 --- a/R/measure_hierarchy.R +++ b/R/measure_hierarchy.R @@ -33,6 +33,7 @@ NULL #' @rdname hierarchy #' @export network_connectedness <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} dists <- igraph::distances(manynet::as_igraph(.data)) make_network_measure(1 - sum(dists==Inf)/sum(dists!=0), .data) @@ -41,6 +42,7 @@ network_connectedness <- function(.data){ #' @rdname hierarchy #' @export network_efficiency <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} degs <- node_indegree(.data, normalized = FALSE) out <- (manynet::network_nodes(.data)-1)/sum(degs) make_network_measure(out, .data) @@ -49,6 +51,7 @@ network_efficiency <- function(.data) { #' @rdname hierarchy #' @export network_upperbound <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} dists <- igraph::distances(.data, mode = "in") dists[is.infinite(dists)] <- 0 dists <- dists[order(rowSums(dists)), order(rowSums(dists))] diff --git a/R/measure_holes.R b/R/measure_holes.R index 25c05ed2..093ed556 100644 --- a/R/measure_holes.R +++ b/R/measure_holes.R @@ -49,6 +49,7 @@ NULL #' node_bridges(ison_southern_women) #' @export node_bridges <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} g <- manynet::as_igraph(.data) .inc <- NULL out <- vapply(igraph::V(g), function(ego){ @@ -72,6 +73,7 @@ node_bridges <- function(.data){ #' node_redundancy(ison_southern_women) #' @export node_redundancy <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(manynet::is_twomode(.data)){ mat <- manynet::as_matrix(.data) out <- c(.redund2(mat), .redund2(t(mat))) @@ -110,6 +112,7 @@ node_redundancy <- function(.data){ #' node_effsize(ison_southern_women) #' @export node_effsize <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(manynet::is_twomode(.data)){ mat <- manynet::as_matrix(.data) out <- c(rowSums(manynet::as_matrix(manynet::to_mode1(.data))>0), @@ -135,6 +138,7 @@ node_effsize <- function(.data){ #' node_efficiency(ison_southern_women) #' @export node_efficiency <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- node_effsize(.data) / node_degree(.data, normalized = FALSE) make_node_measure(as.numeric(out), .data) } @@ -149,6 +153,7 @@ node_efficiency <- function(.data){ #' node_constraint(ison_southern_women) #' @export node_constraint <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} if (manynet::is_twomode(.data)) { get_constraint_scores <- function(mat) { inst <- colnames(mat) @@ -197,6 +202,7 @@ node_constraint <- function(.data) { #' node_hierarchy(ison_southern_women) #' @export node_hierarchy <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} cs <- node_constraint(.data) g <- manynet::as_igraph(.data) out <- vapply(igraph::V(g), function(ego){ @@ -215,6 +221,7 @@ node_hierarchy <- function(.data){ #' @importFrom igraph eccentricity #' @export node_eccentricity <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::eccentricity(manynet::as_igraph(.data), mode = "out") make_node_measure(out, .data) @@ -228,6 +235,7 @@ node_eccentricity <- function(.data){ #' _Proc. Natl. Acad. Sci._ 101: 3747. #' @export node_neighbours_degree <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::knn(manynet::as_igraph(.data), mode = "out")$knn make_node_measure(out, .data) @@ -236,6 +244,7 @@ node_neighbours_degree <- function(.data){ #' @rdname holes #' @export tie_cohesion <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} ties <- igraph::E(.data) coins <- data.frame(heads = igraph::head_of(.data, ties), tails = igraph::tail_of(.data, ties)) diff --git a/R/measure_over.R b/R/measure_over.R index c4b327d2..a66b2fbb 100644 --- a/R/measure_over.R +++ b/R/measure_over.R @@ -14,6 +14,7 @@ NULL over_waves <- function(.data, FUN, ..., attribute = "wave", strategy = "sequential", verbose = FALSE){ + if(missing(.data)) {expect_nodes(); .data <- .G()} oplan <- future::plan(strategy) on.exit(future::plan(oplan), add = TRUE) furrr::future_map_dbl(manynet::to_waves(.data, attribute), function(j) FUN(j, ...), @@ -27,6 +28,7 @@ over_time <- function(.data, FUN, ..., attribute = "time", slice = NULL, strategy = "sequential", verbose = FALSE){ + if(missing(.data)) {expect_nodes(); .data <- .G()} oplan <- future::plan(strategy) on.exit(future::plan(oplan), add = TRUE) out <- furrr::future_map_dbl(manynet::to_slices(.data, attribute, slice), diff --git a/R/member_cliques.R b/R/member_cliques.R index 7c99ced4..834a0932 100644 --- a/R/member_cliques.R +++ b/R/member_cliques.R @@ -57,6 +57,7 @@ NULL #' \doi{10.1016/j.ejor.2020.07.048}. #' @export node_roulette <- function(.data, num_groups, group_size, times = NULL){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(missing(num_groups) & missing(group_size)){ stop(paste("Either `num_groups` must indicate number of groups desired", "or `group_size` must indicate the desired average size of groups.")) diff --git a/R/member_community.R b/R/member_community.R index dd147062..9b42b70f 100644 --- a/R/member_community.R +++ b/R/member_community.R @@ -48,6 +48,7 @@ NULL #' node_optimal(ison_adolescents) #' @export node_optimal <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::cluster_optimal(manynet::as_igraph(.data) )$membership make_node_member(out, .data) @@ -64,6 +65,7 @@ node_optimal <- function(.data){ #' node_kernighanlin(ison_southern_women) #' @export node_kernighanlin <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} # assign groups arbitrarily n <- manynet::network_nodes(.data) group_size <- ifelse(n %% 2 == 0, n/2, (n+1)/2) @@ -126,6 +128,7 @@ node_kernighanlin <- function(.data){ #' node_edge_betweenness(ison_adolescents) #' @export node_edge_betweenness <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- suppressWarnings(igraph::cluster_edge_betweenness( manynet::as_igraph(.data))$membership) make_node_member(out, .data) @@ -147,6 +150,7 @@ node_edge_betweenness <- function(.data){ #' node_fast_greedy(ison_adolescents) #' @export node_fast_greedy <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::cluster_fast_greedy(manynet::as_igraph(.data) )$membership make_node_member(out, .data) @@ -168,6 +172,7 @@ node_fast_greedy <- function(.data){ #' node_leading_eigen(ison_adolescents) #' @export node_leading_eigen <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::cluster_leading_eigen(manynet::as_igraph(.data) )$membership make_node_member(out, .data) @@ -188,6 +193,7 @@ node_leading_eigen <- function(.data){ #' node_walktrap(ison_adolescents) #' @export node_walktrap <- function(.data, times = 50){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::cluster_walktrap(manynet::as_igraph(.data), steps=times)$membership make_node_member(out, .data) @@ -213,6 +219,7 @@ node_walktrap <- function(.data, times = 50){ #' node_infomap(ison_adolescents) #' @export node_infomap <- function(.data, times = 50){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::cluster_infomap(manynet::as_igraph(.data), nb.trials = times )$membership @@ -247,6 +254,7 @@ node_infomap <- function(.data, times = 50){ #' node_spinglass(ison_adolescents) #' @export node_spinglass <- function(.data, max_k = 200, resolution = 1){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::cluster_spinglass(manynet::as_igraph(.data), spins = max_k, gamma = resolution, implementation = ifelse(manynet::is_signed(.data), "neg", "orig") @@ -271,6 +279,7 @@ node_spinglass <- function(.data, max_k = 200, resolution = 1){ #' node_fluid(ison_adolescents) #' @export node_fluid <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} .data <- as_igraph(.data) mods <- vapply(seq.int(manynet::network_nodes(.data)), function(x) igraph::modularity(.data, membership = igraph::membership( @@ -297,6 +306,7 @@ node_fluid <- function(.data) { #' node_louvain(ison_adolescents) #' @export node_louvain <- function(.data, resolution = 1){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- igraph::cluster_louvain(manynet::as_igraph(.data), resolution = resolution )$membership @@ -327,6 +337,7 @@ node_louvain <- function(.data, resolution = 1){ #' node_leiden(ison_adolescents) #' @export node_leiden <- function(.data, resolution = 1){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(manynet::is_weighted(.data)){ # Traag resolution default n <- manynet::network_nodes(.data) resolution <- sum(manynet::tie_weights(.data))/(n*(n - 1)/2) diff --git a/R/member_components.R b/R/member_components.R index 3190646d..aa837bb5 100644 --- a/R/member_components.R +++ b/R/member_components.R @@ -39,6 +39,7 @@ NULL #' node_components(mpn_bristol) #' @export node_components <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) make_node_member(igraph::components(.data, mode = "strong")$membership, .data) @@ -48,6 +49,7 @@ node_components <- function(.data){ #' @importFrom igraph components #' @export node_weak_components <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) make_node_member(igraph::components(.data, mode = "weak")$membership, .data) @@ -57,6 +59,7 @@ node_weak_components <- function(.data){ #' @importFrom igraph components #' @export node_strong_components <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) make_node_member(igraph::components(.data, mode = "strong")$membership, .data) diff --git a/R/member_core.R b/R/member_core.R index a4feea22..d07bf954 100644 --- a/R/member_core.R +++ b/R/member_core.R @@ -44,6 +44,7 @@ NULL #' network_core(mpn_elite_usa_advice) #' @export node_core <- function(.data, method = c("degree", "eigenvector")){ + if(missing(.data)) {expect_nodes(); .data <- .G()} method <- match.arg(method) if(manynet::is_directed(.data)) warning("Asymmetric core-periphery not yet implemented.") if(method == "degree"){ @@ -73,6 +74,7 @@ node_core <- function(.data, method = c("degree", "eigenvector")){ #' node_coreness(ison_adolescents) #' @export node_coreness <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(!manynet::is_graph(.data)) .data <- manynet::as_igraph(.data) out <- igraph::coreness(.data) make_node_member(out, .data) diff --git a/R/model_cluster.R b/R/model_cluster.R index d9d4575d..e010ee17 100644 --- a/R/model_cluster.R +++ b/R/model_cluster.R @@ -55,6 +55,7 @@ cluster_hierarchical <- function(census, distance){ #' \doi{10.1016/0022-2496(75)90028-0}. #' @export cluster_concor <- function(.data, census){ + if(missing(.data)) {expect_nodes(); .data <- .G()} split_cor <- function(m0, cutoff = 1) { if (ncol(m0) < 2 | all(to_correlation(m0)==1)) list(m0) else { diff --git a/R/model_tests.R b/R/model_tests.R index 39b054e7..e6b90590 100644 --- a/R/model_tests.R +++ b/R/model_tests.R @@ -33,6 +33,7 @@ test_random <- function(.data, FUN, ..., times = 1000, strategy = "sequential", verbose = FALSE){ + if(missing(.data)) {expect_nodes(); .data <- .G()} args <- unlist(list(...)) if (!is.null(args)) { obsd <- FUN(.data, args) @@ -82,6 +83,7 @@ test_permutation <- function(.data, FUN, ..., times = 1000, strategy = "sequential", verbose = FALSE){ + if(missing(.data)) {expect_nodes(); .data <- .G()} args <- unlist(list(...)) if (!is.null(args)) { obsd <- FUN(.data, args) diff --git a/R/motif_census.R b/R/motif_census.R index ecbde57d..0dfa3bab 100644 --- a/R/motif_census.R +++ b/R/motif_census.R @@ -28,6 +28,7 @@ NULL #' (tie_cen <- node_tie_census(task_eg)) #' @export node_tie_census <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} object <- manynet::as_igraph(.data) # edge_names <- manynet::network_tie_attributes(object) if (manynet::is_directed(object)) { @@ -91,6 +92,7 @@ node_tie_census <- function(.data){ #' (triad_cen <- node_triad_census(task_eg)) #' @export node_triad_census <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} out <- t(sapply(seq.int(manynet::network_nodes(.data)), function(x) network_triad_census(.data) - network_triad_census(manynet::delete_nodes(.data, x)))) rownames(out) <- manynet::node_names(.data) @@ -134,6 +136,7 @@ node_triad_census <- function(.data){ #' node_quad_census(manynet::ison_southern_women) #' @export node_quad_census <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if (!("oaqc" %in% rownames(utils::installed.packages()))) { message("Please install package `{oaqc}`.") } else { @@ -207,6 +210,7 @@ node_quad_census <- function(.data){ #' node_path_census(manynet::ison_southern_women) #' @export node_path_census <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(manynet::is_weighted(.data)){ tore <- manynet::as_matrix(.data)/mean(manynet::as_matrix(.data)) out <- 1/tore @@ -239,6 +243,7 @@ NULL #' network_dyad_census(manynet::ison_algebra) #' @export network_dyad_census <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} if (manynet::is_twomode(.data)) { stop("A twomode or multilevel option for a dyad census is not yet implemented.") } else { @@ -258,6 +263,7 @@ network_dyad_census <- function(.data) { #' network_triad_census(manynet::ison_adolescents) #' @export network_triad_census <- function(.data) { + if(missing(.data)) {expect_nodes(); .data <- .G()} if (manynet::is_twomode(.data)) { stop("A twomode or multilevel option for a triad census is not yet implemented.") } else { @@ -283,6 +289,7 @@ network_triad_census <- function(.data) { #' (mixed_cen <- network_mixed_census(marvel_friends, manynet::ison_marvel_teams)) #' @export network_mixed_census <- function (.data, object2) { + if(missing(.data)) {expect_nodes(); .data <- .G()} if(manynet::is_twomode(.data)) stop("First object should be a one-mode network") if(!manynet::is_twomode(object2)) @@ -357,6 +364,7 @@ NULL #' node_brokerage_census(manynet::ison_networkers, "Discipline") #' @export node_brokerage_census <- function(.data, membership, standardized = FALSE){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(!manynet::is_twomode(.data)){ out <- sna::brokerage(manynet::as_network(.data), manynet::node_attribute(.data, membership)) @@ -379,6 +387,7 @@ node_brokerage_census <- function(.data, membership, standardized = FALSE){ #' network_brokerage_census(manynet::ison_networkers, "Discipline") #' @export network_brokerage_census <- function(.data, membership, standardized = FALSE){ + if(missing(.data)) {expect_nodes(); .data <- .G()} if(!manynet::is_twomode(.data)){ out <- sna::brokerage(manynet::as_network(.data), manynet::node_attribute(.data, membership)) @@ -404,6 +413,7 @@ network_brokerage_census <- function(.data, membership, standardized = FALSE){ #' \doi{10.1016/j.socnet.2019.08.002} #' @export node_brokering_activity <- function(.data, membership){ + if(missing(.data)) {expect_nodes(); .data <- .G()} from <- to.y <- to_memb <- from_memb <- NULL twopaths <- .to_twopaths(.data) if(!missing(membership)){ @@ -429,6 +439,7 @@ node_brokering_activity <- function(.data, membership){ #' node_brokering_exclusivity(ison_networkers, "Discipline") #' @export node_brokering_exclusivity <- function(.data, membership){ + if(missing(.data)) {expect_nodes(); .data <- .G()} from <- to.y <- to_memb <- from_memb <- NULL twopaths <- .to_twopaths(.data) if(!missing(membership)){ @@ -454,6 +465,7 @@ node_brokering_exclusivity <- function(.data, membership){ #' @rdname brokerage_census #' @export node_brokering <- function(.data, membership){ + if(missing(.data)) {expect_nodes(); .data <- .G()} activ <- node_brokering_activity(.data, membership) exclusiv <- node_brokering_exclusivity(.data, membership) activ <- activ - mean(activ) diff --git a/R/motif_correlation.R b/R/motif_correlation.R index c9b62ddd..bc4eadb5 100644 --- a/R/motif_correlation.R +++ b/R/motif_correlation.R @@ -17,6 +17,7 @@ #' @family motifs #' @export to_correlation <- function(.data){ + if(missing(.data)) {expect_nodes(); .data <- .G()} mat <- manynet::as_matrix(.data) if(manynet::is_twomode(.data)){ # if(!any(colnames(m0) %in% rownames(m0))) From a878a56234a12c9fb9ed60a4c0121f6716035f23 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 23 May 2024 17:22:37 +0200 Subject: [PATCH 19/97] Added argument to overwrite default behaviour in to_correlation() --- R/motif_correlation.R | 30 ++++++++++++++++++------------ man/node_correlation.Rd | 9 ++++++++- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/R/motif_correlation.R b/R/motif_correlation.R index bc4eadb5..7e2a060b 100644 --- a/R/motif_correlation.R +++ b/R/motif_correlation.R @@ -14,22 +14,28 @@ #' This function runs in \eqn{O(mn^2)} complexity. #' @name node_correlation #' @inheritParams cohesion +#' @param method One of the following: +#' "all" includes all information, +#' "diag" excludes the diagonal (self-ties), +#' "recip" excludes the diagonal but compares pairs' reciprocal ties, +#' and "complex" compares pairs' reciprocal ties and their self ties. +#' By default the appropriate method is chosen based on the network format. #' @family motifs #' @export -to_correlation <- function(.data){ +to_correlation <- function(.data, method = NULL){ if(missing(.data)) {expect_nodes(); .data <- .G()} mat <- manynet::as_matrix(.data) - if(manynet::is_twomode(.data)){ - # if(!any(colnames(m0) %in% rownames(m0))) - # mat <- node_tie_census(mat) - out <- .corTwomode(mat) - } else if(manynet::is_complex(.data)){ - out <- .corComplex(mat) - } else if(manynet::is_directed(.data)){ - out <- .corRecip(mat) - } else { - out <- .corDiag(mat) - } + if(is.null(method)) method <- ifelse(manynet::is_twomode(.data), + "all", + ifelse(manynet::is_complex(.data), + "complex", + ifelse(manynet::is_directed(.data), + "recip", "diag"))) + out <- switch(method, + all = .corTwomode(mat), + complex = .corComplex(mat), + recip = .corRecip(mat), + diag = .corDiag(mat)) out } diff --git a/man/node_correlation.Rd b/man/node_correlation.Rd index b83fa09a..9713b18c 100644 --- a/man/node_correlation.Rd +++ b/man/node_correlation.Rd @@ -5,7 +5,7 @@ \alias{to_correlation} \title{Node correlation} \usage{ -to_correlation(.data) +to_correlation(.data, method = NULL) } \arguments{ \item{.data}{An object of a \code{{manynet}}-consistent class: @@ -16,6 +16,13 @@ to_correlation(.data) \item network, from the \code{{network}} package \item tbl_graph, from the \code{{tidygraph}} package }} + +\item{method}{One of the following: +"all" includes all information, +"diag" excludes the diagonal (self-ties), +"recip" excludes the diagonal but compares pairs' reciprocal ties, +and "complex" compares pairs' reciprocal ties and their self ties. +By default the appropriate method is chosen based on the network format.} } \description{ This function performs a Pearson pairwise correlation on a given matrix or network data. From bb91b88db5141ab8174c87f0d4bbf0efba27a4e7 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 23 May 2024 17:22:59 +0200 Subject: [PATCH 20/97] Fixed node_member tests --- tests/testthat/test-member_community.R | 2 +- tests/testthat/test-member_equivalence.R | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test-member_community.R b/tests/testthat/test-member_community.R index 61448a4d..0975866b 100644 --- a/tests/testthat/test-member_community.R +++ b/tests/testthat/test-member_community.R @@ -2,7 +2,7 @@ test_that("node_kernighanlin algorithm works", { expect_s3_class(node_kernighanlin(mpn_elite_mex), "node_member") expect_length(node_kernighanlin(mpn_elite_mex), network_nodes(mpn_elite_mex)) - expect_false(any(node_kernighanlin(mpn_elite_mex) > 2)) + expect_false(any(node_kernighanlin(mpn_elite_mex) > "B")) }) test_that("node_edge_betweenness algorithm works", { diff --git a/tests/testthat/test-member_equivalence.R b/tests/testthat/test-member_equivalence.R index af64de95..2d0a2124 100644 --- a/tests/testthat/test-member_equivalence.R +++ b/tests/testthat/test-member_equivalence.R @@ -19,7 +19,9 @@ test_that("equivalence clustering works", { expect_equal(network_nodes(mpn_elite_mex), length(node_regular_equivalence(mpn_elite_mex, "strict"))) expect_equal(network_nodes(mpn_elite_usa_advice), length(node_automorphic_equivalence(mpn_elite_usa_advice, "strict", distance = "binary"))) expect_equal(network_nodes(mpn_elite_usa_advice), length(node_automorphic_equivalence(mpn_elite_usa_advice, distance = "maximum"))) - expect_true(3 %in% node_structural_equivalence(ison_adolescents, k = 3, "concor")) - expect_true(2 %in% node_regular_equivalence(mpn_elite_mex, 2)) - expect_true(3 %in% node_automorphic_equivalence(mpn_elite_usa_advice, 4)) + expect_true("C" %in% node_structural_equivalence(ison_adolescents, k = 3, "concor")) + expect_true("B" %in% node_regular_equivalence(mpn_elite_mex, 2)) + expect_true("D" %in% node_automorphic_equivalence(mpn_elite_usa_advice, 4)) +}) + }) From d153c725a87c92d4f7c6d4fb23b111721197a77b Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 23 May 2024 17:23:13 +0200 Subject: [PATCH 21/97] Added tests for to_correlation() --- tests/testthat/test-member_equivalence.R | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/testthat/test-member_equivalence.R b/tests/testthat/test-member_equivalence.R index 2d0a2124..308326f0 100644 --- a/tests/testthat/test-member_equivalence.R +++ b/tests/testthat/test-member_equivalence.R @@ -24,4 +24,13 @@ test_that("equivalence clustering works", { expect_true("D" %in% node_automorphic_equivalence(mpn_elite_usa_advice, 4)) }) +# from Traxler et al 2020 +fig2 <- manynet::create_explicit(A--B, A--C, B--C, B--D, B--E, B--F, D--E) + +test_that("to_correlation works", { + expect_equal(to_correlation(fig2)["A","F"], 0.5773503, tolerance = 0.005) + expect_equal(to_correlation(fig2, "diag")["A","F"], 0.5773503, tolerance = 0.005) + expect_equal(to_correlation(fig2, "recip")["A","F"], 0.6123724, tolerance = 0.005) + expect_equal(to_correlation(fig2, "all")["A","B"], -0.6324555, tolerance = 0.005) + expect_equal(to_correlation(fig2, "complex")["A","B"], 0.3162278, tolerance = 0.005) }) From ad67d1408d0e1d1ee2514e493e7c59c6c5b79af2 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 23 May 2024 17:45:20 +0200 Subject: [PATCH 22/97] Fixed bug where print.node_motif() wasn't printing the requested number of lines --- R/class_motifs.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/class_motifs.R b/R/class_motifs.R index 52dec104..75d7fc42 100644 --- a/R/class_motifs.R +++ b/R/class_motifs.R @@ -12,16 +12,16 @@ make_network_motif <- function(out, .data) { #' @export print.node_motif <- function(x, ..., - max.length = 6, + n = 6, digits = 3) { if(!is.null(attr(x, "dimnames")[[1]])){ x <- data.frame(names = attr(x, "dimnames")[[1]], x) } if (any(attr(x, "mode"))) { - print(dplyr::tibble(as.data.frame(x)[!attr(x, "mode")])) - print(dplyr::tibble(as.data.frame(x)[attr(x, "mode")])) + print(dplyr::tibble(as.data.frame(x)[!attr(x, "mode")]), n = n) + print(dplyr::tibble(as.data.frame(x)[attr(x, "mode")]), n = n) } else { - print(dplyr::tibble(as.data.frame(x))) + print(dplyr::tibble(as.data.frame(x)), n = n) } } From 6eb9ec71997d260c8424041af6d004682c5455fe Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 23 May 2024 20:52:00 +0200 Subject: [PATCH 23/97] Fixed remaining documentation bugs --- R/model_cluster.R | 4 ++-- R/motif_census.R | 41 +++++++++++++++++++---------------------- R/motif_correlation.R | 4 ++-- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/R/model_cluster.R b/R/model_cluster.R index e010ee17..876629ba 100644 --- a/R/model_cluster.R +++ b/R/model_cluster.R @@ -78,8 +78,8 @@ cluster_concor <- function(.data, census){ colnames(p_list[[1]]) <- paste0("V",1:ncol(p_list[[1]])) p_group <- list() if(manynet::is_twomode(.data)){ - p_list <- list(p_list[[1]][node_mode(.data), !node_mode(.data), drop = FALSE], - p_list[[1]][!node_mode(.data), node_mode(.data), drop = FALSE]) + p_list <- list(p_list[[1]][, !manynet::node_mode(.data), drop = FALSE], + p_list[[1]][, manynet::node_mode(.data), drop = FALSE]) p_group[[i]] <- lapply(p_list, function(z) colnames(z)) i <- 2 } else i <- 1 diff --git a/R/motif_census.R b/R/motif_census.R index 0dfa3bab..2fca8942 100644 --- a/R/motif_census.R +++ b/R/motif_census.R @@ -137,28 +137,25 @@ node_triad_census <- function(.data){ #' @export node_quad_census <- function(.data){ if(missing(.data)) {expect_nodes(); .data <- .G()} - if (!("oaqc" %in% rownames(utils::installed.packages()))) { - message("Please install package `{oaqc}`.") - } else { - graph <- .data %>% manynet::as_tidygraph() %E>% - as.data.frame() - out <- oaqc::oaqc(graph)[[1]] - out <- out[-1,] - rownames(out) <- manynet::node_names(.data) - colnames(out) <- c("E4", # co-K4 - "I41","I40", # co-diamond - "H4", # co-C4 - "L42","L41","L40", # co-paw - "D42","D40", # co-claw - "U42","U41", # P4 - "Y43","Y41", # claw - "P43","P42","P41", # paw - "04", # C4 - "Z42","Z43", # diamond - "X4") # K4 - if(manynet::is_twomode(.data)) out <- out[,-c(8,9,14,15,16,18,19,20)] - make_node_motif(out, .data) - } + thisRequires("oaqc") + graph <- .data %>% manynet::as_tidygraph() %E>% + as.data.frame() + out <- oaqc::oaqc(graph)[[1]] + out <- out[-1,] + rownames(out) <- manynet::node_names(.data) + colnames(out) <- c("E4", # co-K4 + "I41","I40", # co-diamond + "H4", # co-C4 + "L42","L41","L40", # co-paw + "D42","D40", # co-claw + "U42","U41", # P4 + "Y43","Y41", # claw + "P43","P42","P41", # paw + "04", # C4 + "Z42","Z43", # diamond + "X4") # K4 + if(manynet::is_twomode(.data)) out <- out[,-c(8,9,14,15,16,18,19,20)] + make_node_motif(out, .data) } # #' @export diff --git a/R/motif_correlation.R b/R/motif_correlation.R index 7e2a060b..ab09c93e 100644 --- a/R/motif_correlation.R +++ b/R/motif_correlation.R @@ -57,7 +57,7 @@ to_correlation <- function(.data, method = NULL){ # Though warnings need to be suppressed, # this is bench::mark()ed at about 2 times faster than corrColsRecipRLB() .corRecip <- function(M){ - all.pairs <- combn(1:ncol(M),2) + all.pairs <- utils::combn(1:ncol(M),2) corres <- apply(all.pairs, 2, function(i){ x <- c(M[-i,i[1]], M[i[1],i[2]]) y <- c(M[-i,i[2]], M[i[2],i[1]]) @@ -76,7 +76,7 @@ to_correlation <- function(.data, method = NULL){ # Though warnings need to be suppressed, # this is bench::mark()ed at about 2.3 times faster than corrColsRecipUCI() .corComplex <- function(M){ - all.pairs <- combn(1:ncol(M),2) + all.pairs <- utils::combn(1:ncol(M),2) corres <- apply(all.pairs, 2, function(i){ x <- c(M[-i,i[1]], M[i[1],i[2]], M[i[1],i[1]]) y <- c(M[-i,i[2]], M[i[2],i[1]], M[i[2],i[2]]) From d4599765ba5072817eff041d2e17513903491768 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 23 May 2024 20:52:20 +0200 Subject: [PATCH 24/97] Developed migraph README further --- README.Rmd | 49 ++++++++++++++++++++++++++++++++++++------ README.md | 62 ++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 17 deletions(-) diff --git a/README.Rmd b/README.Rmd index aa32e8da..a60d7c0a 100644 --- a/README.Rmd +++ b/README.Rmd @@ -47,11 +47,11 @@ or require one or more other specific packages. Translating between packages various syntaxes and expectations can introduce significant transaction costs though, driving confusion, inefficiencies, and errors. -`{migraph}` builds upon `{manynet}` to offer smart solutions to these problems. -It includes functions for marking and measuring networks and their nodes and ties, +`{migraph}` builds upon [`{manynet}`](https://stocnet.github.io/manynet/) to offer smart solutions to these problems. +`{migraph}` includes functions for measuring networks and their nodes and ties, identifying motifs and memberships in them, and modelling these networks or simulating processes such as diffusion upon them. -Based on `{manynet}`, every function works for any compatible network format +Since it is based on `{manynet}`, every function works for any compatible network format - from base R matrices or edgelists as data frames, [`{igraph}`](https://igraph.org/r/), [`{network}`](https://statnet.org), or @@ -60,6 +60,21 @@ This means it is compatible with your existing workflow, is extensible by other packages, and uses the most efficient algorithm available for each task. +- [About the package](#about-the-package) + - [Package background](#package-background) +- [How does migraph help?](#how-does-migraph-help) + - [Measures](#measures) + - [Motifs and Memberships](#motifs-and-memberships) + - [Models](#models) +- [Installation](#installation) + - [Stable](#stable) + - [Development](#development) + - [Tutorials](#tutorials) +- [Relationship to other packages](#relationship-to-other-packages) +- [Funding details](#funding-details) + +### Package background + The package is intended as a software companion to the book: @@ -74,9 +89,11 @@ if you like the package please check out the book, and vice versa. ## How does migraph help? -`{migraph}` includes five special groups of functions, +`{migraph}` includes four special groups of functions, each with their own pretty `print()` and `plot()` methods: -marks, measures, memberships, motifs, and models. +measures, memberships, motifs, and models. +Measures are numeric scalars or vectors, memberships categorical, +and motifs and models result in tabular outputs. `{migraph}` uses a common syntax to help new and experienced network analysts find the right function and use it correctly. @@ -110,18 +127,25 @@ Please explore [the list of functions](https://stocnet.github.io/migraph/referen ### Motifs and Memberships -The package also include functions for returning various censuses +The package also include functions for returning various censuses of motifs at the network or node level, e.g.: - `r list_functions("network_.*_census")` - `r list_functions("node_.*_census")` +For example `node_brokerage_census()` returns +the frequency of nodes' participation in +Gould-Fernandez brokerage roles for a one-mode network, +and the Jasny-Lubell brokerage roles for a two-mode network. + These can be analysed alone, or used as a profile for establishing equivalence. `{migraph}` offers both HCA and CONCOR algorithms, as well as elbow, silhouette, and strict methods for _k_-cluster selection. - `r list_functions("node.*_equivalence")` +![](https://www.jameshollway.com/post/migraph/dendroPlot.png) + `{migraph}` also includes functions for establishing membership on other bases, such as typical community detection algorithms, as well as component and core-periphery partitioning algorithms. @@ -133,11 +157,15 @@ or quadratic assignment procedure (QAP) distributions using: - `r list_functions("^test_")` +![](https://www.jameshollway.com/post/migraph/tests-2.png) + Hypotheses can also be tested within multivariate models via multiple (linear or logistic) regression QAP: - `network_reg()` +![](https://www.jameshollway.com/post/migraph/regression-1.png) + `{migraph}` is the only package that offers these testing frameworks for two-mode networks as well as one-mode networks. @@ -156,6 +184,15 @@ You can then begin to use `{migraph}` by loading the package: This will load any required packages and make the data contained within the package available. +`{migraph}` relies on some packages only for one or two rather specific functions. +By default these are not installed together with `{migraph}`, +but we make it easy to install them as and when needed for the first time with a console prompt. +If you would prefer not to encounter these prompts, +or plan to use the package for the first time through tutorials, +you can make sure all the dependencies are installed with: + +`install.packages('migraph', dependencies = TRUE)` + ### Development For the latest development version, diff --git a/README.md b/README.md index 8bef8ff3..04c4265e 100644 --- a/README.md +++ b/README.md @@ -36,18 +36,35 @@ require one or more other specific packages. Translating between packages various syntaxes and expectations can introduce significant transaction costs though, driving confusion, inefficiencies, and errors. -`{migraph}` builds upon `{manynet}` to offer smart solutions to these -problems. It includes functions for marking and measuring networks and -their nodes and ties, identifying motifs and memberships in them, and -modelling these networks or simulating processes such as diffusion upon -them. Based on `{manynet}`, every function works for any compatible -network format - from base R matrices or edgelists as data frames, +`{migraph}` builds upon +[`{manynet}`](https://stocnet.github.io/manynet/) to offer smart +solutions to these problems. `{migraph}` includes functions for +measuring networks and their nodes and ties, identifying motifs and +memberships in them, and modelling these networks or simulating +processes such as diffusion upon them. Since it is based on `{manynet}`, +every function works for any compatible network format - from base R +matrices or edgelists as data frames, [`{igraph}`](https://igraph.org/r/), [`{network}`](https://statnet.org), or [`{tidygraph}`](https://tidygraph.data-imaginist.com/index.html) objects. This means it is compatible with your existing workflow, is extensible by other packages, and uses the most efficient algorithm available for each task. +- [About the package](#about-the-package) + - [Package background](#package-background) +- [How does migraph help?](#how-does-migraph-help) + - [Measures](#measures) + - [Motifs and Memberships](#motifs-and-memberships) + - [Models](#models) +- [Installation](#installation) + - [Stable](#stable) + - [Development](#development) + - [Tutorials](#tutorials) +- [Relationship to other packages](#relationship-to-other-packages) +- [Funding details](#funding-details) + +### Package background + The package is intended as a software companion to the book: @@ -64,9 +81,10 @@ you like the package please check out the book, and vice versa. ## How does migraph help? -`{migraph}` includes five special groups of functions, each with their -own pretty `print()` and `plot()` methods: marks, measures, memberships, -motifs, and models. +`{migraph}` includes four special groups of functions, each with their +own pretty `print()` and `plot()` methods: measures, memberships, +motifs, and models. Measures are numeric scalars or vectors, memberships +categorical, and motifs and models result in tabular outputs. `{migraph}` uses a common syntax to help new and experienced network analysts find the right function and use it correctly. All `network_*()` @@ -108,14 +126,18 @@ find out more. ### Motifs and Memberships -The package also include functions for returning various censuses at the -network or node level, e.g.: +The package also include functions for returning various censuses of +motifs at the network or node level, e.g.: - `network_brokerage_census()`, `network_dyad_census()`, `network_mixed_census()`, `network_triad_census()` - `node_brokerage_census()`, `node_path_census()`, `node_quad_census()`, `node_tie_census()`, `node_triad_census()` +For example `node_brokerage_census()` returns the frequency of nodes’ +participation in Gould-Fernandez brokerage roles for a one-mode network, +and the Jasny-Lubell brokerage roles for a two-mode network. + These can be analysed alone, or used as a profile for establishing equivalence. `{migraph}` offers both HCA and CONCOR algorithms, as well as elbow, silhouette, and strict methods for *k*-cluster selection. @@ -123,6 +145,8 @@ as elbow, silhouette, and strict methods for *k*-cluster selection. - `node_automorphic_equivalence()`, `node_equivalence()`, `node_regular_equivalence()`, `node_structural_equivalence()` +![](https://www.jameshollway.com/post/migraph/dendroPlot.png) + `{migraph}` also includes functions for establishing membership on other bases, such as typical community detection algorithms, as well as component and core-periphery partitioning algorithms. @@ -134,11 +158,15 @@ quadratic assignment procedure (QAP) distributions using: - `test_gof()`, `test_permutation()`, `test_random()` +![](https://www.jameshollway.com/post/migraph/tests-2.png) + Hypotheses can also be tested within multivariate models via multiple (linear or logistic) regression QAP: - `network_reg()` +![](https://www.jameshollway.com/post/migraph/regression-1.png) + `{migraph}` is the only package that offers these testing frameworks for two-mode networks as well as one-mode networks. @@ -158,6 +186,15 @@ You can then begin to use `{migraph}` by loading the package: This will load any required packages and make the data contained within the package available. +`{migraph}` relies on some packages only for one or two rather specific +functions. By default these are not installed together with `{migraph}`, +but we make it easy to install them as and when needed for the first +time with a console prompt. If you would prefer not to encounter these +prompts, or plan to use the package for the first time through +tutorials, you can make sure all the dependencies are installed with: + +`install.packages('migraph', dependencies = TRUE)` + ### Development For the latest development version, for slightly earlier access to new @@ -208,6 +245,9 @@ run_tute() #> 7 migraph tutorial6 Topology #> 8 manynet tutorial7 Diffusion #> 9 migraph tutorial8 Regression +``` + +``` r # run_tute("tutorial5") ``` From c3626f843da6744f442a8496c2d25b5f3f09d11c Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 23 May 2024 20:52:36 +0200 Subject: [PATCH 25/97] #minor bump and NEWS --- DESCRIPTION | 4 ++-- NEWS.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 8475b8d5..41d1e41e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: migraph Title: Many Network Measures, Motifs, Members, and Models -Version: 1.3.4 -Date: 2024-03-07 +Version: 1.4.0 +Date: 2024-05-23 Description: A set of tools for analysing multimodal networks. It includes functions for measuring centrality, centralization, cohesion, closure, constraint and diversity, diff --git a/NEWS.md b/NEWS.md index 785d8a52..d88b6286 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,47 @@ # migraph 1.3.4 +2024-05-23 + +## Package + +- Updated migraph logo with stocnet address, colorsafe colorway, and larger nodes and ties +- Copied thisRequires() helper into migraph from manynet + +## Measures + +- All measure functions can now be used in e.g. `mutate()` without specifying `.data` + +## Members + +- All membership functions can now be used in e.g. `mutate()` without specifying `.data` +- The `node_member` class is now categorical + - `make_node_member()` now converts numeric results to LETTER character results + - `print.node_member()` now works with categorical membership vectors + - `print.node_member()` now declares how many groups before reporting the vectors +- Fixed `node_constraint()` to work with weighted two-mode networks, thanks to Toshitaka Izumi for spotting this +- Added `network_independence()` for calculating the number of nodes in the largest independent set + +## Motifs + +- `node_tie_census()` now works on longitudinal network data +- Added `to_correlation()` for calculating the Pearson correlation + - This takes a method argument for "all", "diag", "recip", or "complex" + - These are similar to functions implemented by Ron Breiger and shared by him in correspondence + - +- Fixed bug where `print.node_motif()` wasn't printing the requested number of lines + +## Models + +- Several improvements to `cluster_concor()` + - `cluster_concor()` now uses `to_correlation()` for initial correlation + - It still uses `stats::cor()` for subsequent iterations + - Fixed how `cluster_concor()` handles unlabelled networks + - Fixed how `cluster_concor()` handles two-mode networks + - Fixed bug where `cluster_concor()` cutoff resulted in unsplit groups +- `cluster_hierarchical()` now also uses `to_correlation()` + +# migraph 1.3.4 + 2024-03-07 ## Measures From f875229f2f89605f5ec9fdb2d69bcf7313289079 Mon Sep 17 00:00:00 2001 From: Henrique Sposito Date: Fri, 24 May 2024 09:44:36 +0200 Subject: [PATCH 26/97] Fixed small issue with `cluster_concor()` --- R/model_cluster.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/model_cluster.R b/R/model_cluster.R index 876629ba..dcbe69c2 100644 --- a/R/model_cluster.R +++ b/R/model_cluster.R @@ -80,7 +80,7 @@ cluster_concor <- function(.data, census){ if(manynet::is_twomode(.data)){ p_list <- list(p_list[[1]][, !manynet::node_mode(.data), drop = FALSE], p_list[[1]][, manynet::node_mode(.data), drop = FALSE]) - p_group[[i]] <- lapply(p_list, function(z) colnames(z)) + p_group[[1]] <- lapply(p_list, function(z) colnames(z)) i <- 2 } else i <- 1 while(!all(vapply(p_list, function(x) ncol(x)==1, logical(1)))){ From b39012b37300fe728a40d6e0b481c72b190d505e Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 24 May 2024 11:31:21 +0200 Subject: [PATCH 27/97] Revert "Fixed small issue with `cluster_concor()`" This reverts commit f875229f2f89605f5ec9fdb2d69bcf7313289079. --- R/model_cluster.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/model_cluster.R b/R/model_cluster.R index dcbe69c2..876629ba 100644 --- a/R/model_cluster.R +++ b/R/model_cluster.R @@ -80,7 +80,7 @@ cluster_concor <- function(.data, census){ if(manynet::is_twomode(.data)){ p_list <- list(p_list[[1]][, !manynet::node_mode(.data), drop = FALSE], p_list[[1]][, manynet::node_mode(.data), drop = FALSE]) - p_group[[1]] <- lapply(p_list, function(z) colnames(z)) + p_group[[i]] <- lapply(p_list, function(z) colnames(z)) i <- 2 } else i <- 1 while(!all(vapply(p_list, function(x) ncol(x)==1, logical(1)))){ From f30fa524d7f6517ef11d2a19624f8328a1fae039 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 24 May 2024 11:32:50 +0200 Subject: [PATCH 28/97] Updated migraph version number in NEWS --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index d88b6286..22fbc9b1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# migraph 1.3.4 +# migraph 1.4.0 2024-05-23 From 3aff8fc8fe66e22fc2c70b8a2a0b1ff9ae9bc802 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 24 May 2024 11:39:47 +0200 Subject: [PATCH 29/97] Avoid i undefined issue --- R/model_cluster.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/model_cluster.R b/R/model_cluster.R index 876629ba..302f73a6 100644 --- a/R/model_cluster.R +++ b/R/model_cluster.R @@ -77,6 +77,7 @@ cluster_concor <- function(.data, census){ if(is.null(colnames(p_list[[1]]))) colnames(p_list[[1]]) <- paste0("V",1:ncol(p_list[[1]])) p_group <- list() + i <- NULL if(manynet::is_twomode(.data)){ p_list <- list(p_list[[1]][, !manynet::node_mode(.data), drop = FALSE], p_list[[1]][, manynet::node_mode(.data), drop = FALSE]) From 3f47ac1f739dee0f4263ad8a79d3e941da190b40 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Fri, 24 May 2024 11:57:16 +0200 Subject: [PATCH 30/97] Try again --- R/model_cluster.R | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/R/model_cluster.R b/R/model_cluster.R index 302f73a6..dcbe69c2 100644 --- a/R/model_cluster.R +++ b/R/model_cluster.R @@ -77,11 +77,10 @@ cluster_concor <- function(.data, census){ if(is.null(colnames(p_list[[1]]))) colnames(p_list[[1]]) <- paste0("V",1:ncol(p_list[[1]])) p_group <- list() - i <- NULL if(manynet::is_twomode(.data)){ p_list <- list(p_list[[1]][, !manynet::node_mode(.data), drop = FALSE], p_list[[1]][, manynet::node_mode(.data), drop = FALSE]) - p_group[[i]] <- lapply(p_list, function(z) colnames(z)) + p_group[[1]] <- lapply(p_list, function(z) colnames(z)) i <- 2 } else i <- 1 while(!all(vapply(p_list, function(x) ncol(x)==1, logical(1)))){ From def74ee86c26293bce9fbad7deab24a4b31e2301 Mon Sep 17 00:00:00 2001 From: James Hollway Date: Thu, 13 Jun 2024 22:10:49 +0200 Subject: [PATCH 31/97] Added descriptions to tutorials --- inst/tutorials/tutorial3/centrality.Rmd | 3 + inst/tutorials/tutorial4/community.Rmd | 3 + inst/tutorials/tutorial5/position.Rmd | 3 + inst/tutorials/tutorial5/position.html | 82 +++++++++---------- .../position_data/data_chunks_index.txt | 1 + inst/tutorials/tutorial6/topology.Rmd | 4 + inst/tutorials/tutorial8/regression.Rmd | 4 + 7 files changed, 59 insertions(+), 41 deletions(-) create mode 100644 inst/tutorials/tutorial5/position_data/data_chunks_index.txt diff --git a/inst/tutorials/tutorial3/centrality.Rmd b/inst/tutorials/tutorial3/centrality.Rmd index ee7edcbe..8d806854 100644 --- a/inst/tutorials/tutorial3/centrality.Rmd +++ b/inst/tutorials/tutorial3/centrality.Rmd @@ -5,6 +5,9 @@ output: learnr::tutorial: theme: journal runtime: shiny_prerendered +description: > + This tutorial aims to show how to measure and map degree, betweenness, + closeness, eigenvector and other types of centrality and centralization. --- ```{r setup, include=FALSE} diff --git a/inst/tutorials/tutorial4/community.Rmd b/inst/tutorials/tutorial4/community.Rmd index a7e9003d..95ee3cb0 100644 --- a/inst/tutorials/tutorial4/community.Rmd +++ b/inst/tutorials/tutorial4/community.Rmd @@ -5,6 +5,9 @@ output: learnr::tutorial: theme: journal runtime: shiny_prerendered +description: > + This tutorial aims to teach you how to calculate various cohesion measures, + as well as detect communities using a variety of algorithms. --- ```{r setup, include=FALSE} diff --git a/inst/tutorials/tutorial5/position.Rmd b/inst/tutorials/tutorial5/position.Rmd index 3a5a5fca..6ee5a281 100644 --- a/inst/tutorials/tutorial5/position.Rmd +++ b/inst/tutorials/tutorial5/position.Rmd @@ -5,6 +5,9 @@ output: learnr::tutorial: theme: journal runtime: shiny_prerendered +description: > + This tutorial aims to teach you how to measure structural holes and + identify and interpret structurally equivalent nodes. --- ```{r setup, include = FALSE} diff --git a/inst/tutorials/tutorial5/position.html b/inst/tutorials/tutorial5/position.html index 41817c9b..37f9f87f 100644 --- a/inst/tutorials/tutorial5/position.html +++ b/inst/tutorials/tutorial5/position.html @@ -403,7 +403,7 @@