-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvoom_ihs.R
121 lines (93 loc) · 3.39 KB
/
voom_ihs.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
library(limma)
voom_ihs <- function (counts, design = NULL, lib.size = NULL, normalize.method = "none",
span = 0.5, plot = FALSE, save.plot = FALSE, ...)
{
ihs <- function(x) {
transformed <- log(x + sqrt(x ^ 2 + 1))
return(transformed)
}
hs <- function(x) {
y <- 0.5*exp(-x)*(exp(2*x)-1)
return(y)
}
out <- list()
if (is(counts, "DGEList")){
out$genes <- counts$genes
out$targets <- counts$samples
if (is.null(design) && diff(range(as.numeric(counts$sample$group))) >
0)
design <- model.matrix(~group, data = counts$samples)
if (is.null(lib.size))
lib.size <- with(counts$samples, lib.size * norm.factors)
counts <- counts$counts
}else{
isExpressionSet <- suppressPackageStartupMessages(is(counts,
"ExpressionSet"))
if (isExpressionSet) {
if (length(Biobase::fData(counts)))
out$genes <- Biobase::fData(counts)
if (length(Biobase::pData(counts)))
out$targets <- Biobase::pData(counts)
counts <- Biobase::exprs(counts)
}
else {
counts <- as.matrix(counts)
}
}
n <- nrow(counts)
if (n < 2L){stop("Need at least two genes to fit a mean-variance trend")}
if (is.null(design)) {
design <- matrix(1, ncol(counts), 1)
rownames(design) <- colnames(counts)
colnames(design) <- "GrandMean"
}
if (is.null(lib.size)){lib.size <- colSums(counts)}
y <- t(ihs(t(counts)/lib.size))
y <- normalizeBetweenArrays(y, method = normalize.method)
fit <- lmFit(y, design, ...)
if (is.null(fit$Amean)){fit$Amean <- rowMeans(y, na.rm = TRUE)}
# fitted mean for each row (taxa)
sx <- fit$Amean
# fitted standard deviation
sy <- sqrt(fit$sigma)
allzero <- rowSums(counts) == 0
if (any(allzero)) {
sx <- sx[!allzero]
sy <- sy[!allzero]
}
l <- lowess(sx, sy, f = span)
if (plot){
plot(sx, sy, xlab = "mean(ihs(count/sizeFactor))", ylab = "Sqrt(standard deviation )",
pch = 16, cex = 0.25)
title("voom_ihs: Mean-variance trend")
lines(l, col = "red")
}
# linearly interpolate given the smooth line from the lowess
f <- approxfun(l, rule = 2)
if(fit$rank < ncol(design)){
j <- fit$pivot[1:fit$rank]
fitted.values <- fit$coef[, j, drop = FALSE] %*% t(fit$design[,
j, drop = FALSE])
}else{
fitted.values <- fit$coef %*% t(fit$design)
}
fitted.cpm <- hs(fitted.values)
fitted.count <- t(t(fitted.cpm)*(lib.size))
fitted.ihs <- ihs(fitted.count)
w <- 1/f(fitted.ihs)^4
dim(w) <- dim(fitted.ihs)
out$E <- y
out$weights <- w
out$design <- design
if(is.null(out$targets)){
out$targets <- data.frame(lib.size = lib.size)
}else{
out$targets$lib.size <- lib.size
}
if (save.plot) {
out$voom.xy <- list(x = sx, y = sy, xlab = "mean(ihs(count/sizeFactor))",
ylab = "Sqrt( standard deviation )")
out$voom.line <- l
}
new("EList", out)
}