Skip to content

Commit 34c4ca4

Browse files
committed
Save centrality data as csv
1 parent 2a7da40 commit 34c4ca4

File tree

7 files changed

+90
-48
lines changed

7 files changed

+90
-48
lines changed

NAMESPACE

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
S3method(add,Report)
44
S3method(add_figure,Report)
55
S3method(export_pdf,Report)
6-
S3method(get_betweenness,Interactions)
76
S3method(get_centrality,Interactions)
8-
S3method(get_closeness,Interactions)
97
S3method(get_cohesion,Interactions)
108
S3method(get_communities,Interactions)
119
S3method(get_density,Interactions)
@@ -15,6 +13,7 @@ S3method(get_transitivity,Interactions)
1513
S3method(plot_graph,Interactions)
1614
S3method(plot_top_authors,Interactions)
1715
S3method(print,Report)
16+
S3method(save_centrality_data,Interactions)
1817
S3method(save_md,Report)
1918
export(Interactions)
2019
export(Report)

R/Assemble_report.r

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ assemble_report <- function(config) {
7474
fig_caption = "Direct connections between the 15 most central authors"
7575
)
7676

77+
# Save centrality data as csv
78+
save_centrality_data(interactions, paste0(paths$output, "/centrality_data_", date_range, ".csv"))
79+
7780
# Save report as markdown
7881
save_md(report, paste0(paths$output, "/Report_", date_range, ".md"))
7982

