#' Homophilic random graph using BA preferential attachment model
#' @description A graph of n nodes is grown by attaching new nodes each with m
#' edges that are preferentially attached to existing nodes with high
#' degree, depending on the homophily parameters.
#' @param n number of nodes
#' @param m number of edges a new node is connected to
#' @param minority_fraction fraction of nodes that belong to the minority group
#' @param h_ab probability to connect a node from group a with groub b
#' @param h_ba probability to connect a node from group b with groub a. If NULL, h_ab is used.
#' @param directed should a directed network be created
#' @details The code is an adaption of the python code from https://github.com/gesiscss/HomophilicNtwMinorities/
#' @return igraph object
#' @references
#' Karimi, F., Génois, M., Wagner, C., Singer, P., & Strohmaier, M. (2018). Homophily influences ranking of minorities in social networks. Scientific reports, 8(1), 1-12. (https://www.nature.com/articles/s41598-018-29405-7)
#'
#' Espín-Noboa, L., Wagner, C., Strohmaier, M., & Karimi, F. (2022). Inequality and inequity in network-based ranking and recommendation algorithms. Scientific reports, 12(1), 1-14. (https://www.nature.com/articles/s41598-022-05434-1)
#' @author David Schoch
#' #maximally heterophilic network
#' sample_pa_homophilic(n = 50, m = 2,minority_fraction = 0.2,h_ab = 1)
#' #maximally homophilic network
#' sample_pa_homophilic(n = 50, m = 2,minority_fraction = 0.2,h_ab = 0)
#' @export
sample_pa_homophilic <- function(n, m, minority_fraction, h_ab, h_ba = NULL, directed = FALSE) {
if (is.null(h_ba)) {
h_ba <- h_ab
}
h_aa <- 1 - h_ab
h_bb <- 1 - h_ba
minority_attr <- sample(
c(
rep(TRUE, floor(minority_fraction * n)),
rep(FALSE, n - floor(minority_fraction * n))
)
)
g <- igraph::make_empty_graph(n = 0, directed = directed)
g <- igraph::add_vertices(g, n, attr = list(minority = minority_attr))
dist <- matrix(NA, n, n)
dist[outer(minority_attr, minority_attr, "&")] <- h_aa # within minority
dist[outer(!minority_attr, !minority_attr, "&")] <- h_bb # within majority
dist[outer(minority_attr, !minority_attr, "&")] <- h_ab # min->maj
dist[outer(!minority_attr, minority_attr, "&")] <- h_ba # maj->min
target_list <- seq_len(m)
source <- m + 1
while (source <= n) {
deg <- igraph::degree(g)
targets <- pick_targets(deg, source, target_list, dist, m)
if (length(targets != 0)) {
el <- rbind(source, targets)
g <- igraph::add_edges(g, c(el))
}
target_list <- c(target_list, source)
source <- source + 1
}
return(g)
}
pick_targets <- function(deg, source, target_list, dist, m) {
target_prob <- dist[source, target_list] * (deg[target_list] + 1e-5)
if (sum(target_prob > 0) < m) {
return(c())
} else {
targets <- sample(target_list, m, prob = target_prob)
return(targets)
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.