前言
在上一章我们介绍了如果计算每个基因的多项式回归系数的总体显著性maSigpro建模代码分析之p.vector
,这次我们就来介绍下逐步回归建模的思想
1.T.fit函数
首先我们看一下这个函数有些什么参数
T.fit <- function (data, design = data$dis, step.method = "backward",
min.obs = data$min.obs, alfa = data$Q, nvar.correction = FALSE, family=gaussian(), epsilon=0.00001 )
首先先读入下数据:
min.obs = 3
G <- nrow(data)
data <- rbind(c(rep(1, ncol(data))), data)
dat <- as.matrix(data)
count.na <- function(x) (length(x) - length(x[is.na(x)]))
dat <- dat[apply(dat, 1, count.na) >= min.obs, ]
groups.vector = NULL
edesign = NULL
dis <- as.data.frame(design$dis)
dat <- dat[, as.character(rownames(dis))]
g <- (dim(dat)[1] - 1)
n <- dim(dat)[2]
p <- dim(dis)[2]
vars.in <- colnames(dis)
sol <- coefficients <- group.coeffs <- t.score <- sig.profiles <- NULL
influ.info <- matrix(NA, nrow = nrow(dis), ncol = 1)
rownames(influ.info) <- rownames(dis)
dis矩阵为第一章所述的设计矩阵(dis矩阵)
之后就会进入逐步回归的建模当中了,这里采用向后算法为例:
reg <- stepback(y = y, d = dis, alfa = alfa, family=family, epsilon=epsilon)
#该函数的参数:
stepback <- function (y = y, d = d, alfa = 0.05, family = gaussian() , epsilon=0.00001)
这里涉及到逐步回归函数stepback()
我们采用一个基因来做回归,看看stepback()的作用
我们先读入数据:
# y 表示基因表达量,510代表第510个基因
y <- as.numeric(dat[510, ])
name <- rownames(dat)[510]
d = dis
lm1 <- glm(y ~ ., data = d, family="gaussian", epsilon=0.00001)
result <- summary(lm1)
#提取各项系数中最大的p值
max <- max(result$coefficients[, 4][-1], na.rm = TRUE)
#显著性定到0.25
alfa = 0.25
while (max > alfa) {
#提取最大的p值所对应的回归系数的名称
varout <- names(result$coefficients[, 4])[result$coefficients[,4] == max][1]
pos <- position(matrix = d, vari = varout)
#将该不显著的系数剔除(逐步回归思想)
d <- d[, -pos]
# 剔除后再建模,依次往复
lm1 <- glm(y ~ ., data = d, family='gaussian', epsilon=0.00001)
result <- summary(lm1)
#选择最大的p值,重复上述步骤
max <- max(result$coefficients[, 4][-1], na.rm = TRUE)
#剔除只剩两个系数的情况
if (length(result$coefficients[, 4][-1]) == 2) {
min <- min(result$coefficients[, 4][-1], na.rm = TRUE)
lastname <- names(result$coefficients[, 4][-1])[result$coefficients[,4][-1] == min]
}
#剔除只剩一个系数的情况
if (length(result$coefficients[, 4][-1]) == 1) {
max <- result$coefficients[, 4][-1]
if (max > alfa) {
max = 0
lm1 <- glm(y ~ 1, family='gaussian', epsilon=0.00001)
}
}
}
这一步体现了逐步回归的思想,即线性回归模型中,并不是每一个回归系数都具有显著性,因此逐步回归的思想是剔除不显著的回归系数,留下显著的回归系数
这张表代表着每一种处理对应的回归系数
比方说ColdvsControl的系数指代的是在设计矩阵(dis矩阵)中ColdvsControl编号为1的组与编号为0的组相比较,类似于因子型决策变量的线性模型比较;
如果回归系数为负,则代表整体的cold处理与其他组相比表现为下调。这里的其他组指代的是除了cold处理组以外的处理组,或者理解为设计矩阵dis中在cold这一列编号为0的组
又比如Time×Cold的系数指代的是在设计矩阵(dis矩阵)中Time×Cold编号为0,3,9和27的与对应的基因表达量建模,得到一个回归系数Time×Cold,该系数表征这个基因是否在cold的条件下随时间而变化
如果回归系数为正,则代表经过cold处理,随时间处理延长,该基因显示为上调。上图所示其他组,代表的是设计矩阵dis中在Time×Cold这一列所有编号为0的组
我们不妨提取出第四列(p值列),并去除截距项作为比较:
上图都是个各个回归系数的p值,逐步回归就是根据利用p值是否大于阈值来做筛选,若大于阈值(该例子的阈值为0.25)则剔除该回归系数(在程序里面是选出最大的p值与阈值相比,然后一个一个剔除,直到满足条件)
剔除后的模型:
这样的话,各个显著的回归系数就计算出来了,那么每一个基因的建模都经历这么一步,我们就可以获得每一个基因多项式回归系数(显著的);其中第一列是回归系数的值,第四列是回归系数的p值
提取拟合显著的基因
这里还想插播一条就是maSigpro提取拟合显著的基因的方法,提取拟合显著的基因利用的是get.siggenes()函数,它具有如下参数:
get.siggenes<-function (tstep, rsq = 0.7, add.IDs = FALSE, IDs = NULL, matchID.col = 1,
only.names = FALSE, vars = c("all", "each", "groups"), significant.intercept = "dummy",
groups.vector = NULL, trat.repl.spots = "none", index = IDs[,
(matchID.col + 1)], match = IDs[, matchID.col], r = 0.7)
其中我只介绍vars= "each"这个参数的用法,这个参数主要是可以把各种情况做差异比较的后得到的差异基因给提取出来
紧接着T.fit以后
tstep <- T.fit(fit, step.method = "backward", alfa = 0.05)
dis <- tstep$dis
edesign <- tstep$edesign
groups.vector <- tstep$groups.vector
not.all.empty <- function(x) (is.element(FALSE, x == " "))
indep <- strsplit(colnames(dis)[grep("x", colnames(dis))[1]],
"x")[[1]][1]
rsq = 0.7
#tstep$sol[, 2]代表的是R^2,利用R^2做初步过滤
if (any(tstep$sol[, 2] > rsq)) {
sig.pvalues <- tstep$sol[which(tstep$sol[, 2] > rsq), ]
sig.profiles <- tstep$sig.profiles[which(tstep$sol[, 2] > rsq), ]
coefficients <- tstep$coefficients[which(tstep$sol[, 2] > rsq), ]
group.coeffs <- tstep$group.coeffs[which(tstep$sol[, 2] > rsq), ]
}
我们的tstep对象包括
1.sol: 每一个基因多项式回归系数的p值
2.sig.profiles:标准化后的基因表达矩阵
3.coefficients:每一个基因多项式回归系数
其中sig.pvalues为:
上图表示的是每个基因所建立的多项式回归模型中各个回归系数的p值(显著性);第一列p-value代表整模型的显著性,第四列p.valor_ColdvsControl代表Cold组与Control组相比较的回归系数的显著性;我们之前做逐步回归的时候提到过,NA代表该基因所建立的模型中被剔除的回归系数
for (i in 1:ncol(summary)) {
sigs <- sig.profiles[which(!is.na(sig.pvalues[,(2 + i)])), ]
coeffs <- coefficients[which(!is.na(sig.pvalues[,(2 + i)])), ]
gc <- group.coeffs[which(!is.na(sig.pvalues[,(2 + i)])), ]
ps <- sig.pvalues[which(!is.na(sig.pvalues[,(2 + i)])), ]
names.sigs <- rownames(sigs)
summary[, i] <- c(names.sigs, rep(" ", nrow(sig.profiles) - nrow(sigs)))
sig.genes[[i]] <- list(sigs, coeffs, gc, ps,
nrow(sigs), edesign, groups.vector)
names(sig.genes[[i]]) <- c("sig.profiles", "coefficients",
"group.coeffs", "sig.pvalues", "g", "edesign",
"groups.vector")
}
names(sig.genes) <- c("independ", colnames(dis))
summary <- as.data.frame(summary[apply(summary, 1,
not.all.empty), ])
那么我们可以根据每一个回归系数所代表的统计学意义maSigpro建模代码分析之p.vector
,来筛选拟合显著的基因,这些基因的意义可以根据回归系数的意义进行定义:
比方说ColdvsControl仅代表Cold处理与Control组相比较下的差异基因,Time仅代表基因差异表达是否是由时间引起的,即所有的不同时间点(3,9,27)分别与与对照(0 时间点)相比下的差异基因的并集;而Time×Cold代表在ColdvsControl的基础上是否有时间因素的加成,也可以理解为ColdvsControl与Time所得差异基因的交集
可以结合这张图来理解:
我们抽象出来模型model.glm出来,对于某基因A来说:
1.x1为dis矩阵中ColdvsControl的那一个列向量
2.x2为dis矩阵中Time的那一个列向量
3.x1x2为dis矩阵中Time×Cold的那一个列向量
4.β1,β2,β3分别为x1,x2,x1x2的系数
5.y为某基因在各个sample里面的表达量
如果β1显著,那么代表x1的变化(即处理的变化)会带来y的变化;如果β2显著,那么代表x2的变化(即时间的变化)会带来y的变化;如果β3显著,那么代表x1和x2的交互项变化(即处理的变化,时间的变化或者两者同时变化)会带来y的变化;
只要自变量的变化能带来 y 的变化的,我们都称之为差异基因
项目GitHub:https://github.com/g1o/maSigPro