Nothing
#' Extract network backbone using the disparity filter
#'
#' Applies the disparity filter to a weighted edge list. For each edge, it
#' computes an alpha (p-value) from both endpoints and keeps the edge if it
#' is statistically significant from at least one endpoint.
#'
#' The null model asks: given that node \eqn{i} has total strength \eqn{s_i}
#' distributed uniformly across \eqn{k_i} edges, what is the probability that
#' a single edge weight is as large as \eqn{w_{ij}}? The answer is
#' \deqn{\alpha_{ij} = \left(1 - \frac{w_{ij}}{s_i}\right)^{k_i - 1}}
#'
#' An edge is retained if \eqn{\min(\alpha_{ij}, \alpha_{ji}) < \alpha}.
#' Nodes with only one edge always have \eqn{\alpha = 0} and are always kept.
#'
#' @param edges A data frame with at least columns `from`, `to`, and `weight`.
#' Must be an undirected edge list (each pair appears once).
#' @param alpha Numeric. Significance threshold in (0, 1). Default `0.05`.
#'
#' @return The filtered edge data frame with an added `alpha` column (the
#' minimum alpha from the two endpoints).
#'
#' @export
#' @examples
#' edges <- data.frame(
#' from = c("A", "A", "A", "B", "C"),
#' to = c("B", "C", "D", "C", "D"),
#' weight = c(10, 1, 1, 8, 1)
#' )
#' backbone(edges, alpha = 0.05)
backbone <- function(edges, alpha = 0.05) {
check_edges(edges)
if (!is.numeric(alpha) || length(alpha) != 1L || alpha <= 0 || alpha >= 1)
stop("'alpha' must be a single number between 0 and 1 (exclusive), got: ",
alpha, call. = FALSE)
if (nrow(edges) == 0L) {
edges$alpha <- numeric(0)
return(edges)
}
## Strength and degree per node in one O(m) pass: double the edge list
## so every node appears once as "from", then tapply aggregates.
node_both <- c(edges$from, edges$to)
weight_both <- c(edges$weight, edges$weight)
strength <- tapply(weight_both, node_both, sum)
degree <- tapply(rep(1L, length(node_both)), node_both, sum)
## Alpha from node i for edge (i,j): (1 - w/s_i)^(k_i - 1)
## Nodes with degree 1 always get alpha = 0 (always kept)
compute_alpha <- function(node, w) {
s <- strength[node]
k <- degree[node]
if (k <= 1L || s == 0) return(0)
(1 - w / s) ^ (k - 1L)
}
edge_alpha <- pmin(
mapply(compute_alpha, edges$from, edges$weight),
mapply(compute_alpha, edges$to, edges$weight)
)
edges$alpha <- edge_alpha
result <- edges[edge_alpha < alpha, ]
result <- result[order(-result$weight), ]
rownames(result) <- NULL
result
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.