7878# '
7979# ' # Different degree aggregation strategies
8080# ' result_first <- degree_adoption_diagnostic(kfamilyDiffNet, degree_strategy = "first")
81- # ' result_last <- degree_adoption_diagnostic(kfamilyDiffNet, degree_strategy = "last")
81+ # ' result_last <- degree_adoption_diagnostic(kfamilyDiffNet, degree_strategy = "last")
8282# '
8383# ' # Multi-diffusion (toy) ----------------------------------------------------
8484# ' set.seed(999)
85- # ' n <- 40; t <- 5; q <- 2
86- # ' garr <- rgraph_ws(n, t, p=.3)
85+ # ' n <- 40
86+ # ' t <- 5
87+ # ' q <- 2
88+ # ' garr <- rgraph_ws(n, t, p = .3)
8789# ' diffnet_multi <- rdiffnet(seed.graph = garr, t = t, seed.p.adopt = rep(list(0.1), q))
8890# '
8991# ' # pooled (one combined analysis)
9698# ' @family statistics
9799# ' @export
98100degree_adoption_diagnostic <- function (
99- graph ,
100- degree_strategy = c(" mean" , " first" , " last" ),
101- bootstrap = TRUE ,
102- R = 1000 ,
103- conf.level = 0.95 ,
104- toa = NULL ,
105- t0 = NULL , t1 = NULL ,
106- name = NULL ,
107- behavior = NULL ,
108- combine = c(" none" , " pooled" , " average" , " earliest" ),
109- min_adopters = 3 ,
110- valued = getOption(" diffnet.valued" , FALSE ),
111- ...
112- ) {
101+ graph ,
102+ degree_strategy = c(" mean" , " first" , " last" ),
103+ bootstrap = TRUE ,
104+ R = 1000 ,
105+ conf.level = 0.95 ,
106+ toa = NULL ,
107+ t0 = NULL , t1 = NULL ,
108+ name = NULL ,
109+ behavior = NULL ,
110+ combine = c(" none" , " pooled" , " average" , " earliest" ),
111+ min_adopters = 3 ,
112+ valued = getOption(" diffnet.valued" , FALSE ),
113+ ... ) {
113114 # Check that bootstrap is a logical scalar
114115 if (! is.logical(bootstrap ) || length(bootstrap ) != 1 || is.na(bootstrap )) {
115116 stop(" 'bootstrap' must be a logical scalar" )
@@ -154,8 +155,10 @@ degree_adoption_diagnostic <- function(
154155 }
155156 behavior_indices <- match(behavior , colnames(toa ))
156157 if (any(is.na(behavior_indices ))) {
157- stop(" Some behavior names not found in colnames(toa): " ,
158- paste(behavior [is.na(behavior_indices )], collapse = " , " ))
158+ stop(
159+ " Some behavior names not found in colnames(toa): " ,
160+ paste(behavior [is.na(behavior_indices )], collapse = " , " )
161+ )
159162 }
160163 } else if (is.numeric(behavior )) {
161164 behavior_indices <- behavior
@@ -186,8 +189,10 @@ degree_adoption_diagnostic <- function(
186189 combined_data <- prepare_combined_data(degrees , toa , combine , min_adopters , Q )
187190
188191 if (nrow(combined_data ) < min_adopters ) {
189- stop(" Insufficient adopters for correlation analysis. (n=" , nrow(combined_data ),
190- " , minimum = " , min_adopters , " )." )
192+ stop(
193+ " Insufficient adopters for correlation analysis. (n=" , nrow(combined_data ),
194+ " , minimum = " , min_adopters , " )."
195+ )
191196 }
192197
193198 # Compute correlations
@@ -232,8 +237,12 @@ process_graph_input <- function(graph, toa, t0, t1, name, ...) {
232237 # If graph is a list, ensure all elements are dgCMatrix
233238 if (is.list(graph )) {
234239 graph <- lapply(graph , function (g ) {
235- if (inherits(g , " dgCMatrix" )) return (g )
236- if (is.matrix(g )) return (as(Matrix :: Matrix(g , sparse = TRUE ), " dgCMatrix" ))
240+ if (inherits(g , " dgCMatrix" )) {
241+ return (g )
242+ }
243+ if (is.matrix(g )) {
244+ return (as(Matrix :: Matrix(g , sparse = TRUE ), " dgCMatrix" ))
245+ }
237246 stop(" All elements of the graph list must be matrices or dgCMatrix." )
238247 })
239248 }
@@ -328,8 +337,8 @@ analyze_multi_behaviors_separately <- function(degrees, toa, min_adopters, boots
328337 toa = toa_q [adopters_q ]
329338 )
330339
331- correlations_matrix [1 , q ] <- cor_safe(data_q $ indegree , data_q $ toa )
332- correlations_matrix [2 , q ] <- cor_safe(data_q $ outdegree , data_q $ toa )
340+ correlations_matrix [1 , q ] <- cor_safe(data_q $ indegree , data_q $ toa )
341+ correlations_matrix [2 , q ] <- cor_safe(data_q $ outdegree , data_q $ toa )
333342 sample_sizes [q ] <- nrow(data_q )
334343
335344 if (bootstrap ) {
@@ -391,7 +400,9 @@ prepare_combined_data <- function(degrees, toa, combine, min_adopters, Q) {
391400 } else if (combine == " earliest" ) {
392401 # Earliest TOA across behaviors per actor
393402 toa_min <- apply(toa , 1 , function (row ) {
394- if (all(is.na(row ))) return (NA_real_ )
403+ if (all(is.na(row ))) {
404+ return (NA_real_ )
405+ }
395406 min(row , na.rm = TRUE )
396407 })
397408 toa_min [is.infinite(toa_min )] <- NA
@@ -414,12 +425,12 @@ compute_correlations <- function(data) {
414425
415426compute_bootstrap_results <- function (combined_data , R , conf.level ) {
416427 # Compute baseline correlations
417- base_corr <- compute_correlations(combined_data )
418- indeg_corr <- base_corr [[" indegree_toa" ]]
428+ base_corr <- compute_correlations(combined_data )
429+ indeg_corr <- base_corr [[" indegree_toa" ]]
419430 outdeg_corr <- base_corr [[" outdegree_toa" ]]
420431
421432 indeg_boot_list <- NULL
422- out_boot_list <- NULL
433+ out_boot_list <- NULL
423434
424435 # Out-degree
425436 if (! is.na(outdeg_corr )) {
@@ -430,13 +441,16 @@ compute_bootstrap_results <- function(combined_data, R, conf.level) {
430441 }
431442 boot_obj_out <- boot :: boot(combined_data , statistic = safe_bootstrap_out , R = R )
432443 bias_out <- mean(boot_obj_out $ t , na.rm = TRUE ) - outdeg_corr
433- se_out <- stats :: sd(boot_obj_out $ t , na.rm = TRUE )
434-
435- ci_out <- tryCatch({
436- bci <- boot :: boot.ci(boot_obj_out , conf = conf.level , type = " perc" )
437- # Percentile CI vector (low, high)
438- if (! is.null(bci $ percent )) bci $ percent [4 : 5 ] else NULL
439- }, error = function (e ) NULL )
444+ se_out <- stats :: sd(boot_obj_out $ t , na.rm = TRUE )
445+
446+ ci_out <- tryCatch(
447+ {
448+ bci <- boot :: boot.ci(boot_obj_out , conf = conf.level , type = " perc" )
449+ # Percentile CI vector (low, high)
450+ if (! is.null(bci $ percent )) bci $ percent [4 : 5 ] else NULL
451+ },
452+ error = function (e ) NULL
453+ )
440454
441455 out_boot_list <- list (
442456 correlation = outdeg_corr ,
@@ -462,12 +476,15 @@ compute_bootstrap_results <- function(combined_data, R, conf.level) {
462476 }
463477 boot_obj_in <- boot :: boot(combined_data , statistic = safe_bootstrap_in , R = R )
464478 bias_in <- mean(boot_obj_in $ t , na.rm = TRUE ) - indeg_corr
465- se_in <- stats :: sd(boot_obj_in $ t , na.rm = TRUE )
466-
467- ci_in <- tryCatch({
468- bci <- boot :: boot.ci(boot_obj_in , conf = conf.level , type = " perc" )
469- if (! is.null(bci $ percent )) bci $ percent [4 : 5 ] else NULL
470- }, error = function (e ) NULL )
479+ se_in <- stats :: sd(boot_obj_in $ t , na.rm = TRUE )
480+
481+ ci_in <- tryCatch(
482+ {
483+ bci <- boot :: boot.ci(boot_obj_in , conf = conf.level , type = " perc" )
484+ if (! is.null(bci $ percent )) bci $ percent [4 : 5 ] else NULL
485+ },
486+ error = function (e ) NULL
487+ )
471488
472489 indeg_boot_list <- list (
473490 correlation = indeg_corr ,
@@ -508,7 +525,7 @@ check_undirected_graph <- function(graph) {
508525 return (all(sapply(graph , function (g ) isSymmetric(as.matrix(g )))))
509526 }
510527 if (is.array(graph ) && length(dim(graph )) == 3 ) {
511- return (all(sapply(seq_len(dim(graph )[3 ]), function (t ) isSymmetric(as.matrix(graph [,, t ])))))
528+ return (all(sapply(seq_len(dim(graph )[3 ]), function (t ) isSymmetric(as.matrix(graph [, , t ])))))
512529 }
513530 if (is.matrix(graph )) {
514531 return (isSymmetric(as.matrix(graph )))
@@ -568,7 +585,7 @@ print_single_behavior_results <- function(x, undirected) {
568585 # Print correlations
569586 cat(" Correlations:\n " )
570587 if (undirected ) {
571- deg_r <- indeg_r # For undirected graphs, in-degree = out-degree = degree
588+ deg_r <- indeg_r # For undirected graphs, in-degree = out-degree = degree
572589 cat(sprintf(" Degree - Time of Adoption: %.3f\n " , deg_r ))
573590 } else {
574591 cat(sprintf(" In-degree - Time of Adoption: %.3f\n " , indeg_r ))
@@ -582,16 +599,24 @@ print_single_behavior_results <- function(x, undirected) {
582599 bootstrap_data <- x $ bootstrap
583600 deg_ci <- if (undirected && ! is.null(bootstrap_data $ indegree $ conf_int )) {
584601 bootstrap_data $ indegree $ conf_int
585- } else NULL
602+ } else {
603+ NULL
604+ }
586605 indeg_ci <- if (! is.null(bootstrap_data $ indegree $ conf_int )) {
587606 bootstrap_data $ indegree $ conf_int
588- } else NULL
607+ } else {
608+ NULL
609+ }
589610 outdeg_ci <- if (! is.null(bootstrap_data $ outdegree $ conf_int )) {
590611 bootstrap_data $ outdegree $ conf_int
591- } else NULL
612+ } else {
613+ NULL
614+ }
592615 lvl <- if (! is.null(bootstrap_data $ indegree $ conf_level )) {
593616 bootstrap_data $ indegree $ conf_level * 100
594- } else NA_real_
617+ } else {
618+ NA_real_
619+ }
595620
596621 if (undirected ) {
597622 explain_degree_correlation(" Degree" , deg_r , deg_ci , lvl_arg = lvl )
@@ -648,16 +673,24 @@ print_multi_behavior_results <- function(x, undirected) {
648673 bootstrap_data <- if (! is.null(x $ bootstrap )) x $ bootstrap [[j ]] else NULL
649674 deg_ci <- if (undirected && ! is.null(bootstrap_data ) && ! is.null(bootstrap_data $ indegree $ conf_int )) {
650675 bootstrap_data $ indegree $ conf_int
651- } else NULL
676+ } else {
677+ NULL
678+ }
652679 indeg_ci <- if (! is.null(bootstrap_data ) && ! is.null(bootstrap_data $ indegree $ conf_int )) {
653680 bootstrap_data $ indegree $ conf_int
654- } else NULL
681+ } else {
682+ NULL
683+ }
655684 outdeg_ci <- if (! is.null(bootstrap_data ) && ! is.null(bootstrap_data $ outdegree $ conf_int )) {
656685 bootstrap_data $ outdegree $ conf_int
657- } else NULL
686+ } else {
687+ NULL
688+ }
658689 lvl <- if (! is.null(bootstrap_data ) && ! is.null(bootstrap_data $ indegree $ conf_level )) {
659690 bootstrap_data $ indegree $ conf_level * 100
660- } else NA_real_
691+ } else {
692+ NA_real_
693+ }
661694
662695 cat(sprintf(" [%s]\n " , bname ))
663696 if (undirected ) {
@@ -696,49 +729,72 @@ explain_degree_correlation <- function(label, r, ci, lvl_arg = NA_real_, thr = 0
696729
697730format_interpretation_no_ci <- function (label , r , abs_big , degree_term , thr ) {
698731 if (! abs_big ) {
699- cat(sprintf(" %s: Weak relationship between %s and adoption timing:\n |r| \u 2264 %.1f; no CI.\n " ,
700- label , degree_term , thr ))
701- } else if (r > 0 ) {
702- cat(sprintf(" %s: Central actors (high %s) tended to adopt early (supporters):\n |r| > %.1f; no CI.\n " ,
703- label , degree_term , thr ))
732+ cat(sprintf(
733+ " %s: Weak relationship between %s and adoption timing:\n |r| \u 2264 %.1f; no CI.\n " ,
734+ label , degree_term , thr
735+ ))
736+ } else if (r < 0 ) {
737+ cat(sprintf(
738+ " %s: Central actors (high %s) tended to adopt early (supporters):\n |r| > %.1f; no CI.\n " ,
739+ label , degree_term , thr
740+ ))
704741 } else {
705- cat(sprintf(" %s: Central actors (high %s) tended to adopt late (opposers):\n |r| > %.1f; no CI.\n " ,
706- label , degree_term , thr ))
742+ cat(sprintf(
743+ " %s: Central actors (high %s) tended to adopt late (opposers):\n |r| > %.1f; no CI.\n " ,
744+ label , degree_term , thr
745+ ))
707746 }
708747}
709748
710749format_interpretation_with_ci <- function (label , r , ci , abs_big , degree_term , thr , lvl_arg ) {
711750 lvl_local <- if (! is.na(lvl_arg )) lvl_arg else 95
712751 ci_includes_zero <- (length(ci ) > = 2 ) && is.finite(ci [1 ]) && is.finite(ci [2 ]) && (ci [1 ] < = 0 && ci [2 ] > = 0 )
752+
753+ ci_low <- if (length(ci ) > = 1 ) ci [1 ] else NA_real_
754+ ci_high <- if (length(ci ) > = 2 ) ci [2 ] else NA_real_
713755
714756 if (! abs_big ) {
715- cat(sprintf(" %s: Weak relationship between %s and adoption timing; %s statistically supported:\n |r| \u 2264 %.1f; CI (%.1f%%) %s 0.\n " ,
716- label , degree_term ,
717- if (ci_includes_zero ) " NOT" else " " ,
718- thr , lvl_local ,
719- if (ci_includes_zero ) " includes" else " excludes" ))
720- } else if (r > 0 ) {
721- cat(sprintf(" %s: Central actors (high %s) tended to adopt early (supporters); %s statistically supported:\n |r| > %.1f; CI (%.1f%%) %s 0.\n " ,
722- label , degree_term ,
723- if (ci_includes_zero ) " NOT" else " " ,
724- thr , lvl_local ,
725- if (ci_includes_zero ) " includes" else " excludes" ))
757+ cat(sprintf(
758+ " %s: Weak relationship between %s and adoption timing; %s statistically supported:\n |r| \u 2264 %.1f; CI (%.1f%%) = [%.3f, %.3f]\n " ,
759+ label , degree_term ,
760+ if (ci_includes_zero ) " NOT" else " " ,
761+ thr , lvl_local ,
762+ ci_low , ci_high
763+ ))
764+ } else if (r < 0 ) {
765+ cat(sprintf(
766+ " %s: Central actors (high %s) tended to adopt early (supporters); %s statistically supported:\n |r| > %.1f; CI (%.1f%%) = [%.3f, %.3f]\n " ,
767+ label , degree_term ,
768+ if (ci_includes_zero ) " NOT" else " " ,
769+ thr , lvl_local ,
770+ ci_low , ci_high
771+ ))
726772 } else {
727- cat(sprintf(" %s: Central actors (high %s) tended to adopt late (opposers); %s statistically supported:\n |r| > %.1f; CI (%.1f%%) %s 0.\n " ,
728- label , degree_term ,
729- if (ci_includes_zero ) " NOT" else " " ,
730- thr , lvl_local ,
731- if (ci_includes_zero ) " includes" else " excludes" ))
773+ cat(sprintf(
774+ " %s: Central actors (high %s) tended to adopt late (opposers); %s statistically supported:\n |r| > %.1f; CI (%.1f%%) = [%.3f, %.3f]\n " ,
775+ label , degree_term ,
776+ if (ci_includes_zero ) " NOT" else " " ,
777+ thr , lvl_local ,
778+ ci_low , ci_high
779+ ))
732780 }
733781}
734782
735783# Safe correlation: returns NA (no warnings) if zero-variance or too few pairs
736784cor_safe <- function (x , y ) {
737- x <- as.numeric(x ); y <- as.numeric(y )
785+ x <- as.numeric(x )
786+ y <- as.numeric(y )
738787 ok <- is.finite(x ) & is.finite(y )
739- if (! any(ok )) return (NA_real_ )
740- x <- x [ok ]; y <- y [ok ]
741- if (length(x ) < 2L ) return (NA_real_ )
742- if (sd(x ) == 0 || sd(y ) == 0 ) return (NA_real_ )
788+ if (! any(ok )) {
789+ return (NA_real_ )
790+ }
791+ x <- x [ok ]
792+ y <- y [ok ]
793+ if (length(x ) < 2L ) {
794+ return (NA_real_ )
795+ }
796+ if (sd(x ) == 0 || sd(y ) == 0 ) {
797+ return (NA_real_ )
798+ }
743799 stats :: cor(x , y )
744800}
0 commit comments