Skip to content

Commit 9c2feae

Browse files
Copilotkrlmlr
andauthored
feat: Add mean_degree() to R (#2415)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: krlmlr <[email protected]> Co-authored-by: Kirill Müller <[email protected]>
1 parent f6acc52 commit 9c2feae

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,7 @@ export(maximal.independent.vertex.sets)
683683
export(maximal_ivs)
684684
export(maximum.bipartite.matching)
685685
export(maximum.cardinality.search)
686+
export(mean_degree)
686687
export(mean_distance)
687688
export(membership)
688689
export(merge_coords)

R/structural-properties.R

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,10 @@ mean_distance <- function(
894894
#' For `max_degree()`, the largest degree in the graph. When no vertices are
895895
#' selected, or when the input is the null graph, zero is returned as this
896896
#' is the smallest possible degree.
897+
#'
898+
#' For `mean_degree()`, the average degree in the graph as a single number.
899+
#' For graphs with no vertices, `NaN` is returned.
900+
#' `r lifecycle::badge("experimental")`
897901
#' @author Gabor Csardi \email{csardi.gabor@@gmail.com}
898902
#' @keywords graphs
899903
#' @family structural.properties
@@ -904,6 +908,7 @@ mean_distance <- function(
904908
#' degree(g)
905909
#' g2 <- sample_gnp(1000, 10 / 1000)
906910
#' max_degree(g2)
911+
#' mean_degree(g2)
907912
#' degree_distribution(g2)
908913
#'
909914
degree <- function(
@@ -951,6 +956,16 @@ max_degree <- function(
951956
)
952957
}
953958

959+
#' @rdname degree
960+
#' @export
961+
#' @cdocs igraph_mean_degree
962+
mean_degree <- function(graph, loops = TRUE) {
963+
mean_degree_impl(
964+
graph = graph,
965+
loops = loops
966+
)
967+
}
968+
954969
#' @rdname degree
955970
#' @param cumulative Logical; whether the cumulative degree distribution is to
956971
#' be calculated.

man/degree.Rd

Lines changed: 9 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-structural-properties.R

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,34 @@ test_that("max_degree() works", {
7272
expect_equal(max_degree(make_empty_graph()), 0)
7373
})
7474

75+
test_that("mean_degree() works", {
76+
# Undirected graph: formula is 2 * edges / vertices
77+
g_undirected <- make_ring(10)
78+
expect_equal(mean_degree(g_undirected), 2)
79+
80+
# Directed graph: formula is edges / vertices
81+
# This graph has edges 1->2, 2->2 (loop), 2->3, so 3 edges / 3 vertices = 1
82+
g_directed <- make_graph(c(1, 2, 2, 2, 2, 3), directed = TRUE)
83+
expect_equal(mean_degree(g_directed), 1)
84+
85+
# Test loops parameter: excluding the self-loop (2->2)
86+
# Without loops: (3 edges - 1 loop) / 3 vertices = 2/3
87+
expect_equal(mean_degree(g_directed, loops = FALSE), 2 / 3)
88+
89+
# Empty graph
90+
expect_true(is.nan(mean_degree(make_empty_graph())))
91+
92+
# Compare with manual calculation for undirected graph
93+
g_random <- sample_gnp(100, 0.05)
94+
manual_mean <- 2 * ecount(g_random) / vcount(g_random)
95+
expect_equal(mean_degree(g_random), manual_mean)
96+
97+
# For directed graph
98+
g_directed_random <- sample_gnp(100, 0.05, directed = TRUE)
99+
manual_mean_dir <- ecount(g_directed_random) / vcount(g_directed_random)
100+
expect_equal(mean_degree(g_directed_random), manual_mean_dir)
101+
})
102+
75103
test_that("BFS uses 1-based root vertex index", {
76104
g <- make_ring(3)
77105
expect_equal(bfs(g, root = 1)$root, 1)

0 commit comments

Comments
 (0)