R/Interactions.plots.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ plot_graph.Interactions <- function(interactions, output_file = "output/graph.pn
33
comm <- get_communities(interactions)
44
colors <- grDevices::rainbow(length(unique(comm$membership)), alpha = 0.4)
55

6-
centrality <- get_centrality(interactions)
6+
centrality <- get_centrality(interactions)$degree
77
vertex_size <- 1 + (centrality / max(centrality)) * 15
88

99
grDevices::png(filename = output_file, width = 2500, height = 1800, res = 360)
@@ -41,7 +41,7 @@ plot_graph <- function(interactions, output_file) {
4141
#' @export
4242
plot_top_authors.Interactions <- function(interactions, n = 10, output_file = "output/top_authors.png") {
4343
# Identify the top n authors based on centrality
44-
centrality <- get_centrality(interactions)
44+
centrality <- get_centrality(interactions)$degree
4545
top_authors <- order(centrality, decreasing = TRUE)[1:n]
4646

4747
# Create a subgraph with the top n authors

R/Interactions_class.r

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -93,31 +93,16 @@ get_transitivity <- function(interactions) {
9393

9494
#' @export
9595
get_centrality.Interactions <- function(interactions) {
96-
return(igraph::degree(interactions$graph))
96+
degree <- igraph::degree(interactions$graph)
97+
closeness <- igraph::closeness(interactions$graph)
98+
betweenness <- igraph::betweenness(interactions$graph)
99+
return(list(degree = degree, closeness = closeness, betweenness = betweenness))
97100
}
98101

99102
get_centrality <- function(interactions) {
100103
UseMethod("get_centrality", interactions)
101104
}
102105

103-
#' @export
104-
get_betweenness.Interactions <- function(interactions) {
105-
return(igraph::betweenness(interactions$graph))
106-
}
107-
108-
get_betweenness <- function(interactions) {
109-
UseMethod("get_betweenness", interactions)
110-
}
111-
112-
#' @export
113-
get_closeness.Interactions <- function(interactions) {
114-
return(igraph::closeness(interactions$graph))
115-
}
116-
117-
get_closeness <- function(interactions) {
118-
UseMethod("get_closeness", interactions)
119-
}
120-
121106
#' @export
122107
get_diameter.Interactions <- function(interactions) {
123108
return(igraph::diameter(interactions$graph, directed = interactions$directed, weights = NULL))
@@ -139,7 +124,7 @@ get_communities <- function(interactions) {
139124
#' @export
140125
get_most_central_per_community.Interactions <- function(interactions) {
141126
comm <- get_communities(interactions)
142-
centrality <- get_centrality(interactions)
127+
centrality <- get_centrality(interactions)$degree
143128
most_central_authors <- sapply(unique(comm$membership), function(group) {
144129
group_vertices <- which(comm$membership == group)
145130
group_centrality <- centrality[group_vertices]
@@ -152,3 +137,19 @@ get_most_central_per_community.Interactions <- function(interactions) {
152137
get_most_central_per_community <- function(interactions) {
153138
UseMethod("get_most_central_per_community", interactions)
154139
}
140+
141+
#' @export
142+
save_centrality_data.Interactions <- function(interactions, output_file = "output/centrality_data.csv") {
143+
centrality <- get_centrality(interactions)
144+
output_data <- data.frame(
145+
degree = centrality$degree,
146+
closeness = centrality$closeness,
147+
betweenness = centrality$betweenness
148+
)
149+
output_data <- output_data[statnet.common::order(-output_data$degree), ]
150+
utils::write.csv(output_data, output_file, row.names = TRUE)
151+
}
152+
153+
save_centrality_data <- function(interactions, output_file) {
154+
UseMethod("save_centrality_data", interactions)
155+
}

R/Report_text.r

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -101,33 +101,31 @@ density_transitivity <- function(interactions) {
101101
#' @export
102102
centrality_metrics <- function(interactions) {
103103
centrality <- get_centrality(interactions)
104-
betweenness <- get_betweenness(interactions)
105-
closeness <- get_closeness(interactions)
106104
diameter <- get_diameter(interactions)
107105
text <- paste0("\n# Node Centrality and Centralization",
108106
"\n## Degree Centrality",
109107
"\nDegree centrality measures the number of direct connections each node has in the network.
110108
Nodes with higher degree centrality are likely to be influential or well-connected individuals/entities.",
111-
"\n\n- **The least connected node has (Min)**: ", round(min(centrality)),
112-
"\n- **The most connected node has (Max)**: ", round(max(centrality)),
113-
"\n- **On average, nodes have about (Mean)**: ", round(mean(centrality)),
114-
"\n- **Half of the nodes have more connection than (Median)**: ", round(median(centrality)),
109+
"\n\n- **The least connected node has (Min)**: ", round(min(centrality$degree)),
110+
"\n- **The most connected node has (Max)**: ", round(max(centrality$degree)),
111+
"\n- **On average, nodes have about (Mean)**: ", round(mean(centrality$degree)),
112+
"\n- **Half of the nodes have more connection than (Median)**: ", round(median(centrality$degree)),
115113

116114
"\n\n## Betweenness Centrality",
117115
"\nBetweenness centrality quantifies how often a node acts as a bridge in the shortest paths between other nodes.
118116
Nodes with high betweenness are critical connectors in the network. Removing them could significantly disrupt the flow of information.",
119-
"\n\n- **Min**: ", round(min(betweenness)),
120-
"\n- **The node with the highest value is a critical bridge in the network, controlling the flow of information. with Max**: ", round(max(betweenness)),
121-
"\n- **Mean**: ", round(mean(betweenness)),
122-
"\n- **Median**: ", round(median(betweenness)),
117+
"\n\n- **Min**: ", round(min(centrality$betweenness)),
118+
"\n- **The node with the highest value is a critical bridge in the network, controlling the flow of information. with Max**: ", round(max(centrality$betweenness)),
119+
"\n- **Mean**: ", round(mean(centrality$betweenness)),
120+
"\n- **Median**: ", round(median(centrality$betweenness)),
123121

124122
"\n\n## Closeness Centrality",
125123
"\nCloseness centrality measures how quickly a node can access other nodes in the network.
126124
Nodes with high closeness centrality are in advantageous positions to disseminate information quickly.",
127-
"\n\n- **The least central node has a (Min) avarage path to reach other nodes**: ", round(min(closeness), digits = 5),
128-
"\n- **Max**: ", round(max(closeness), digits = 5),
129-
"\n- **Mean**: ", round(mean(closeness), digits = 5),
130-
"\n- **Median**: ", round(median(closeness), digits = 5),
125+
"\n\n- **The least central node has a (Min) avarage path to reach other nodes**: ", round(min(centrality$closeness), digits = 5),
126+
"\n- **Max**: ", round(max(centrality$closeness), digits = 5),
127+
"\n- **Mean**: ", round(mean(centrality$closeness), digits = 5),
128+
"\n- **Median**: ", round(median(centrality$closeness), digits = 5),
131129
"\n\n## Network diameter",
132130
"\nThe network diameter is the maximum distance (in terms of edges or steps) required to connect any two nodes in the network through the shortest possible path. ",
133131
"\n\n- In our network: **the diameter is ", diameter, "**, it indicates that the farthest two nodes in your co-authorship network can be linked by the shortest path of ", diameter, " steps. ",

tests/testthat/test-Assemble-report.R

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,29 @@ test_that("assemble_report works correctly", {
8383

8484
mock_save_md <- function(report, file_path) {
8585
md_path <- paste0(folder, "/Report_2000-2001.md")
86-
writeLines("Mock PDF Content", con = md_path)
86+
writeLines("Mock MD Content", con = md_path)
8787
}
8888

8989
mock_export_pdf <- function(report, input_file, output_file) {
9090
pdf_path <- paste0(folder, "/Report_2000-2001.pdf")
9191
writeLines("Mock PDF Content", con = pdf_path)
9292
}
9393

94+
mock_save_centrality_data <- function(interactions, output_path) {
95+
csv_path <- paste0(folder, "/centrality_data_2000-2001.csv")
96+
writeLines("Mock CSV Content", con = csv_path)
97+
}
98+
99+
mock_get_author_stats <- function(data, author_column_name = "Author", delimiter = ";") {
100+
list(
101+
sum = 3,
102+
average = 2,
103+
median = 2,
104+
min = 1,
105+
max = 3
106+
)
107+
}
108+
94109
# Use with_mock to override the functions
95110
testthat::with_mocked_bindings(
96111
import_csv_data = mock_import_csv_data,
@@ -109,6 +124,8 @@ test_that("assemble_report works correctly", {
109124
plot_top_authors = mock_plot_top_authors,
110125
save_md = mock_save_md,
111126
export_pdf = mock_export_pdf,
127+
save_centrality_data = mock_save_centrality_data,
128+
get_author_stats = mock_get_author_stats,
112129
{
113130
# Run the assemble_report function with the mock config
114131
assemble_report(config)

tests/testthat/test-Interactions.R

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,10 @@ test_that("transitivity works", {
3636
})
3737

3838
test_that("centrality works", {
39-
expect_equal(mean(get_centrality(interactions)), 3)
40-
})
41-
42-
test_that("betweenness works", {
43-
expect_equal(round(mean(get_betweenness(interactions)), digits = 3), 0.167)
44-
})
45-
46-
test_that("closeness works", {
47-
expect_equal(round(mean(get_closeness(interactions)), digits = 3), 0.292)
39+
centrality <- get_centrality(interactions)
40+
expect_equal(mean(centrality$degree), 3)
41+
expect_equal(round(mean(centrality$betweenness), digits = 3), 0.167)
42+
expect_equal(round(mean(centrality$closeness), digits = 3), 0.292)
4843
})
4944

5045
test_that("diameter works", {
@@ -60,3 +55,32 @@ test_that("most_central_authors works", {
6055
author_list <- get_most_central_per_community(interactions)
6156
expect_equal(author_list, "Author1")
6257
})
58+
59+
test_that("save_centrality_data saves the correct centrality data to a CSV file", {
60+
# Create a sample data frame
61+
data <- data.frame(
62+
Author = c("Author1;Author2", "Author2;Author3", "Author1;Author3"),
63+
Year = c(2020, 2021, 2022)
64+
)
65+
66+
# Create an Interactions object
67+
interactions <- Interactions(data)
68+
69+
# Define the output file path
70+
output_file <- tempfile(fileext = ".csv")
71+
72+
# Call the save_centrality_data function
73+
save_centrality_data(interactions, output_file)
74+
75+
# Read the output file
76+
output_data <- read.csv(output_file)
77+
78+
# Check that the output data has the correct columns
79+
expect_true(all(c("degree", "closeness", "betweenness") %in% colnames(output_data)))
80+
81+
# Check that the output data is sorted by degree in descending order
82+
expect_true(all(diff(output_data$degree) <= 0))
83+
84+
# Clean up the temporary file
85+
unlink(output_file)
86+
})

0 commit comments

Comments
 (0)