#' Network Plot #' #' Draw an undirected graph from a square matrix #' where each variable is a node and the pairwise #' entries are the strength of the relationship #' (ex: correlation, partial correlation) #' #' @param R A square numeric matrix with names columns and rows #' @param title Optional plot title #' #' @return A ggraph object #' #' @examples #' X <- matrix(data = rnorm(100), nrow = 10) #' R <- cor(X) #' networkplot(R, title = 'Example Correlation Plot') #' #' @import ggraph #' @import igraph #' #' @export networkplot <- function(R, title = NULL){ Rm <- tryCatch({ if(is.matrix(R)){ if(nrow(R) != ncol(R)) stop('R must be square') Rm <- R }else if(is.vector(R)){ m <- length(R) n <- (1 + sqrt(1 + 8 * m)) / 2 if(n != floor(n)) stop('Vector length not compatible with upper triangle') n <- as.integer(n) Rm <- matrix(0, n, n) Rm[upper.tri(Rm)] <- R Rm <- Rm + t(Rm) diag(Rm) <- 1 }else{ Rm <- as.matrix(R) if(nrow(Rm) != ncol(Rm)) stop('R must be square') } if(is.null(rownames(Rm))){ rownames(Rm) <- as.character(seq_len(nrow(Rm))) } if(is.null(colnames(Rm))){ colnames(Rm) <- as.character(seq_len(ncol(Rm))) } Rm }, error = function(e){ stop(paste('Invalid input for networkplot:', e$message)) }) idx <- which(upper.tri(Rm), arr.ind = TRUE) edges <- data.frame( from = rownames(Rm)[idx[,1]], to = colnames(Rm)[idx[,2]], r = Rm[idx] ) g <- igraph::graph_from_data_frame( edges, directed = FALSE ) p <- ggraph::ggraph(graph = g, layout = 'circle') + ggraph::geom_edge_arc( ggplot2::aes( edge_alpha = abs(.data$r), edge_color = .data$r ), strength = 0.5 ) + ggraph::scale_edge_color_gradient2( low = 'red', mid = 'white', high = 'blue', midpoint = 0, limits = c(-1, 1), guide = 'none' ) + ggraph::geom_node_point(size = 3) + ggraph::geom_node_text( ggplot2::aes(label = .data$name), repel = TRUE, size = 3 ) + ggplot2::theme_void() + ggplot2::theme(legend.position = 'none') if(!is.null(title)){ p <- p + ggplot2::ggtitle(title) + ggplot2::theme( plot.title = ggplot2::element_text(hjust = 0.5) ) } return(p) }