Skip to content

Commit 120ce0d

Browse files
committed
prec_to_adj
1 parent 2e057f1 commit 120ce0d

7 files changed

Lines changed: 209 additions & 19 deletions

File tree

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export(compute_penalty)
88
export(gen_prec_sbm)
99
export(grasps)
1010
export(performance)
11+
export(prec_to_adj)
1112
export(sparsify_block_banded)
1213
import(ggforce)
1314
import(ggplot2)

R/performance.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
#' }
9292
#'
9393
#' @example
94-
#' inst/example/ex-performance.R
94+
#' inst/example/ex-grasps.R
9595
#'
9696
#' @export
9797

R/prec_to_adj.R

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#' Adjacency Matrix from Precision Matrix
2+
#'
3+
#' @description
4+
#' Convert a precision matrix to a partial-correlation-based adjacency matrix.
5+
#'
6+
#' @param prec.mat A numeric precision matrix.
7+
#'
8+
#' @param diag.zero A logical value (default = TRUE) specifying whether to
9+
#' set the diagonal entries of the adjacency matrix to 0.
10+
#' If \code{diag.zero = FALSE}, the diagonal entries are set to 1 for a weighted
11+
#' network. For an unweighted network (\code{weighted = FALSE}), the diagonal is
12+
#' always forced to 0 to avoid self-loops.
13+
#'
14+
#' @param absolute A logical value (default = FALSE) specifying whether to
15+
#' take the absolute values of the partial correlations.
16+
#'
17+
#' @param threshold A nonnegative numeric value (default = \code{NULL})
18+
#' specifying the threshold for edge filtering.
19+
#' Entries with absolute values smaller than the threshold are set to 0.
20+
#'
21+
#' @param weighted A logical value (default = TRUE) specifying whether to
22+
#' return a weighted adjacency matrix.
23+
#' If \code{weighted = FALSE}, the matrix is a binary adjacency matrix with
24+
#' entries equal to 0 or 1.
25+
#'
26+
#' @return
27+
#' A numeric adjacency matrix.
28+
#'
29+
#' @details
30+
#' For a precision matrix \eqn{\Omega}, the partial correlation between nodes
31+
#' \eqn{i} and \eqn{j} is computed as
32+
#' \deqn{\rho_{ij} = - \Omega_{ij} / \sqrt{\Omega_{ii}\Omega_{jj}}.}
33+
#'
34+
#' @example
35+
#' inst/example/ex-grasps.R
36+
#'
37+
#' @export
38+
39+
prec_to_adj <- function(prec.mat, diag.zero = TRUE, absolute = FALSE,
40+
threshold = NULL, weighted = TRUE) {
41+
42+
if (!is.matrix(prec.mat)) {
43+
prec.mat <- as.matrix(prec.mat)
44+
}
45+
if (any(!is.finite(prec.mat))) {
46+
stop("The precision matrix contains non-finite values!")
47+
}
48+
if (!isSymmetric(prec.mat)) {
49+
stop("The precision matrix must be symmetric!")
50+
}
51+
d <- diag(prec.mat)
52+
if (any(d <= 0)) {
53+
stop("All diagonal entries of the precision matrix must be positive!")
54+
}
55+
56+
## partial-correlation-based adjacency matrix
57+
norm_mat <- outer(sqrt(d), sqrt(d), "*")
58+
adj_mat <- -prec.mat / norm_mat
59+
60+
## optional: diagonal entries
61+
if (diag.zero) {
62+
diag(adj_mat) <- 0
63+
} else {
64+
diag(adj_mat) <- 1
65+
}
66+
67+
## optional: absolute value
68+
if (absolute) {
69+
adj_mat <- abs(adj_mat)
70+
}
71+
72+
## optional: thresholding
73+
if (!is.null(threshold)) {
74+
if (!is.numeric(threshold) || length(threshold) != 1 || threshold < 0) {
75+
stop("The threshold must be a nonnegative scalar!")
76+
}
77+
adj_mat[abs(adj_mat) < threshold] <- 0
78+
}
79+
80+
## optional: binary adjacency matrix
81+
if (!weighted) {
82+
adj_mat <- 1 * (adj_mat != 0)
83+
diag(adj_mat) <- 0
84+
if (!diag.zero) {
85+
message("For an unweighted network, the diagonal is forced to 0 to avoid self-loops.")
86+
}
87+
}
88+
89+
return(adj_mat)
90+
}

inst/example/ex-grasps.R

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,21 @@ sim <- gen_prec_sbm(p = 30, K = 3,
1313
## visualization
1414
plot(sim)
1515

16-
## n-by-d data matrix
16+
## n-by-p data matrix
1717
library(MASS)
1818
X <- mvrnorm(n = 20, mu = rep(0, 30), Sigma = sim$Sigma)
1919

20-
## adapt, HBIC
21-
res <- grasps(X = X, membership = sim$membership, penalty = "adapt", crit = "HBIC")
20+
## precision matrix: adaptive lasso; BIC
21+
prec <- grasps(X = X, membership = sim$membership, penalty = "adapt", crit = "BIC")
2222

23-
## visualization
24-
plot(res)
23+
## precision matrix visualization
24+
plot(prec)
2525

2626
## performance
27-
performance(hatOmega = res$hatOmega, Omega = sim$Omega)
27+
performance(hatOmega = prec$hatOmega, Omega = sim$Omega)
28+
29+
## adjacency matrix: diagonal = 0; raw partial correlations;
30+
## no thresholding; weighted network
31+
adj <- prec_to_adj(prec$hatOmega,
32+
diag.zero = TRUE, absolute = FALSE,
33+
threshold = NULL, weighted = TRUE)

man/grasps.Rd

Lines changed: 12 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/performance.Rd

Lines changed: 12 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/prec_to_adj.Rd

Lines changed: 81 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)