-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathgetPopulationFit.R
More file actions
109 lines (98 loc) · 3.75 KB
/
Copy pathgetPopulationFit.R
File metadata and controls
109 lines (98 loc) · 3.75 KB
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
#' Obtain the population-level fitting of the genes.
#'
#' This function is used to obtain the population-level fitting pattern along pseudotime of the genes, using the estimated parameters from the lamian model.
#'
#' @author Wenpin Hou <whou10@jhu.edu>
#' @import splines
#' @export
#' @return a matrix, population fitting of the genes (rows) by cells (ordered by pseudotime)
#' @param testobj output object of the function tespt().
#' @param gene a vector of gene names
#' @param type one of c('Time', 'Variable). Case insensitive.
#' @param num.timepoint the number of time points used to fit the curve. Default is the minimum of 1e3 and max(pseudotime). This argument will reduce the running time of both this function and the downstream plot function if there are too many cells.
#' @examples
#' data(mantestobj)
#' a <- getPopulationFit(testobj = mantestobj, gene = rownames(mantestobj$populationFit[[1]])[seq(1,3)], type = 'variable')
getPopulationFit <- function(testobj,
gene = NULL,
type = 'time',
num.timepoint = 1e3){
type <- toupper(type)
if (!'testvar' %in% names(testobj)) {
testvar <- testobj$testvar <- 2
} else {
testvar = testobj$testvar
}
if (type == 'VARIABLE'){
design = testobj$design[, c(1, testobj$testvar)] ## design for multi
} else {
design = testobj$design
}
knotnum = testobj$knotnum
pseudotime = testobj$pseudotime
pseudotime = pseudotime[order(pseudotime)]
pt <- seq(min(pseudotime), max(pseudotime), length.out = num.timepoint)
if (sum(design[, 1]) != nrow(design)){
print("The first column of design matrix should be all 1s (intercept)! Using the first column as the variable column ...")
design = cbind(intercept = 1, design)
colnames(design)[1] <- 'intercept'
}
if (is.null(gene)) gene <- rownames(testobj$statistics)
if (type == 'TIME') {
design = design[, 1, drop = FALSE]
} else {
variable = colnames(design)[2]
design <- unique(design[, c(colnames(design)[1], variable)])
rownames(design) <- paste0(variable, '_', unique(design[, variable]))
}
fitlist <- lapply(gene, function(g){
tmp = matrix(testobj$parameter[[g]]$beta, ncol = knotnum[g]+4)
if (type == 'VARIABLE'){
beta = as.vector(tmp[c(1,testvar), ]) ### subset the beta values of the intercept and the test covariate for multi
} else {
beta = as.vector(tmp[1, ]) ### subset the beta values of the intercept and the test covariate for multi
}
x <- sapply(row.names(design), function(i) {
kronecker(diag(knotnum[g] + 4), design[i, , drop = FALSE]) ###
}, simplify = FALSE)
if (knotnum[g] == 0) {
# phi <- cbind(1, bs(pt))
phi <- bs(pt, intercept = TRUE)
} else {
knots = seq(min(pt), max(pt), length.out = knotnum[g] + 2)[2:(knotnum[g] + 1)]
# phi <- cbind(1, bs(pt, knots = knots))
phi <- bs(pt,knots = knots, intercept = TRUE)
}
if (type == 'VARIABLE') {
fit <- lapply(x, function(i) {
if (ncol(phi) == nrow(i)){
phi %*% i %*% beta
} else {
phi %*% t(i) %*% beta
}
})
} else {
i = x[[1]]
if (ncol(phi) == nrow(i)){
fit <- phi %*% i %*% beta
} else {
fit <- phi %*% t(i) %*% beta
}
}
return(fit)
})
names(fitlist) <- gene
if (type == 'VARIABLE'){
fitres <- lapply(names(fitlist[[1]]), function(i){
tmp <- t(sapply(fitlist, function(j){
j[[i]]
}))
})
names(fitres) <- names(fitlist[[1]])
} else if (type == 'TIME'){
fitres <- t(do.call(cbind, fitlist))
rownames(fitres) <- gene
if (ncol(testobj$expr) == ncol(fitres)) colnames(fitres) <- colnames(testobj$expr)
}
return(fitres)
}