This function identifies hub nodes in an igraph network based on
degree and betweenness centrality using either z-score or quantile thresholds.
Optionally, it visualizes the classification using a scatter plot with marginal histograms.
Usage
find_hubs(
graph,
method = c("zscore", "quantile"),
degree_threshold = 3,
betweenness_threshold = 1,
degree_quantile = 0.95,
betweenness_quantile = 0.95,
log_transform = TRUE,
plot = TRUE,
focus_color = "darkgreen",
label.size = 12,
hub_names = TRUE,
hub_cex = 3,
gg_extra = list(),
weights = NULL,
weight_type = c("strength", "distance")
)Arguments
- graph
An
igraphobject or a data frame containing a symbolic edge list in the first two columns. Additional columns are considered as edge attributes.- method
Character. Method to identify hubs:
"zscore"(standardized metrics) or"quantile"(empirical percentiles).- degree_threshold
Numeric. Threshold for standardized degree (only used if
method = "zscore").- betweenness_threshold
Numeric. Threshold for standardized betweenness (only used if
method = "zscore").- degree_quantile
Numeric between 0 and 1. Quantile threshold for degree (used if
method = "quantile").- betweenness_quantile
Numeric between 0 and 1. Quantile threshold for betweenness (used if
method = "quantile").- log_transform
Logical. If
TRUE, applies log-transformation to degree and betweenness metrics.- plot
Logical. If
TRUE, generates a plot of the degree vs. betweenness classification.- focus_color
Character. Color to display in the focus area of the plot (hubs region).
- label.size
Numeric. Base font size for plot elements. Passed to
theme_classic.- hub_names
Logical. If
TRUE, adds node labels to identified hubs on the plot.- hub_cex
Numeric. Font size scaling factor for hub labels on the plot.
- gg_extra
List. Additional user-defined layers for the returned ggplot. eg. list(ylim(-2,2), theme_bw(), theme(legend.position = "none"))
- weights
Optional edge weights:
NULL(default) to ignore them, the name of an edge attribute, or a numeric vector of lengthigraph::ecount(graph). When supplied, degree becomes vertex strength and betweenness is computed on edge costs. See netkit-weights.- weight_type
Either
"strength"(default) or"distance". See netkit-weights.
Value
A list with the following components:
plotA scatter plot of degree vs. betweenness with hub nodes highlighted, or
NULLwhenplot = FALSE. The element is always present, so the return shape does not depend on the arguments. Note this is aggExtraPlot(a grid gtable), not aggplot: the scatterplot is passed throughggMarginal()to add the marginal histograms, which assembles it, so it can be printed but not extended with+. To customize it, pass layers throughgg_extra; those are added before the assembly step.methodDescription of the method and thresholds used.
resultA
tibblewith node name, degree, betweenness, transformed metrics, and hub status.graphThe original graph with a new vertex attribute
is_hub.
Edge weights
Functions that can use edge weights take two arguments:
weightsNULL(the default) to ignore edge weights; the name of an edge attribute, such as"weight"; or a numeric vector with one value per edge, inigraph::E(graph)order.weight_type"strength"(the default) if a larger value means a more tightly connected pair – confidence scores, correlations, co-expression, read counts, interaction scores."distance"if a larger value means further apart – costs, dissimilarities, reaction times.
Declaring which you have is not bookkeeping. igraph reads the weight
attribute implicitly and gives it opposite meanings in different functions:
a cost in igraph::betweenness(), igraph::distances(),
igraph::diameter() and igraph::mean_distance(), but a strength in
igraph::cluster_louvain() and the other community detection algorithms.
Attaching a confidence score and letting that happen implicitly therefore
inverts every path-based metric – a high-confidence interaction is treated as
a long distance – while community detection reads the same numbers the way
you intended.
netkit resolves weights and weight_type once per call and derives both a
strength and a distance vector from them, so each metric receives the one it
needs. A "strength" is converted to a distance by reciprocal
(\(1/w\)); a "distance" is converted to a strength by reflection
(\(\max(w) - w + \min(w)\)), which keeps a zero distance finite.
Examples
g <- igraph::sample_pa(80, power = 1.5, directed = FALSE)
res <- find_hubs(g, method = "quantile", plot = FALSE)
res$method
#> [1] "Hub nodes identified by method: quantile with Degree metric threshold = 1.63293809389639 and Betweenness metric threshold = 0.213719350028092 (unweighted)"
head(res$result)
#> # A tibble: 6 × 7
#> node degree strength betweenness degree_metric betweenness_metric is_hub
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <lgl>
#> 1 1 33 33 0.887 3.53 0.635 TRUE
#> 2 2 8 8 0.237 2.20 0.213 FALSE
#> 3 3 4 4 0.418 1.61 0.349 FALSE
#> 4 4 7 7 0.258 2.08 0.229 TRUE
#> 5 5 2 2 0.0253 1.10 0.0250 FALSE
#> 6 6 2 2 0.0500 1.10 0.0488 FALSE
# The returned graph carries an `is_hub` vertex attribute, so results chain.
table(igraph::V(res$graph)$is_hub)
#>
#> FALSE TRUE
#> 77 3