-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgetLQ.R
190 lines (188 loc) · 6.61 KB
/
getLQ.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#####################################################################
## Copyright 2018 Philip Morris Products, S.A.
## Quai Jeanrenaud 5, 2000 Neuchatel, Switzerland
#####################################################################
#' Get precomputed matrix for fast NPA computations
#'
#' @param Model A R list object with slot model containing nodes and edges
#' data.frame
#' @param verbose A logical. Default is \code{TRUE}, messages will be displayed
#' during the function execution
#' @param pattern.gene A character vector. Regular expression for filtering
#' downstrean genes
#' @return A R list object with computed metric like L2, L3 matrices,
#' Qbackbone, ...
#' @importFrom methods is
#' @export
#' @examples
#' data(Hs__CFA__Apoptosis__0__0__1)
#' # Hs__CFA__Apoptosis__0__0__1 <- getLQ(
#' # Hs__CFA__Apoptosis__0__0__1, verbose = TRUE)
getLQ <- function(Model, verbose = TRUE, pattern.gene = "^EXP\\(") {
# model$edges
sourcenode.index <- 1
targetnode.index <- 3
signedge.index <- 2
neg.rel <- c(
"directlyDecreases",
"decreases",
"negativeCorrelation",
"|-cw-|",
"=|",
"-|",
"-neg-",
"-1"
)
perm <- function(x) {
sample(x, length(x), replace = FALSE)
}
permL3 <- function(L3, seed = 145) {
L3perm <- L3
ltmp <- L3perm
diag(ltmp) <- 0
diagL <- diag(L3perm) - rowSums(abs(ltmp))
diag(L3perm) <- 0
L3perm[upper.tri(L3perm)] <- 0
## Removed, this should be done outside the function
# set.seed(seed)
L3perm[lower.tri(L3perm)] <- perm(L3perm[lower.tri(L3perm)])
L3perm <- L3perm + t(L3perm)
for (k in which(rowSums(abs(L3perm)) == 0)) {
## Removed, this should be done outside the function
# set.seed(seed + 12 * k)
add <- sample(c(1:nrow(L3perm))[-k], 1)
L3perm[k, add] <- 1
L3perm[add, k] <- 1
} #ensure no isolated nodes
diag(L3perm) <- rowSums(abs(L3perm)) + diagL
all(L3perm == t(L3perm))
return(L3perm)
}
getSym <- function(a) {
d0 <- diag(a)
a <- a + t(a)
# a[abs(a) > 1] = 1
diag(a) <- d0
return(a)
}
getSignedAdj <- function(E1, symmetric = TRUE) {
nds <- sort(unique(as.vector(E1[, c(1, 2)])))
A <- tapply(as.numeric(E1[, 3]), list(
factor(E1[, 1], levels = nds),
factor(E1[,2], levels = nds)),
sum)
A[is.na(A)] <- 0
A[abs(A) > 1] <- sign(A[abs(A) > 1])
if (symmetric == TRUE & !all(A == t(A))) {
A <- getSym(A)
}
return(A)
}
# Some time some nodes are downstream, but not EXP()
Model$startNodeDown <- lapply(Model$startNodeDown, function(x) {
y <- x[grep(pattern.gene, as.character(x$nodeLabel), perl = TRUE), ]
y <- y[y$Direction != 0, ]
return(y)
})
# Check no EXP() in the backbone
geneinback <- grep(pattern.gene, unique(as.vector(as.matrix(
Model$model$edges[,c(sourcenode.index, targetnode.index)]))),
perl = TRUE)
if (length(geneinback) > 0) {
print(geneinback)
stop(paste("Some backbone nodes are genes", pattern.gene))
}
# Get signed backbone edges
Ebackbone <- Model$model$edges[, c(sourcenode.index, signedge.index,
targetnode.index)]
dire <- rep(1, nrow(Ebackbone))
dire[Ebackbone[, 2] %in% neg.rel] <- -1
Ebackbone <- data.frame(Ebackbone[, c(1, 3)], Direction = dire)
Ebackbone <- Ebackbone[order(Ebackbone[, 2]), ]
Ebackbone <- Ebackbone[order(Ebackbone[, 1]), ]
Ebackbone <- unique(Ebackbone) #if duplicated edges...
# Get edges from functional layer to transcriptional layer
dhyp <- NULL
Ehyp <- NULL
for (k in 1:length(Model$startNodeDown)) {
Ehyp <- rbind(Ehyp, cbind(rep(names(Model$startNodeDown)[k],
nrow(Model$startNodeDown[[k]])),
as.character(Model$startNodeDown[[k]]$nodeLabel)))
dhyp <- c(dhyp,
Model$startNodeDown[[k]]$Direction/nrow(Model$startNodeDown[[k]]))
#normalize edges to transcript
}
Edown <- cbind(Ehyp, Direction = dhyp)
colnames(Edown) <- colnames(Ebackbone)
E00 <- rbind(Ebackbone, Edown)
Ad <- getSignedAdj(as.matrix(E00), symmetric = TRUE)
if (verbose == TRUE) {
message(paste("Graph size=", nrow(Ad)))
}
L <- diag(rowSums(abs(Ad))) - Ad
# Q = diag(rowSums(abs(Ad)))+ Ad
#not needed:save memory Get indices of transript layer
downgene <- grep(pattern.gene, rownames(L), perl = TRUE)
# Get key matrices
L2 <- L[downgene, -downgene]
L3 <- L[-downgene, -downgene]
L3inv <- try(solve(L3), silent=TRUE)
if (inherits(L3inv, "try-error")) {
svL3 <- svd(L3)
lambdainv <- rep(0, length(svL3$d))
lambdainv[abs(svL3$d) > 1e-13] <- 1/svL3$d[abs(svL3$d) > 1e-13]
L3inv <- svL3$v %*% diag(lambdainv) %*% t(svL3$u)
rownames(L3inv) <- rownames(L3)
colnames(L3inv) <- colnames(L3)
}
L3invtL2 <- L3inv %*% t(L2)
notDown <- which(rownames(L) %in% rownames(L3))
if (!all(sort(c(notDown, downgene)) == 1:nrow(L))) {
stop("wrong indexes...")
}
# Q
Qbackbone <- -L3 #Q[notDown, notDown]
# Recompute the diag:
if (length(notDown) == 1) {
Qbackbone <- matrix(Qbackbone, ncol = 1)
rownames(Qbackbone) <- colnames(Qbackbone) <- rownames(L)[notDown]
}
diag(Qbackbone) <- 0
diag(Qbackbone) <- rowSums(abs(Qbackbone))
if (nrow(Qbackbone) == 1) {
diag(Qbackbone) <- 1
}
NetSize <- nrow(Ebackbone)
# Prepare for K-stat
sqrtMat <- function(A) {
sv <- svd(A)
if (!all(sv$d > 0)) {
stop("Matrix not positive definite")
}
Asqrt <- sv$u %*% sqrt(diag(sv$d)) %*% t(sv$v)
return(Asqrt)
}
Qb.sqrt <- sqrtMat(Qbackbone)
b <- 500
## Removed, this should be done outside the function
# set.seed(2674)
QbL3inv.perm <- lapply(1:b, function(i) {
l3 <- permL3(L3, seed = i + 858)
ql3inv <- try(-Qb.sqrt %*% solve(l3), silent = TRUE)
if (inherits(ql3inv, "try-error")) {
ql3inv <- matrix(NA, nrow(L3), ncol(L3))
}
return(ql3inv)
})
return(list(
Qbackbone = Qbackbone,
L3invtL2 = L3invtL2,
L2 = L2,
L3 = L3,
QbL3inv.perm = QbL3inv.perm,
sgn = Ebackbone[, 3],
NetSize = NetSize,
backbone = Ebackbone[, c(1, 3, 2)],
startNodeDown = Model$startNodeDown,
g = Model$g))
}