|
a |
|
b/R/5.topological.R |
|
|
1 |
# ========5.topological======= |
|
|
2 |
|
|
|
3 |
#' Extract each sample network from the whole network |
|
|
4 |
#' |
|
|
5 |
#' @param whole_net the whole network |
|
|
6 |
#' @param otutab otutab, columns are samples, these columns will be extract |
|
|
7 |
#' @param threads threads, default: 1 |
|
|
8 |
#' @param save_net should save these sub_nets? FALSE or a filename |
|
|
9 |
#' @param fast less indexes for faster calculate ? |
|
|
10 |
#' @param verbose verbose |
|
|
11 |
#' @param remove_negative remove negative edge or not? default: FALSE |
|
|
12 |
#' |
|
|
13 |
#' @return a dataframe contains all sub_net parameters |
|
|
14 |
#' @export |
|
|
15 |
#' @family topological |
|
|
16 |
#' @examples |
|
|
17 |
#' data(otutab, package = "pcutils") |
|
|
18 |
#' extract_sample_net(co_net, otutab) -> sub_net_pars |
|
|
19 |
extract_sample_net <- function(whole_net, otutab, threads = 1, save_net = FALSE, fast = TRUE, remove_negative = FALSE, verbose = TRUE) { |
|
|
20 |
i <- NULL |
|
|
21 |
V(whole_net)$name -> v_name |
|
|
22 |
reps <- ncol(otutab) |
|
|
23 |
|
|
|
24 |
if (verbose) message("extracting") |
|
|
25 |
sub_nets <- lapply(1:reps, \(i){ |
|
|
26 |
rownames(otutab)[otutab[, i] > 0] -> exist_sp |
|
|
27 |
subgraph(whole_net, which(v_name %in% exist_sp)) -> spe_sub |
|
|
28 |
class(spe_sub) <- c("metanet", "igraph") |
|
|
29 |
return(spe_sub) |
|
|
30 |
}) |
|
|
31 |
names(sub_nets) <- colnames(otutab) |
|
|
32 |
if (verbose) message("calculating topological indexes") |
|
|
33 |
|
|
|
34 |
# parallel |
|
|
35 |
# main function |
|
|
36 |
loop <- function(i) { |
|
|
37 |
spe_sub <- sub_nets[[i]] |
|
|
38 |
indexs <- net_par(spe_sub, mode = "n", fast = fast, remove_negative = remove_negative)[["n_index"]] |
|
|
39 |
wc <- igraph::cluster_fast_greedy(spe_sub, weights = abs(igraph::E(spe_sub)$weight)) |
|
|
40 |
indexs$modularity <- igraph::modularity(wc) |
|
|
41 |
indexs |
|
|
42 |
} |
|
|
43 |
{ |
|
|
44 |
if (threads > 1) { |
|
|
45 |
pcutils::lib_ps("foreach", "doSNOW", "snow", library = FALSE) |
|
|
46 |
if (verbose) { |
|
|
47 |
pb <- utils::txtProgressBar(max = reps, style = 3) |
|
|
48 |
opts <- list(progress = function(n) utils::setTxtProgressBar(pb, n)) |
|
|
49 |
} else { |
|
|
50 |
opts <- NULL |
|
|
51 |
} |
|
|
52 |
cl <- snow::makeCluster(threads) |
|
|
53 |
doSNOW::registerDoSNOW(cl) |
|
|
54 |
res <- foreach::`%dopar%`( |
|
|
55 |
foreach::foreach(i = 1:reps, .options.snow = opts), |
|
|
56 |
loop(i) |
|
|
57 |
) |
|
|
58 |
snow::stopCluster(cl) |
|
|
59 |
gc() |
|
|
60 |
} else { |
|
|
61 |
res <- lapply(1:reps, loop) |
|
|
62 |
} |
|
|
63 |
} |
|
|
64 |
# simplify method |
|
|
65 |
sub_net_pars <- do.call(rbind, res) |
|
|
66 |
|
|
|
67 |
rownames(sub_net_pars) <- colnames(otutab) |
|
|
68 |
|
|
|
69 |
if (is.logical(save_net)) { |
|
|
70 |
if (save_net) save_net <- paste0("sub_net_", date()) |
|
|
71 |
} |
|
|
72 |
if (is.character(save_net)) { |
|
|
73 |
saveRDS(sub_nets, file = paste0(save_net, ".RDS")) |
|
|
74 |
} |
|
|
75 |
sub_net_pars |
|
|
76 |
} |
|
|
77 |
|
|
|
78 |
#' Calculate natural_connectivity |
|
|
79 |
#' |
|
|
80 |
#' @param p an igraph or metanet object |
|
|
81 |
#' @return natural_connectivity (numeric) |
|
|
82 |
#' @export |
|
|
83 |
#' @references \code{`nc` in `ggClusterNet`} |
|
|
84 |
#' @family topological |
|
|
85 |
#' @examples |
|
|
86 |
#' igraph::make_ring(10) %>% nc() |
|
|
87 |
nc <- function(p) { |
|
|
88 |
adj_matrix <- as.matrix(igraph::as_adj(p, sparse = FALSE)) |
|
|
89 |
adj_matrix[abs(adj_matrix) != 0] <- 1 |
|
|
90 |
|
|
|
91 |
lambda <- eigen(adj_matrix, only.values = TRUE)$values |
|
|
92 |
lambda <- sort(lambda, decreasing = TRUE) |
|
|
93 |
|
|
|
94 |
lambda_sum <- 0 |
|
|
95 |
N <- length(lambda) |
|
|
96 |
for (i in 1:N) lambda_sum <- lambda_sum + exp(lambda[i]) |
|
|
97 |
lambda_average <- log(lambda_sum / N, base = exp(1)) |
|
|
98 |
lambda_average |
|
|
99 |
} |
|
|
100 |
|
|
|
101 |
|
|
|
102 |
#' Calculate all topological indexes of a network |
|
|
103 |
#' |
|
|
104 |
#' @param go an igraph or metanet object |
|
|
105 |
#' @param fast less indexes for faster calculate ? |
|
|
106 |
#' @param mode calculate what? c("v", "e", "n", "all") |
|
|
107 |
#' @param remove_negative remove negative edge or not? default: FALSE |
|
|
108 |
#' |
|
|
109 |
#' @return a 3-elements list |
|
|
110 |
#' \item{n_index}{indexs of the whole network} |
|
|
111 |
#' \item{v_index}{indexs of each vertex} |
|
|
112 |
#' \item{e_index}{indexs of each edge} |
|
|
113 |
#' @export |
|
|
114 |
#' @family topological |
|
|
115 |
#' @examples |
|
|
116 |
#' igraph::make_graph("Walther") %>% net_par() |
|
|
117 |
#' c_net_index(co_net) -> co_net_with_par |
|
|
118 |
net_par <- function(go, mode = c("v", "e", "n", "all"), fast = TRUE, remove_negative = FALSE) { |
|
|
119 |
from <- to <- NULL |
|
|
120 |
stopifnot(is_igraph(go)) |
|
|
121 |
if ("all" %in% mode) mode <- c("v", "e", "n") |
|
|
122 |
|
|
|
123 |
n_index <- NULL |
|
|
124 |
v_index <- NULL |
|
|
125 |
e_index <- NULL |
|
|
126 |
|
|
|
127 |
Negative_percentage <- ifelse(!is.null(E(go)$cor), sum(igraph::E(go)$cor < 0) / length(igraph::E(go)), NA) |
|
|
128 |
# remove negative weight |
|
|
129 |
if (remove_negative) { |
|
|
130 |
if (!is.null(E(go)$cor)) { |
|
|
131 |
# message("Remove negative correlation edges") |
|
|
132 |
c_net_filter(go, cor > 0, mode = "e") -> go |
|
|
133 |
} |
|
|
134 |
} |
|
|
135 |
|
|
|
136 |
# non-weighted network |
|
|
137 |
up <- go |
|
|
138 |
if (!is.null(igraph::edge_attr(up)[["weight"]])) up <- igraph::delete_edge_attr(up, "weight") |
|
|
139 |
|
|
|
140 |
if ("n" %in% mode) { |
|
|
141 |
# Calculate Network Parameters |
|
|
142 |
n_index <- data.frame( |
|
|
143 |
check.names = F, |
|
|
144 |
`Node_number` = length(igraph::V(go)), # number of nodes |
|
|
145 |
`Edge_number` = length(igraph::E(go)), # number of edges |
|
|
146 |
`Edge_density` = igraph::edge_density(go), # density of network, connectance |
|
|
147 |
`Negative_percentage` = Negative_percentage, # negative edges percentage |
|
|
148 |
`Average_path_length` = igraph::average.path.length(up), # Average path length |
|
|
149 |
|
|
|
150 |
`Global_efficiency` = igraph::global_efficiency(up), |
|
|
151 |
`Average_degree` = mean(igraph::degree(go)), # Average degree |
|
|
152 |
`Average_weighted_degree` = ifelse(is.null(igraph::E(go)$weight), mean(igraph::degree(go)), sum(igraph::E(go)$weight) / length(igraph::V(go))), # weighted degree |
|
|
153 |
Diameter = igraph::diameter(up), # network diameter |
|
|
154 |
`Clustering_coefficient` = igraph::transitivity(go), # Clustering coefficient |
|
|
155 |
`Centralized_betweenness` = igraph::centralization.betweenness(go)$centralization, # Betweenness centralization |
|
|
156 |
`Natural_connectivity` = nc(go) # natural |
|
|
157 |
) |
|
|
158 |
|
|
|
159 |
if (!fast) { |
|
|
160 |
# mean_dist=mean_distance(go)# |
|
|
161 |
# w_mean_dist=ifelse(is.null(E(go)$weight),mean_dist,mean_distance(go)) |
|
|
162 |
# v_conn= vertex.connectivity(go) # |
|
|
163 |
# e_conn= edge.connectivity(go) # |
|
|
164 |
# components= count_components(go) # |
|
|
165 |
modularity <- igraph::modularity(igraph::cluster_fast_greedy(go)) # |
|
|
166 |
rand.g <- igraph::erdos.renyi.game(length(V(go)), length(E(go)), type = "gnm") |
|
|
167 |
rand_m <- igraph::modularity(igraph::cluster_fast_greedy(rand.g)) |
|
|
168 |
relative_modularity <- (modularity - rand_m) / rand_m # |
|
|
169 |
|
|
|
170 |
n_index <- data.frame( |
|
|
171 |
check.names = F, |
|
|
172 |
n_index, |
|
|
173 |
Modularity = modularity, |
|
|
174 |
`Relative_modularity` = relative_modularity, |
|
|
175 |
`Centralized_closeness` = igraph::centralization.closeness(go)$centralization, # Closeness centralization |
|
|
176 |
`Centralized_degree` = igraph::centralization.degree(go)$centralization, # Degree centralization |
|
|
177 |
`Centralized_eigenvector` = igraph::centralization.evcent(go)$centralization # eigenvector centralization |
|
|
178 |
) |
|
|
179 |
} |
|
|
180 |
n_index <- apply(n_index, 1, FUN = \(x)replace(x, is.nan(x), 0)) %>% |
|
|
181 |
t() %>% |
|
|
182 |
as.data.frame() |
|
|
183 |
n_index <- cbind_new(get_n(go, simple = TRUE), n_index) |
|
|
184 |
} |
|
|
185 |
if ("v" %in% mode) { |
|
|
186 |
# Calculate Vertices Parameters |
|
|
187 |
v_index <- data.frame( |
|
|
188 |
check.names = F, |
|
|
189 |
Degree = igraph::degree(go), |
|
|
190 |
`Clustering_coefficient` = igraph::transitivity(go, type = "local"), # local clustering coefficient |
|
|
191 |
Betweenness = igraph::betweenness(go), # betweenness |
|
|
192 |
Eccentricity = igraph::eccentricity(go), |
|
|
193 |
Closeness = igraph::closeness(go), |
|
|
194 |
`Hub_score` = igraph::hub_score(go)[["vector"]] |
|
|
195 |
# page_rank = page.rank(go)$vector |
|
|
196 |
# igraph::evcent(go)[["vector"]] |
|
|
197 |
# igraph::local_efficiency(go) |
|
|
198 |
) |
|
|
199 |
|
|
|
200 |
# weighted degree |
|
|
201 |
if (!is.null(E(go)$cor)) { |
|
|
202 |
get_e(go) -> edge_list |
|
|
203 |
edge_list %>% |
|
|
204 |
dplyr::select(from, cor) %>% |
|
|
205 |
rbind(., dplyr::select(edge_list, to, cor) %>% dplyr::rename(from = to)) %>% |
|
|
206 |
dplyr::group_by(from) %>% |
|
|
207 |
dplyr::summarise(w_degree = sum(cor)) -> w_degree |
|
|
208 |
v_index$`Average_weighted_degree` <- w_degree[match(rownames(v_index), w_degree$from), "w_degree"] %>% unlist() |
|
|
209 |
} |
|
|
210 |
|
|
|
211 |
v_index <- apply(v_index, 1, FUN = \(x)replace(x, is.nan(x), 0)) %>% |
|
|
212 |
t() %>% |
|
|
213 |
as.data.frame() |
|
|
214 |
v_index <- cbind_new(get_v(go), v_index) |
|
|
215 |
} |
|
|
216 |
if ("e" %in% mode) { |
|
|
217 |
# Calculate Edges Parameters |
|
|
218 |
e_index <- get_e(go) |
|
|
219 |
# if(!(edge_attr(go)%>%unlist()%>%is.null()))e_index=data.frame(edge_attr(go),e_index) |
|
|
220 |
} |
|
|
221 |
return(list(n_index = n_index, v_index = v_index, e_index = e_index)) |
|
|
222 |
} |
|
|
223 |
|
|
|
224 |
|
|
|
225 |
#' Add topological indexes for a network |
|
|
226 |
#' @param go igraph or metanet |
|
|
227 |
#' @param force replace existed net_par |
|
|
228 |
#' |
|
|
229 |
#' @export |
|
|
230 |
#' @rdname net_par |
|
|
231 |
c_net_index <- function(go, force = FALSE) { |
|
|
232 |
if (!force) { |
|
|
233 |
if (!is.null(graph_attr(go)[["net_par"]])) stop("Already calculated net_pars, set `force = TRUE to replace existed net_par") |
|
|
234 |
} |
|
|
235 |
net_par(go, fast = FALSE) -> res |
|
|
236 |
graph_attr(go) <- as.list(res$n_index) |
|
|
237 |
graph_attr(go)[["net_par"]] <- TRUE |
|
|
238 |
vertex_attr(go) <- as.list(res$v_index) |
|
|
239 |
edge_attr(go) <- as.list(res$e_index) |
|
|
240 |
go |
|
|
241 |
} |
|
|
242 |
|
|
|
243 |
|
|
|
244 |
#' Fit power-law distribution for an igraph |
|
|
245 |
#' |
|
|
246 |
#' @param go igraph |
|
|
247 |
#' @param p.value calculate p.value |
|
|
248 |
#' |
|
|
249 |
#' @return ggplot |
|
|
250 |
#' @export |
|
|
251 |
#' @family topological |
|
|
252 |
#' @examples |
|
|
253 |
#' fit_power(co_net) |
|
|
254 |
fit_power <- function(go, p.value = FALSE) { |
|
|
255 |
x <- y <- formula <- NULL |
|
|
256 |
# igraph::degree distribution |
|
|
257 |
degree_dist <- table(igraph::degree(go)) |
|
|
258 |
dat <- data.frame(degree = as.numeric(names(degree_dist)), count = as.numeric(degree_dist)) |
|
|
259 |
# fit, set the original a & b |
|
|
260 |
mod <- stats::nls(count ~ a * degree^b, data = dat, start = list(a = 2, b = 1.5)) |
|
|
261 |
summary(mod) |
|
|
262 |
# extract the coefficient |
|
|
263 |
a <- round(coef(mod)[1], 3) |
|
|
264 |
b <- round(coef(mod)[2], 3) |
|
|
265 |
fit <- fitted(mod) |
|
|
266 |
SSre <- sum((dat$count - fit)^2) |
|
|
267 |
SStot <- sum((dat$count - mean(dat$count))^2) |
|
|
268 |
R2 <- round(1 - SSre / SStot, 3) |
|
|
269 |
|
|
|
270 |
# bootstrap t get p.value |
|
|
271 |
if (p.value) { |
|
|
272 |
dat_rand <- dat |
|
|
273 |
p_num <- lapply(seq_len(999), \(i){ |
|
|
274 |
dat_rand$count <- sample(dat_rand$count) |
|
|
275 |
SSre_rand <- sum((dat_rand$count - fit)^2) |
|
|
276 |
SStot_rand <- sum((dat_rand$count - mean(dat_rand$count))^2) |
|
|
277 |
R2_rand <- 1 - SSre_rand / SStot_rand |
|
|
278 |
R2_rand > R2 |
|
|
279 |
}) |
|
|
280 |
p_value <- (sum(unlist(p_num)) + 1) / (999 + 1) |
|
|
281 |
} |
|
|
282 |
|
|
|
283 |
p <- ggplot(dat, aes(x = degree, y = count)) + |
|
|
284 |
geom_point() + |
|
|
285 |
theme_bw() + |
|
|
286 |
stat_smooth(method = "nls", formula = y ~ a * x^b, method.args = list(start = list(a = 2, b = 1.5)), se = FALSE) + |
|
|
287 |
labs(x = "Degree", y = "Count") |
|
|
288 |
|
|
|
289 |
if (p.value) { |
|
|
290 |
label <- data.frame( |
|
|
291 |
x = 0.8 * max(dat$degree), |
|
|
292 |
y = c(0.9, 0.8, 0.7) * max(dat$count), |
|
|
293 |
formula = c( |
|
|
294 |
sprintf("italic(Y) == %.3f*italic(X)^%.3f", a, b), |
|
|
295 |
sprintf("italic(R^2) == %.3f", R2), |
|
|
296 |
sprintf("italic(P) < %.3f", p_value) |
|
|
297 |
) |
|
|
298 |
) |
|
|
299 |
} else { |
|
|
300 |
label <- data.frame( |
|
|
301 |
x = 0.8 * max(dat$degree), |
|
|
302 |
y = c(0.9, 0.8) * max(dat$count), |
|
|
303 |
formula = c( |
|
|
304 |
sprintf("italic(Y) == %.3f*italic(X)^%.3f", a, b), |
|
|
305 |
sprintf("italic(R^2) == %.3f", R2) |
|
|
306 |
) |
|
|
307 |
) |
|
|
308 |
} |
|
|
309 |
p + geom_text(aes(x = x, y = y, label = formula), data = label, parse = TRUE) |
|
|
310 |
} |
|
|
311 |
|
|
|
312 |
|
|
|
313 |
#' Degree distribution comparison with random network |
|
|
314 |
#' |
|
|
315 |
#' @param go igraph object |
|
|
316 |
#' @param plot plot or not |
|
|
317 |
#' |
|
|
318 |
#' @return ggplot |
|
|
319 |
#' @export |
|
|
320 |
#' @family topological |
|
|
321 |
#' @examples |
|
|
322 |
#' rand_net(co_net) |
|
|
323 |
rand_net <- function(go = go, plot = TRUE) { |
|
|
324 |
freq <- net <- NULL |
|
|
325 |
# generate a random network |
|
|
326 |
rand.g <- igraph::erdos.renyi.game(length(V(go)), length(E(go)), type = "gnm") |
|
|
327 |
|
|
|
328 |
if (!plot) { |
|
|
329 |
return(rand.g) |
|
|
330 |
} |
|
|
331 |
|
|
|
332 |
data1 <- data.frame( |
|
|
333 |
freq = igraph::degree_distribution(go), net = "Network", |
|
|
334 |
degree = 0:(length(degree_distribution(go)) - 1) |
|
|
335 |
) |
|
|
336 |
|
|
|
337 |
data2 <- data.frame( |
|
|
338 |
freq = igraph::degree_distribution(rand.g), net = "Random E-R", |
|
|
339 |
degree = 0:(length(degree_distribution(rand.g)) - 1) |
|
|
340 |
) |
|
|
341 |
|
|
|
342 |
# if data1[1,1]=0, it'is delete single vertex |
|
|
343 |
if (data1[1, 1] == 0) data1 <- data1[-1, ] |
|
|
344 |
|
|
|
345 |
data <- rbind(data1, data2) |
|
|
346 |
p1 <- ggplot(data) + |
|
|
347 |
geom_point(aes(x = degree, y = freq, group = net, fill = net), pch = 21, size = 2) + |
|
|
348 |
geom_smooth(aes(x = degree, y = freq, group = net, color = net), se = FALSE, method = "loess", formula = "y ~ x") + |
|
|
349 |
labs(x = "Degree", y = "Proportion") + |
|
|
350 |
scale_color_manual(values = c("#F58B8B", "#7AADF0")) + |
|
|
351 |
scale_fill_manual(values = c("#F58B8B", "#7AADF0")) + |
|
|
352 |
MetaNet_theme + |
|
|
353 |
theme(legend.position = c(0.8, 0.9), legend.title = element_blank()) |
|
|
354 |
print(p1) |
|
|
355 |
return(rand.g) |
|
|
356 |
} |
|
|
357 |
|
|
|
358 |
#' Net_pars of many random network |
|
|
359 |
#' |
|
|
360 |
#' @param go igraph |
|
|
361 |
#' @param reps simulation time |
|
|
362 |
#' @param threads threads |
|
|
363 |
#' @param verbose verbose |
|
|
364 |
#' |
|
|
365 |
#' @export |
|
|
366 |
#' @rdname compare_rand |
|
|
367 |
rand_net_par <- function(go, reps = 99, threads = 1, verbose = TRUE) { |
|
|
368 |
i <- NULL |
|
|
369 |
# parallel |
|
|
370 |
# main function |
|
|
371 |
loop <- function(i) { |
|
|
372 |
# generate a random network |
|
|
373 |
rand.g <- igraph::erdos.renyi.game(length(igraph::V(go)), |
|
|
374 |
length(igraph::E(go)), |
|
|
375 |
type = "gnm" |
|
|
376 |
) |
|
|
377 |
indexs <- net_par(rand.g, mode = "n")[["n_index"]] |
|
|
378 |
wc <- igraph::cluster_fast_greedy(rand.g) |
|
|
379 |
indexs$modularity <- igraph::modularity(wc) |
|
|
380 |
indexs |
|
|
381 |
} |
|
|
382 |
{ |
|
|
383 |
if (threads > 1) { |
|
|
384 |
pcutils::lib_ps("foreach", "doSNOW", "snow", library = FALSE) |
|
|
385 |
if (verbose) { |
|
|
386 |
pb <- utils::txtProgressBar(max = reps, style = 3) |
|
|
387 |
opts <- list(progress = function(n) utils::setTxtProgressBar(pb, n)) |
|
|
388 |
} else { |
|
|
389 |
opts <- NULL |
|
|
390 |
} |
|
|
391 |
cl <- snow::makeCluster(threads) |
|
|
392 |
doSNOW::registerDoSNOW(cl) |
|
|
393 |
res <- foreach::`%dopar%`( |
|
|
394 |
foreach::foreach(i = 1:reps, .options.snow = opts), |
|
|
395 |
loop(i) |
|
|
396 |
) |
|
|
397 |
snow::stopCluster(cl) |
|
|
398 |
gc() |
|
|
399 |
} else { |
|
|
400 |
res <- lapply(1:reps, loop) |
|
|
401 |
} |
|
|
402 |
} |
|
|
403 |
# simplify method |
|
|
404 |
rand_net_pars <- do.call(rbind, res) |
|
|
405 |
|
|
|
406 |
rand_net_pars |
|
|
407 |
} |
|
|
408 |
|
|
|
409 |
#' Compare some indexes between your net with random networks |
|
|
410 |
#' |
|
|
411 |
#' @param pars your net pars resulted by net_pars() |
|
|
412 |
#' @param randp random networks pars resulted by rand_net_par() |
|
|
413 |
#' @param index compared indexes: "Average_path_length","Clustering_coefficient" or else |
|
|
414 |
#' |
|
|
415 |
#' @return ggplot |
|
|
416 |
#' @export |
|
|
417 |
#' @family topological |
|
|
418 |
#' @examples |
|
|
419 |
#' data("c_net") |
|
|
420 |
#' rand_net_par(co_net_rmt, reps = 30) -> randp |
|
|
421 |
#' net_par(co_net_rmt, fast = FALSE) -> pars |
|
|
422 |
#' compare_rand(pars, randp) |
|
|
423 |
compare_rand <- function(pars, randp, index = c("Average_path_length", "Clustering_coefficient")) { |
|
|
424 |
V1 <- NULL |
|
|
425 |
labss <- t(pars$n_index[, index, drop = FALSE]) %>% as.data.frame() |
|
|
426 |
rownames(labss) -> labss$indexes |
|
|
427 |
|
|
|
428 |
p <- pcutils::group_box(randp[, index, drop = FALSE]) |
|
|
429 |
|
|
|
430 |
p <- p + |
|
|
431 |
geom_hline(data = labss, aes(yintercept = V1), linetype = 2, color = "blue3") + |
|
|
432 |
geom_text( |
|
|
433 |
data = labss, aes(x = 1, y = V1 * 1.05, label = paste0("Network: ", round(V1, 3))), |
|
|
434 |
color = "blue3" |
|
|
435 |
) + |
|
|
436 |
MetaNet_theme + |
|
|
437 |
theme(legend.position = "none", axis.text.x = element_blank()) |
|
|
438 |
p |
|
|
439 |
} |
|
|
440 |
|
|
|
441 |
|
|
|
442 |
#' Calculate small-world coefficient |
|
|
443 |
#' |
|
|
444 |
#' @param go igraph or metanet |
|
|
445 |
#' @param reps simulation time |
|
|
446 |
#' @param threads threads |
|
|
447 |
#' @param verbose verbose |
|
|
448 |
#' |
|
|
449 |
#' @return number |
|
|
450 |
#' @export |
|
|
451 |
#' @family topological |
|
|
452 |
#' @examples |
|
|
453 |
#' \donttest{ |
|
|
454 |
#' # set reps at least 99 when you run. |
|
|
455 |
#' smallworldness(co_net, reps = 9) |
|
|
456 |
#' } |
|
|
457 |
smallworldness <- function(go, reps = 99, threads = 1, verbose = TRUE) { |
|
|
458 |
rand_net_par(go, reps = reps, threads = threads, verbose = verbose) -> rands |
|
|
459 |
small_world_coefficient <- (igraph::transitivity(go) / mean(rands$Clustering_coefficient)) / |
|
|
460 |
(igraph::average.path.length(go) / mean(rands$`Average_path_length`)) |
|
|
461 |
small_world_coefficient |
|
|
462 |
} |